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/ec.h1100
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c386
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c1042
-rw-r--r--src/lib/libcrypto/ec/ec_ameth.c659
-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.c2059
-rw-r--r--src/lib/libcrypto/ec/ec_cvt.c144
-rw-r--r--src/lib/libcrypto/ec/ec_err.c258
-rw-r--r--src/lib/libcrypto/ec/ec_key.c463
-rw-r--r--src/lib/libcrypto/ec/ec_lcl.h393
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c1164
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c940
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c340
-rw-r--r--src/lib/libcrypto/ec/ec_print.c195
-rw-r--r--src/lib/libcrypto/ec/eck_prn.c391
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c315
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c210
-rw-r--r--src/lib/libcrypto/ec/ecp_smpl.c1719
19 files changed, 0 insertions, 13330 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
deleted file mode 100644
index ee7078130c..0000000000
--- a/src/lib/libcrypto/ec/ec.h
+++ /dev/null
@@ -1,1100 +0,0 @@
1/* crypto/ec/ec.h */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/**
6 * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
7 * \author Originally written by Bodo Moeller for the OpenSSL project
8 */
9/* ====================================================================
10 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
22 * distribution.
23 *
24 * 3. All advertising materials mentioning features or use of this
25 * software must display the following acknowledgment:
26 * "This product includes software developed by the OpenSSL Project
27 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
28 *
29 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
30 * endorse or promote products derived from this software without
31 * prior written permission. For written permission, please contact
32 * openssl-core@openssl.org.
33 *
34 * 5. Products derived from this software may not be called "OpenSSL"
35 * nor may "OpenSSL" appear in their names without prior written
36 * permission of the OpenSSL Project.
37 *
38 * 6. Redistributions of any form whatsoever must retain the following
39 * acknowledgment:
40 * "This product includes software developed by the OpenSSL Project
41 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
44 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
46 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
47 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
49 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 * OF THE POSSIBILITY OF SUCH DAMAGE.
55 * ====================================================================
56 *
57 * This product includes cryptographic software written by Eric Young
58 * (eay@cryptsoft.com). This product includes software written by Tim
59 * Hudson (tjh@cryptsoft.com).
60 *
61 */
62/* ====================================================================
63 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
64 *
65 * Portions of the attached software ("Contribution") are developed by
66 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
67 *
68 * The Contribution is licensed pursuant to the OpenSSL open source
69 * license provided above.
70 *
71 * The elliptic curve binary polynomial software is originally written by
72 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
73 *
74 */
75
76#ifndef HEADER_EC_H
77#define HEADER_EC_H
78
79#include <openssl/opensslconf.h>
80
81#ifdef OPENSSL_NO_EC
82#error EC is disabled.
83#endif
84
85#include <openssl/asn1.h>
86#include <openssl/symhacks.h>
87#ifndef OPENSSL_NO_DEPRECATED
88#include <openssl/bn.h>
89#endif
90
91#ifdef __cplusplus
92extern "C" {
93#elif defined(__SUNPRO_C)
94# if __SUNPRO_C >= 0x520
95# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
96# endif
97#endif
98
99
100#ifndef OPENSSL_ECC_MAX_FIELD_BITS
101# define OPENSSL_ECC_MAX_FIELD_BITS 661
102#endif
103
104/** Enum for the point conversion form as defined in X9.62 (ECDSA)
105 * for the encoding of a elliptic curve point (x,y) */
106typedef enum {
107 /** the point is encoded as z||x, where the octet z specifies
108 * which solution of the quadratic equation y is */
109 POINT_CONVERSION_COMPRESSED = 2,
110 /** the point is encoded as z||x||y, where z is the octet 0x02 */
111 POINT_CONVERSION_UNCOMPRESSED = 4,
112 /** the point is encoded as z||x||y, where the octet z specifies
113 * which solution of the quadratic equation y is */
114 POINT_CONVERSION_HYBRID = 6
115} point_conversion_form_t;
116
117
118typedef struct ec_method_st EC_METHOD;
119
120typedef struct ec_group_st
121 /*
122 EC_METHOD *meth;
123 -- field definition
124 -- curve coefficients
125 -- optional generator with associated information (order, cofactor)
126 -- optional extra data (precomputed table for fast computation of multiples of generator)
127 -- ASN1 stuff
128 */
129 EC_GROUP;
130
131typedef struct ec_point_st EC_POINT;
132
133
134/********************************************************************/
135/* EC_METHODs for curves over GF(p) */
136/********************************************************************/
137
138/** Returns the basic GFp ec methods which provides the basis for the
139 * optimized methods.
140 * \return EC_METHOD object
141 */
142const EC_METHOD *EC_GFp_simple_method(void);
143
144/** Returns GFp methods using montgomery multiplication.
145 * \return EC_METHOD object
146 */
147const EC_METHOD *EC_GFp_mont_method(void);
148
149/** Returns GFp methods using optimized methods for NIST recommended curves
150 * \return EC_METHOD object
151 */
152const EC_METHOD *EC_GFp_nist_method(void);
153
154
155/********************************************************************/
156/* EC_METHOD for curves over GF(2^m) */
157/********************************************************************/
158
159/** Returns the basic GF2m ec method
160 * \return EC_METHOD object
161 */
162const EC_METHOD *EC_GF2m_simple_method(void);
163
164
165/********************************************************************/
166/* EC_GROUP functions */
167/********************************************************************/
168
169/** Creates a new EC_GROUP object
170 * \param meth EC_METHOD to use
171 * \return newly created EC_GROUP object or NULL in case of an error.
172 */
173EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
174
175/** Frees a EC_GROUP object
176 * \param group EC_GROUP object to be freed.
177 */
178void EC_GROUP_free(EC_GROUP *group);
179
180/** Clears and frees a EC_GROUP object
181 * \param group EC_GROUP object to be cleared and freed.
182 */
183void EC_GROUP_clear_free(EC_GROUP *group);
184
185/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
186 * \param dst destination EC_GROUP object
187 * \param src source EC_GROUP object
188 * \return 1 on success and 0 if an error occurred.
189 */
190int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
191
192/** Creates a new EC_GROUP object and copies the copies the content
193 * form src to the newly created EC_KEY object
194 * \param src source EC_GROUP object
195 * \return newly created EC_GROUP object or NULL in case of an error.
196 */
197EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
198
199/** Returns the EC_METHOD of the EC_GROUP object.
200 * \param group EC_GROUP object
201 * \return EC_METHOD used in this EC_GROUP object.
202 */
203const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
204
205/** Returns the field type of the EC_METHOD.
206 * \param meth EC_METHOD object
207 * \return NID of the underlying field type OID.
208 */
209int EC_METHOD_get_field_type(const EC_METHOD *meth);
210
211/** Sets the generator and it's order/cofactor of a EC_GROUP object.
212 * \param group EC_GROUP object
213 * \param generator EC_POINT object with the generator.
214 * \param order the order of the group generated by the generator.
215 * \param cofactor the index of the sub-group generated by the generator
216 * in the group of all points on the elliptic curve.
217 * \return 1 on success and 0 if an error occured
218 */
219int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
220
221/** Returns the generator of a EC_GROUP object.
222 * \param group EC_GROUP object
223 * \return the currently used generator (possibly NULL).
224 */
225const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
226
227/** Gets the order of a EC_GROUP
228 * \param group EC_GROUP object
229 * \param order BIGNUM to which the order is copied
230 * \param ctx BN_CTX object (optional)
231 * \return 1 on success and 0 if an error occured
232 */
233int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
234
235/** Gets the cofactor of a EC_GROUP
236 * \param group EC_GROUP object
237 * \param cofactor BIGNUM to which the cofactor is copied
238 * \param ctx BN_CTX object (optional)
239 * \return 1 on success and 0 if an error occured
240 */
241int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
242
243/** Sets the name of a EC_GROUP object
244 * \param group EC_GROUP object
245 * \param nid NID of the curve name OID
246 */
247void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
248
249/** Returns the curve name of a EC_GROUP object
250 * \param group EC_GROUP object
251 * \return NID of the curve name OID or 0 if not set.
252 */
253int EC_GROUP_get_curve_name(const EC_GROUP *group);
254
255void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
256int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
257
258void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
259point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
260
261unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
262size_t EC_GROUP_get_seed_len(const EC_GROUP *);
263size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
264
265/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
266 * \param group EC_GROUP object
267 * \param p BIGNUM with the prime number
268 * \param a BIGNUM with parameter a of the equation
269 * \param b BIGNUM with parameter b of the equation
270 * \param ctx BN_CTX object (optional)
271 * \return 1 on success and 0 if an error occured
272 */
273int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
274
275/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
276 * \param group EC_GROUP object
277 * \param p BIGNUM for the prime number
278 * \param a BIGNUM for parameter a of the equation
279 * \param b BIGNUM for parameter b of the equation
280 * \param ctx BN_CTX object (optional)
281 * \return 1 on success and 0 if an error occured
282 */
283int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
284
285/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
286 * \param group EC_GROUP object
287 * \param p BIGNUM with the polynomial defining the underlying field
288 * \param a BIGNUM with parameter a of the equation
289 * \param b BIGNUM with parameter b of the equation
290 * \param ctx BN_CTX object (optional)
291 * \return 1 on success and 0 if an error occured
292 */
293int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
294
295/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
296 * \param group EC_GROUP object
297 * \param p BIGNUM for the polynomial defining the underlying field
298 * \param a BIGNUM for parameter a of the equation
299 * \param b BIGNUM for parameter b of the equation
300 * \param ctx BN_CTX object (optional)
301 * \return 1 on success and 0 if an error occured
302 */
303int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
304
305/** Returns the number of bits needed to represent a field element
306 * \param group EC_GROUP object
307 * \return number of bits needed to represent a field element
308 */
309int EC_GROUP_get_degree(const EC_GROUP *group);
310
311/** Checks whether the parameter in the EC_GROUP define a valid ec group
312 * \param group EC_GROUP object
313 * \param ctx BN_CTX object (optional)
314 * \return 1 if group is a valid ec group and 0 otherwise
315 */
316int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
317
318/** Checks whether the discriminant of the elliptic curve is zero or not
319 * \param group EC_GROUP object
320 * \param ctx BN_CTX object (optional)
321 * \return 1 if the discriminant is not zero and 0 otherwise
322 */
323int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
324
325/** Compares two EC_GROUP objects
326 * \param a first EC_GROUP object
327 * \param b second EC_GROUP object
328 * \param ctx BN_CTX object (optional)
329 * \return 0 if both groups are equal and 1 otherwise
330 */
331int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
332
333/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
334 * after choosing an appropriate EC_METHOD */
335
336/** Creates a new EC_GROUP object with the specified parameters defined
337 * over GFp (defined by the equation y^2 = x^3 + a*x + b)
338 * \param p BIGNUM with the prime number
339 * \param a BIGNUM with the parameter a of the equation
340 * \param b BIGNUM with the parameter b of the equation
341 * \param ctx BN_CTX object (optional)
342 * \return newly created EC_GROUP object with the specified parameters
343 */
344EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
345
346/** Creates a new EC_GROUP object with the specified parameters defined
347 * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
348 * \param p BIGNUM with the polynomial defining the underlying field
349 * \param a BIGNUM with the parameter a of the equation
350 * \param b BIGNUM with the parameter b of the equation
351 * \param ctx BN_CTX object (optional)
352 * \return newly created EC_GROUP object with the specified parameters
353 */
354EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
355
356/** Creates a EC_GROUP object with a curve specified by a NID
357 * \param nid NID of the OID of the curve name
358 * \return newly created EC_GROUP object with specified curve or NULL
359 * if an error occurred
360 */
361EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
362
363
364/********************************************************************/
365/* handling of internal curves */
366/********************************************************************/
367
368typedef struct {
369 int nid;
370 const char *comment;
371 } EC_builtin_curve;
372
373/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number
374 * of all available curves or zero if a error occurred.
375 * In case r ist not zero nitems EC_builtin_curve structures
376 * are filled with the data of the first nitems internal groups */
377size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
378
379
380/********************************************************************/
381/* EC_POINT functions */
382/********************************************************************/
383
384/** Creates a new EC_POINT object for the specified EC_GROUP
385 * \param group EC_GROUP the underlying EC_GROUP object
386 * \return newly created EC_POINT object or NULL if an error occurred
387 */
388EC_POINT *EC_POINT_new(const EC_GROUP *group);
389
390/** Frees a EC_POINT object
391 * \param point EC_POINT object to be freed
392 */
393void EC_POINT_free(EC_POINT *point);
394
395/** Clears and frees a EC_POINT object
396 * \param point EC_POINT object to be cleared and freed
397 */
398void EC_POINT_clear_free(EC_POINT *point);
399
400/** Copies EC_POINT object
401 * \param dst destination EC_POINT object
402 * \param src source EC_POINT object
403 * \return 1 on success and 0 if an error occured
404 */
405int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
406
407/** Creates a new EC_POINT object and copies the content of the supplied
408 * EC_POINT
409 * \param src source EC_POINT object
410 * \param group underlying the EC_GROUP object
411 * \return newly created EC_POINT object or NULL if an error occurred
412 */
413EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
414
415/** Returns the EC_METHOD used in EC_POINT object
416 * \param point EC_POINT object
417 * \return the EC_METHOD used
418 */
419const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
420
421/** Sets a point to infinity (neutral element)
422 * \param group underlying EC_GROUP object
423 * \param point EC_POINT to set to infinity
424 * \return 1 on success and 0 if an error occured
425 */
426int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
427
428/** Sets the jacobian projective coordinates of a EC_POINT over GFp
429 * \param group underlying EC_GROUP object
430 * \param p EC_POINT object
431 * \param x BIGNUM with the x-coordinate
432 * \param y BIGNUM with the y-coordinate
433 * \param z BIGNUM with the z-coordinate
434 * \param ctx BN_CTX object (optional)
435 * \return 1 on success and 0 if an error occured
436 */
437int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
438 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
439
440/** Gets the jacobian projective coordinates of a EC_POINT over GFp
441 * \param group underlying EC_GROUP object
442 * \param p EC_POINT object
443 * \param x BIGNUM for the x-coordinate
444 * \param y BIGNUM for the y-coordinate
445 * \param z BIGNUM for the z-coordinate
446 * \param ctx BN_CTX object (optional)
447 * \return 1 on success and 0 if an error occured
448 */
449int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
450 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
451
452/** Sets the affine coordinates of a EC_POINT over GFp
453 * \param group underlying EC_GROUP object
454 * \param p EC_POINT object
455 * \param x BIGNUM with the x-coordinate
456 * \param y BIGNUM with the y-coordinate
457 * \param ctx BN_CTX object (optional)
458 * \return 1 on success and 0 if an error occured
459 */
460int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
461 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
462
463/** Gets the affine coordinates of a EC_POINT over GFp
464 * \param group underlying EC_GROUP object
465 * \param p EC_POINT object
466 * \param x BIGNUM for the x-coordinate
467 * \param y BIGNUM for the y-coordinate
468 * \param ctx BN_CTX object (optional)
469 * \return 1 on success and 0 if an error occured
470 */
471int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
472 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
473
474/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
475 * \param group underlying EC_GROUP object
476 * \param p EC_POINT object
477 * \param x BIGNUM with x-coordinate
478 * \param y_bit integer with the y-Bit (either 0 or 1)
479 * \param ctx BN_CTX object (optional)
480 * \return 1 on success and 0 if an error occured
481 */
482int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
483 const BIGNUM *x, int y_bit, BN_CTX *ctx);
484
485/** Sets the affine coordinates of a EC_POINT over GF2m
486 * \param group underlying EC_GROUP object
487 * \param p EC_POINT object
488 * \param x BIGNUM with the x-coordinate
489 * \param y BIGNUM with the y-coordinate
490 * \param ctx BN_CTX object (optional)
491 * \return 1 on success and 0 if an error occured
492 */
493int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
494 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
495
496/** Gets the affine coordinates of a EC_POINT over GF2m
497 * \param group underlying EC_GROUP object
498 * \param p EC_POINT object
499 * \param x BIGNUM for the x-coordinate
500 * \param y BIGNUM for the y-coordinate
501 * \param ctx BN_CTX object (optional)
502 * \return 1 on success and 0 if an error occured
503 */
504int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
505 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
506
507/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
508 * \param group underlying EC_GROUP object
509 * \param p EC_POINT object
510 * \param x BIGNUM with x-coordinate
511 * \param y_bit integer with the y-Bit (either 0 or 1)
512 * \param ctx BN_CTX object (optional)
513 * \return 1 on success and 0 if an error occured
514 */
515int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
516 const BIGNUM *x, int y_bit, BN_CTX *ctx);
517
518/** Encodes a EC_POINT object to a octet string
519 * \param group underlying EC_GROUP object
520 * \param p EC_POINT object
521 * \param form point conversion form
522 * \param buf memory buffer for the result. If NULL the function returns
523 * required buffer size.
524 * \param len length of the memory buffer
525 * \param ctx BN_CTX object (optional)
526 * \return the length of the encoded octet string or 0 if an error occurred
527 */
528size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
529 point_conversion_form_t form,
530 unsigned char *buf, size_t len, BN_CTX *ctx);
531
532/** Decodes a EC_POINT from a octet string
533 * \param group underlying EC_GROUP object
534 * \param p EC_POINT object
535 * \param buf memory buffer with the encoded ec point
536 * \param len length of the encoded ec point
537 * \param ctx BN_CTX object (optional)
538 * \return 1 on success and 0 if an error occured
539 */
540int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
541 const unsigned char *buf, size_t len, BN_CTX *ctx);
542
543/* other interfaces to point2oct/oct2point: */
544BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
545 point_conversion_form_t form, BIGNUM *, BN_CTX *);
546EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
547 EC_POINT *, BN_CTX *);
548char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
549 point_conversion_form_t form, BN_CTX *);
550EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
551 EC_POINT *, BN_CTX *);
552
553
554/********************************************************************/
555/* functions for doing EC_POINT arithmetic */
556/********************************************************************/
557
558/** Computes the sum of two EC_POINT
559 * \param group underlying EC_GROUP object
560 * \param r EC_POINT object for the result (r = a + b)
561 * \param a EC_POINT object with the first summand
562 * \param b EC_POINT object with the second summand
563 * \param ctx BN_CTX object (optional)
564 * \return 1 on success and 0 if an error occured
565 */
566int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
567
568/** Computes the double of a EC_POINT
569 * \param group underlying EC_GROUP object
570 * \param r EC_POINT object for the result (r = 2 * a)
571 * \param a EC_POINT object
572 * \param ctx BN_CTX object (optional)
573 * \return 1 on success and 0 if an error occured
574 */
575int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
576
577/** Computes the inverse of a EC_POINT
578 * \param group underlying EC_GROUP object
579 * \param a EC_POINT object to be inverted (it's used for the result as well)
580 * \param ctx BN_CTX object (optional)
581 * \return 1 on success and 0 if an error occured
582 */
583int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
584
585/** Checks whether the point is the neutral element of the group
586 * \param group the underlying EC_GROUP object
587 * \param p EC_POINT object
588 * \return 1 if the point is the neutral element and 0 otherwise
589 */
590int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
591
592/** Checks whether the point is on the curve
593 * \param group underlying EC_GROUP object
594 * \param point EC_POINT object to check
595 * \param ctx BN_CTX object (optional)
596 * \return 1 if point if on the curve and 0 otherwise
597 */
598int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
599
600/** Compares two EC_POINTs
601 * \param group underlying EC_GROUP object
602 * \param a first EC_POINT object
603 * \param b second EC_POINT object
604 * \param ctx BN_CTX object (optional)
605 * \return 0 if both points are equal and a value != 0 otherwise
606 */
607int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
608
609int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
610int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
611
612/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
613 * \param group underlying EC_GROUP object
614 * \param r EC_POINT object for the result
615 * \param n BIGNUM with the multiplier for the group generator (optional)
616 * \param num number futher summands
617 * \param p array of size num of EC_POINT objects
618 * \param m array of size num of BIGNUM objects
619 * \param ctx BN_CTX object (optional)
620 * \return 1 on success and 0 if an error occured
621 */
622int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
623
624/** Computes r = generator * n + q * m
625 * \param group underlying EC_GROUP object
626 * \param r EC_POINT object for the result
627 * \param n BIGNUM with the multiplier for the group generator (optional)
628 * \param q EC_POINT object with the first factor of the second summand
629 * \param m BIGNUM with the second factor of the second summand
630 * \param ctx BN_CTX object (optional)
631 * \return 1 on success and 0 if an error occured
632 */
633int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
634
635/** Stores multiples of generator for faster point multiplication
636 * \param group EC_GROUP object
637 * \param ctx BN_CTX object (optional)
638 * \return 1 on success and 0 if an error occured
639 */
640int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
641
642/** Reports whether a precomputation has been done
643 * \param group EC_GROUP object
644 * \return 1 if a pre-computation has been done and 0 otherwise
645 */
646int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
647
648
649/********************************************************************/
650/* ASN1 stuff */
651/********************************************************************/
652
653/* EC_GROUP_get_basis_type() returns the NID of the basis type
654 * used to represent the field elements */
655int EC_GROUP_get_basis_type(const EC_GROUP *);
656int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
657int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
658 unsigned int *k2, unsigned int *k3);
659
660#define OPENSSL_EC_NAMED_CURVE 0x001
661
662typedef struct ecpk_parameters_st ECPKPARAMETERS;
663
664EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
665int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
666
667#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
668#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
669#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
670 (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
671#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
672 (unsigned char *)(x))
673
674#ifndef OPENSSL_NO_BIO
675int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
676#endif
677#ifndef OPENSSL_NO_FP_API
678int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
679#endif
680
681
682/********************************************************************/
683/* EC_KEY functions */
684/********************************************************************/
685
686typedef struct ec_key_st EC_KEY;
687
688/* some values for the encoding_flag */
689#define EC_PKEY_NO_PARAMETERS 0x001
690#define EC_PKEY_NO_PUBKEY 0x002
691
692/** Creates a new EC_KEY object.
693 * \return EC_KEY object or NULL if an error occurred.
694 */
695EC_KEY *EC_KEY_new(void);
696
697/** Creates a new EC_KEY object using a named curve as underlying
698 * EC_GROUP object.
699 * \param nid NID of the named curve.
700 * \return EC_KEY object or NULL if an error occurred.
701 */
702EC_KEY *EC_KEY_new_by_curve_name(int nid);
703
704/** Frees a EC_KEY object.
705 * \param key EC_KEY object to be freed.
706 */
707void EC_KEY_free(EC_KEY *key);
708
709/** Copies a EC_KEY object.
710 * \param dst destination EC_KEY object
711 * \param src src EC_KEY object
712 * \return dst or NULL if an error occurred.
713 */
714EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
715
716/** Creates a new EC_KEY object and copies the content from src to it.
717 * \param src the source EC_KEY object
718 * \return newly created EC_KEY object or NULL if an error occurred.
719 */
720EC_KEY *EC_KEY_dup(const EC_KEY *src);
721
722/** Increases the internal reference count of a EC_KEY object.
723 * \param key EC_KEY object
724 * \return 1 on success and 0 if an error occurred.
725 */
726int EC_KEY_up_ref(EC_KEY *key);
727
728/** Returns the EC_GROUP object of a EC_KEY object
729 * \param key EC_KEY object
730 * \return the EC_GROUP object (possibly NULL).
731 */
732const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
733
734/** Sets the EC_GROUP of a EC_KEY object.
735 * \param key EC_KEY object
736 * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY
737 * object will use an own copy of the EC_GROUP).
738 * \return 1 on success and 0 if an error occurred.
739 */
740int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
741
742/** Returns the private key of a EC_KEY object.
743 * \param key EC_KEY object
744 * \return a BIGNUM with the private key (possibly NULL).
745 */
746const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
747
748/** Sets the private key of a EC_KEY object.
749 * \param key EC_KEY object
750 * \param prv BIGNUM with the private key (note: the EC_KEY object
751 * will use an own copy of the BIGNUM).
752 * \return 1 on success and 0 if an error occurred.
753 */
754int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
755
756/** Returns the public key of a EC_KEY object.
757 * \param key the EC_KEY object
758 * \return a EC_POINT object with the public key (possibly NULL)
759 */
760const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
761
762/** Sets the public key of a EC_KEY object.
763 * \param key EC_KEY object
764 * \param pub EC_POINT object with the public key (note: the EC_KEY object
765 * will use an own copy of the EC_POINT object).
766 * \return 1 on success and 0 if an error occurred.
767 */
768int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
769
770unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
771void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
772point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
773void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
774/* functions to set/get method specific data */
775void *EC_KEY_get_key_method_data(EC_KEY *,
776 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
777void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
778 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
779/* wrapper functions for the underlying EC_GROUP object */
780void EC_KEY_set_asn1_flag(EC_KEY *, int);
781
782/** Creates a table of pre-computed multiples of the generator to
783 * accelerate further EC_KEY operations.
784 * \param key EC_KEY object
785 * \param ctx BN_CTX object (optional)
786 * \return 1 on success and 0 if an error occurred.
787 */
788int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
789
790/** Creates a new ec private (and optional a new public) key.
791 * \param key EC_KEY object
792 * \return 1 on success and 0 if an error occurred.
793 */
794int EC_KEY_generate_key(EC_KEY *key);
795
796/** Verifies that a private and/or public key is valid.
797 * \param key the EC_KEY object
798 * \return 1 on success and 0 otherwise.
799 */
800int EC_KEY_check_key(const EC_KEY *key);
801
802
803/********************************************************************/
804/* de- and encoding functions for SEC1 ECPrivateKey */
805/********************************************************************/
806
807/** Decodes a private key from a memory buffer.
808 * \param key a pointer to a EC_KEY object which should be used (or NULL)
809 * \param in pointer to memory with the DER encoded private key
810 * \param len length of the DER encoded private key
811 * \return the decoded private key or NULL if an error occurred.
812 */
813EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
814
815/** Encodes a private key object and stores the result in a buffer.
816 * \param key the EC_KEY object to encode
817 * \param out the buffer for the result (if NULL the function returns number
818 * of bytes needed).
819 * \return 1 on success and 0 if an error occurred.
820 */
821int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
822
823
824/********************************************************************/
825/* de- and encoding functions for EC parameters */
826/********************************************************************/
827
828/** Decodes ec parameter from a memory buffer.
829 * \param key a pointer to a EC_KEY object which should be used (or NULL)
830 * \param in pointer to memory with the DER encoded ec parameters
831 * \param len length of the DER encoded ec parameters
832 * \return a EC_KEY object with the decoded parameters or NULL if an error
833 * occurred.
834 */
835EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
836
837/** Encodes ec parameter and stores the result in a buffer.
838 * \param key the EC_KEY object with ec paramters to encode
839 * \param out the buffer for the result (if NULL the function returns number
840 * of bytes needed).
841 * \return 1 on success and 0 if an error occurred.
842 */
843int i2d_ECParameters(EC_KEY *key, unsigned char **out);
844
845
846/********************************************************************/
847/* de- and encoding functions for EC public key */
848/* (octet string, not DER -- hence 'o2i' and 'i2o') */
849/********************************************************************/
850
851/** Decodes a ec public key from a octet string.
852 * \param key a pointer to a EC_KEY object which should be used
853 * \param in memory buffer with the encoded public key
854 * \param len length of the encoded public key
855 * \return EC_KEY object with decoded public key or NULL if an error
856 * occurred.
857 */
858EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
859
860/** Encodes a ec public key in an octet string.
861 * \param key the EC_KEY object with the public key
862 * \param out the buffer for the result (if NULL the function returns number
863 * of bytes needed).
864 * \return 1 on success and 0 if an error occurred
865 */
866int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
867
868#ifndef OPENSSL_NO_BIO
869/** Prints out the ec parameters on human readable form.
870 * \param bp BIO object to which the information is printed
871 * \param key EC_KEY object
872 * \return 1 on success and 0 if an error occurred
873 */
874int ECParameters_print(BIO *bp, const EC_KEY *key);
875
876/** Prints out the contents of a EC_KEY object
877 * \param bp BIO object to which the information is printed
878 * \param key EC_KEY object
879 * \param off line offset
880 * \return 1 on success and 0 if an error occurred
881 */
882int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
883
884#endif
885#ifndef OPENSSL_NO_FP_API
886/** Prints out the ec parameters on human readable form.
887 * \param fp file descriptor to which the information is printed
888 * \param key EC_KEY object
889 * \return 1 on success and 0 if an error occurred
890 */
891int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
892
893/** Prints out the contents of a EC_KEY object
894 * \param fp file descriptor to which the information is printed
895 * \param key EC_KEY object
896 * \param off line offset
897 * \return 1 on success and 0 if an error occurred
898 */
899int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
900
901#endif
902
903#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
904
905#ifndef __cplusplus
906#if defined(__SUNPRO_C)
907# if __SUNPRO_C >= 0x520
908# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
909# endif
910# endif
911#endif
912
913#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
914 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
915 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
916
917
918#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
919
920/* BEGIN ERROR CODES */
921/* The following lines are auto generated by the script mkerr.pl. Any changes
922 * made after this point may be overwritten when the script is next run.
923 */
924void ERR_load_EC_strings(void);
925
926/* Error codes for the EC functions. */
927
928/* Function codes. */
929#define EC_F_COMPUTE_WNAF 143
930#define EC_F_D2I_ECPARAMETERS 144
931#define EC_F_D2I_ECPKPARAMETERS 145
932#define EC_F_D2I_ECPRIVATEKEY 146
933#define EC_F_DO_EC_KEY_PRINT 221
934#define EC_F_ECKEY_PARAM2TYPE 223
935#define EC_F_ECKEY_PARAM_DECODE 212
936#define EC_F_ECKEY_PRIV_DECODE 213
937#define EC_F_ECKEY_PRIV_ENCODE 214
938#define EC_F_ECKEY_PUB_DECODE 215
939#define EC_F_ECKEY_PUB_ENCODE 216
940#define EC_F_ECKEY_TYPE2PARAM 220
941#define EC_F_ECPARAMETERS_PRINT 147
942#define EC_F_ECPARAMETERS_PRINT_FP 148
943#define EC_F_ECPKPARAMETERS_PRINT 149
944#define EC_F_ECPKPARAMETERS_PRINT_FP 150
945#define EC_F_ECP_NIST_MOD_192 203
946#define EC_F_ECP_NIST_MOD_224 204
947#define EC_F_ECP_NIST_MOD_256 205
948#define EC_F_ECP_NIST_MOD_521 206
949#define EC_F_EC_ASN1_GROUP2CURVE 153
950#define EC_F_EC_ASN1_GROUP2FIELDID 154
951#define EC_F_EC_ASN1_GROUP2PARAMETERS 155
952#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156
953#define EC_F_EC_ASN1_PARAMETERS2GROUP 157
954#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158
955#define EC_F_EC_EX_DATA_SET_DATA 211
956#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208
957#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159
958#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195
959#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160
960#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161
961#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
962#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
963#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164
964#define EC_F_EC_GFP_MONT_FIELD_DECODE 133
965#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
966#define EC_F_EC_GFP_MONT_FIELD_MUL 131
967#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209
968#define EC_F_EC_GFP_MONT_FIELD_SQR 132
969#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
970#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
971#define EC_F_EC_GFP_NIST_FIELD_MUL 200
972#define EC_F_EC_GFP_NIST_FIELD_SQR 201
973#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
974#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
975#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
976#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
977#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
978#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
979#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
980#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
981#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
982#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167
983#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
984#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168
985#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
986#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169
987#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
988#define EC_F_EC_GROUP_CHECK 170
989#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171
990#define EC_F_EC_GROUP_COPY 106
991#define EC_F_EC_GROUP_GET0_GENERATOR 139
992#define EC_F_EC_GROUP_GET_COFACTOR 140
993#define EC_F_EC_GROUP_GET_CURVE_GF2M 172
994#define EC_F_EC_GROUP_GET_CURVE_GFP 130
995#define EC_F_EC_GROUP_GET_DEGREE 173
996#define EC_F_EC_GROUP_GET_ORDER 141
997#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193
998#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194
999#define EC_F_EC_GROUP_NEW 108
1000#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174
1001#define EC_F_EC_GROUP_NEW_FROM_DATA 175
1002#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142
1003#define EC_F_EC_GROUP_SET_CURVE_GF2M 176
1004#define EC_F_EC_GROUP_SET_CURVE_GFP 109
1005#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
1006#define EC_F_EC_GROUP_SET_GENERATOR 111
1007#define EC_F_EC_KEY_CHECK_KEY 177
1008#define EC_F_EC_KEY_COPY 178
1009#define EC_F_EC_KEY_GENERATE_KEY 179
1010#define EC_F_EC_KEY_NEW 182
1011#define EC_F_EC_KEY_PRINT 180
1012#define EC_F_EC_KEY_PRINT_FP 181
1013#define EC_F_EC_POINTS_MAKE_AFFINE 136
1014#define EC_F_EC_POINT_ADD 112
1015#define EC_F_EC_POINT_CMP 113
1016#define EC_F_EC_POINT_COPY 114
1017#define EC_F_EC_POINT_DBL 115
1018#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183
1019#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116
1020#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117
1021#define EC_F_EC_POINT_INVERT 210
1022#define EC_F_EC_POINT_IS_AT_INFINITY 118
1023#define EC_F_EC_POINT_IS_ON_CURVE 119
1024#define EC_F_EC_POINT_MAKE_AFFINE 120
1025#define EC_F_EC_POINT_MUL 184
1026#define EC_F_EC_POINT_NEW 121
1027#define EC_F_EC_POINT_OCT2POINT 122
1028#define EC_F_EC_POINT_POINT2OCT 123
1029#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185
1030#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124
1031#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186
1032#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125
1033#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126
1034#define EC_F_EC_POINT_SET_TO_INFINITY 127
1035#define EC_F_EC_PRE_COMP_DUP 207
1036#define EC_F_EC_PRE_COMP_NEW 196
1037#define EC_F_EC_WNAF_MUL 187
1038#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
1039#define EC_F_I2D_ECPARAMETERS 190
1040#define EC_F_I2D_ECPKPARAMETERS 191
1041#define EC_F_I2D_ECPRIVATEKEY 192
1042#define EC_F_I2O_ECPUBLICKEY 151
1043#define EC_F_O2I_ECPUBLICKEY 152
1044#define EC_F_OLD_EC_PRIV_DECODE 222
1045#define EC_F_PKEY_EC_CTRL 197
1046#define EC_F_PKEY_EC_CTRL_STR 198
1047#define EC_F_PKEY_EC_DERIVE 217
1048#define EC_F_PKEY_EC_KEYGEN 199
1049#define EC_F_PKEY_EC_PARAMGEN 219
1050#define EC_F_PKEY_EC_SIGN 218
1051
1052/* Reason codes. */
1053#define EC_R_ASN1_ERROR 115
1054#define EC_R_ASN1_UNKNOWN_FIELD 116
1055#define EC_R_BUFFER_TOO_SMALL 100
1056#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
1057#define EC_R_DECODE_ERROR 142
1058#define EC_R_DISCRIMINANT_IS_ZERO 118
1059#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
1060#define EC_R_FIELD_TOO_LARGE 143
1061#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
1062#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
1063#define EC_R_INCOMPATIBLE_OBJECTS 101
1064#define EC_R_INVALID_ARGUMENT 112
1065#define EC_R_INVALID_COMPRESSED_POINT 110
1066#define EC_R_INVALID_COMPRESSION_BIT 109
1067#define EC_R_INVALID_CURVE 141
1068#define EC_R_INVALID_DIGEST_TYPE 138
1069#define EC_R_INVALID_ENCODING 102
1070#define EC_R_INVALID_FIELD 103
1071#define EC_R_INVALID_FORM 104
1072#define EC_R_INVALID_GROUP_ORDER 122
1073#define EC_R_INVALID_PENTANOMIAL_BASIS 132
1074#define EC_R_INVALID_PRIVATE_KEY 123
1075#define EC_R_INVALID_TRINOMIAL_BASIS 137
1076#define EC_R_KEYS_NOT_SET 140
1077#define EC_R_MISSING_PARAMETERS 124
1078#define EC_R_MISSING_PRIVATE_KEY 125
1079#define EC_R_NOT_A_NIST_PRIME 135
1080#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136
1081#define EC_R_NOT_IMPLEMENTED 126
1082#define EC_R_NOT_INITIALIZED 111
1083#define EC_R_NO_FIELD_MOD 133
1084#define EC_R_NO_PARAMETERS_SET 139
1085#define EC_R_PASSED_NULL_PARAMETER 134
1086#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
1087#define EC_R_POINT_AT_INFINITY 106
1088#define EC_R_POINT_IS_NOT_ON_CURVE 107
1089#define EC_R_SLOT_FULL 108
1090#define EC_R_UNDEFINED_GENERATOR 113
1091#define EC_R_UNDEFINED_ORDER 128
1092#define EC_R_UNKNOWN_GROUP 129
1093#define EC_R_UNKNOWN_ORDER 114
1094#define EC_R_UNSUPPORTED_FIELD 131
1095#define EC_R_WRONG_ORDER 130
1096
1097#ifdef __cplusplus
1098}
1099#endif
1100#endif
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
deleted file mode 100644
index e12b9b284a..0000000000
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ /dev/null
@@ -1,386 +0,0 @@
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" (CHES '99, LNCS 1717).
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 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
111 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
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 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
144 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
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 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
213 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
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;
220 BN_ULONG mask,word;
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;
255 mask = BN_TBIT;
256 word = scalar->d[i];
257 while (!(word & mask)) mask >>= 1;
258 mask >>= 1;
259 /* if top most bit was at word break, go to next word */
260 if (!mask)
261 {
262 i--;
263 mask = BN_TBIT;
264 }
265
266 for (; i >= 0; i--)
267 {
268 word = scalar->d[i];
269 while (mask)
270 {
271 if (word & mask)
272 {
273 if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
274 if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
275 }
276 else
277 {
278 if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
279 if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
280 }
281 mask >>= 1;
282 }
283 mask = BN_TBIT;
284 }
285
286 /* convert out of "projective" coordinates */
287 i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
288 if (i == 0) goto err;
289 else if (i == 1)
290 {
291 if (!EC_POINT_set_to_infinity(group, r)) goto err;
292 }
293 else
294 {
295 if (!BN_one(&r->Z)) goto err;
296 r->Z_is_one = 1;
297 }
298
299 /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
300 BN_set_negative(&r->X, 0);
301 BN_set_negative(&r->Y, 0);
302
303 ret = 1;
304
305 err:
306 BN_CTX_end(ctx);
307 return ret;
308 }
309
310
311/* Computes the sum
312 * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
313 * gracefully ignoring NULL scalar values.
314 */
315int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
316 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
317 {
318 BN_CTX *new_ctx = NULL;
319 int ret = 0;
320 size_t i;
321 EC_POINT *p=NULL;
322 EC_POINT *acc = NULL;
323
324 if (ctx == NULL)
325 {
326 ctx = new_ctx = BN_CTX_new();
327 if (ctx == NULL)
328 return 0;
329 }
330
331 /* This implementation is more efficient than the wNAF implementation for 2
332 * or fewer points. Use the ec_wNAF_mul implementation for 3 or more points,
333 * or if we can perform a fast multiplication based on precomputation.
334 */
335 if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group)))
336 {
337 ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
338 goto err;
339 }
340
341 if ((p = EC_POINT_new(group)) == NULL) goto err;
342 if ((acc = EC_POINT_new(group)) == NULL) goto err;
343
344 if (!EC_POINT_set_to_infinity(group, acc)) goto err;
345
346 if (scalar)
347 {
348 if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
349 if (BN_is_negative(scalar))
350 if (!group->meth->invert(group, p, ctx)) goto err;
351 if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
352 }
353
354 for (i = 0; i < num; i++)
355 {
356 if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
357 if (BN_is_negative(scalars[i]))
358 if (!group->meth->invert(group, p, ctx)) goto err;
359 if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
360 }
361
362 if (!EC_POINT_copy(r, acc)) goto err;
363
364 ret = 1;
365
366 err:
367 if (p) EC_POINT_free(p);
368 if (acc) EC_POINT_free(acc);
369 if (new_ctx != NULL)
370 BN_CTX_free(new_ctx);
371 return ret;
372 }
373
374
375/* Precomputation for point multiplication: fall back to wNAF methods
376 * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
377
378int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
379 {
380 return ec_wNAF_precompute_mult(group, ctx);
381 }
382
383int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
384 {
385 return ec_wNAF_have_precompute_mult(group);
386 }
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
deleted file mode 100644
index 03deae6674..0000000000
--- a/src/lib/libcrypto/ec/ec2_smpl.c
+++ /dev/null
@@ -1,1042 +0,0 @@
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-2005 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 group->poly[5] = -1;
161 }
162
163
164/* Copy a GF(2^m)-based EC_GROUP structure.
165 * Note that all other members are handled by EC_GROUP_copy.
166 */
167int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
168 {
169 int i;
170 if (!BN_copy(&dest->field, &src->field)) return 0;
171 if (!BN_copy(&dest->a, &src->a)) return 0;
172 if (!BN_copy(&dest->b, &src->b)) return 0;
173 dest->poly[0] = src->poly[0];
174 dest->poly[1] = src->poly[1];
175 dest->poly[2] = src->poly[2];
176 dest->poly[3] = src->poly[3];
177 dest->poly[4] = src->poly[4];
178 dest->poly[5] = src->poly[5];
179 if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
180 if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
181 for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
182 for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
183 return 1;
184 }
185
186
187/* Set the curve parameters of an EC_GROUP structure. */
188int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
189 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
190 {
191 int ret = 0, i;
192
193 /* group->field */
194 if (!BN_copy(&group->field, p)) goto err;
195 i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
196 if ((i != 5) && (i != 3))
197 {
198 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
199 goto err;
200 }
201
202 /* group->a */
203 if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
204 if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
205 for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
206
207 /* group->b */
208 if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
209 if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
210 for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
211
212 ret = 1;
213 err:
214 return ret;
215 }
216
217
218/* Get the curve parameters of an EC_GROUP structure.
219 * If p, a, or b are NULL then there values will not be set but the method will return with success.
220 */
221int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
222 {
223 int ret = 0;
224
225 if (p != NULL)
226 {
227 if (!BN_copy(p, &group->field)) return 0;
228 }
229
230 if (a != NULL)
231 {
232 if (!BN_copy(a, &group->a)) goto err;
233 }
234
235 if (b != NULL)
236 {
237 if (!BN_copy(b, &group->b)) goto err;
238 }
239
240 ret = 1;
241
242 err:
243 return ret;
244 }
245
246
247/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */
248int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
249 {
250 return BN_num_bits(&group->field)-1;
251 }
252
253
254/* Checks the discriminant of the curve.
255 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
256 */
257int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
258 {
259 int ret = 0;
260 BIGNUM *b;
261 BN_CTX *new_ctx = NULL;
262
263 if (ctx == NULL)
264 {
265 ctx = new_ctx = BN_CTX_new();
266 if (ctx == NULL)
267 {
268 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
269 goto err;
270 }
271 }
272 BN_CTX_start(ctx);
273 b = BN_CTX_get(ctx);
274 if (b == NULL) goto err;
275
276 if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
277
278 /* check the discriminant:
279 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
280 */
281 if (BN_is_zero(b)) goto err;
282
283 ret = 1;
284
285err:
286 if (ctx != NULL)
287 BN_CTX_end(ctx);
288 if (new_ctx != NULL)
289 BN_CTX_free(new_ctx);
290 return ret;
291 }
292
293
294/* Initializes an EC_POINT. */
295int ec_GF2m_simple_point_init(EC_POINT *point)
296 {
297 BN_init(&point->X);
298 BN_init(&point->Y);
299 BN_init(&point->Z);
300 return 1;
301 }
302
303
304/* Frees an EC_POINT. */
305void ec_GF2m_simple_point_finish(EC_POINT *point)
306 {
307 BN_free(&point->X);
308 BN_free(&point->Y);
309 BN_free(&point->Z);
310 }
311
312
313/* Clears and frees an EC_POINT. */
314void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
315 {
316 BN_clear_free(&point->X);
317 BN_clear_free(&point->Y);
318 BN_clear_free(&point->Z);
319 point->Z_is_one = 0;
320 }
321
322
323/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */
324int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
325 {
326 if (!BN_copy(&dest->X, &src->X)) return 0;
327 if (!BN_copy(&dest->Y, &src->Y)) return 0;
328 if (!BN_copy(&dest->Z, &src->Z)) return 0;
329 dest->Z_is_one = src->Z_is_one;
330
331 return 1;
332 }
333
334
335/* Set an EC_POINT to the point at infinity.
336 * A point at infinity is represented by having Z=0.
337 */
338int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
339 {
340 point->Z_is_one = 0;
341 BN_zero(&point->Z);
342 return 1;
343 }
344
345
346/* Set the coordinates of an EC_POINT using affine coordinates.
347 * Note that the simple implementation only uses affine coordinates.
348 */
349int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
350 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
351 {
352 int ret = 0;
353 if (x == NULL || y == NULL)
354 {
355 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
356 return 0;
357 }
358
359 if (!BN_copy(&point->X, x)) goto err;
360 BN_set_negative(&point->X, 0);
361 if (!BN_copy(&point->Y, y)) goto err;
362 BN_set_negative(&point->Y, 0);
363 if (!BN_copy(&point->Z, BN_value_one())) goto err;
364 BN_set_negative(&point->Z, 0);
365 point->Z_is_one = 1;
366 ret = 1;
367
368 err:
369 return ret;
370 }
371
372
373/* Gets the affine coordinates of an EC_POINT.
374 * Note that the simple implementation only uses affine coordinates.
375 */
376int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
377 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
378 {
379 int ret = 0;
380
381 if (EC_POINT_is_at_infinity(group, point))
382 {
383 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
384 return 0;
385 }
386
387 if (BN_cmp(&point->Z, BN_value_one()))
388 {
389 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
390 return 0;
391 }
392 if (x != NULL)
393 {
394 if (!BN_copy(x, &point->X)) goto err;
395 BN_set_negative(x, 0);
396 }
397 if (y != NULL)
398 {
399 if (!BN_copy(y, &point->Y)) goto err;
400 BN_set_negative(y, 0);
401 }
402 ret = 1;
403
404 err:
405 return ret;
406 }
407
408
409/* Calculates and sets the affine coordinates of an EC_POINT from the given
410 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
411 * Note that the simple implementation only uses affine coordinates.
412 *
413 * The method is from the following publication:
414 *
415 * Harper, Menezes, Vanstone:
416 * "Public-Key Cryptosystems with Very Small Key Lengths",
417 * EUROCRYPT '92, Springer-Verlag LNCS 658,
418 * published February 1993
419 *
420 * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
421 * the same method, but claim no priority date earlier than July 29, 1994
422 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
423 */
424int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
425 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
426 {
427 BN_CTX *new_ctx = NULL;
428 BIGNUM *tmp, *x, *y, *z;
429 int ret = 0, z0;
430
431 /* clear error queue */
432 ERR_clear_error();
433
434 if (ctx == NULL)
435 {
436 ctx = new_ctx = BN_CTX_new();
437 if (ctx == NULL)
438 return 0;
439 }
440
441 y_bit = (y_bit != 0) ? 1 : 0;
442
443 BN_CTX_start(ctx);
444 tmp = BN_CTX_get(ctx);
445 x = BN_CTX_get(ctx);
446 y = BN_CTX_get(ctx);
447 z = BN_CTX_get(ctx);
448 if (z == NULL) goto err;
449
450 if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
451 if (BN_is_zero(x))
452 {
453 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
454 }
455 else
456 {
457 if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
458 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
459 if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
460 if (!BN_GF2m_add(tmp, x, tmp)) goto err;
461 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
462 {
463 unsigned long err = ERR_peek_last_error();
464
465 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
466 {
467 ERR_clear_error();
468 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
469 }
470 else
471 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
472 goto err;
473 }
474 z0 = (BN_is_odd(z)) ? 1 : 0;
475 if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
476 if (z0 != y_bit)
477 {
478 if (!BN_GF2m_add(y, y, x)) goto err;
479 }
480 }
481
482 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
483
484 ret = 1;
485
486 err:
487 BN_CTX_end(ctx);
488 if (new_ctx != NULL)
489 BN_CTX_free(new_ctx);
490 return ret;
491 }
492
493
494/* Converts an EC_POINT to an octet string.
495 * If buf is NULL, the encoded length will be returned.
496 * If the length len of buf is smaller than required an error will be returned.
497 */
498size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
499 unsigned char *buf, size_t len, BN_CTX *ctx)
500 {
501 size_t ret;
502 BN_CTX *new_ctx = NULL;
503 int used_ctx = 0;
504 BIGNUM *x, *y, *yxi;
505 size_t field_len, i, skip;
506
507 if ((form != POINT_CONVERSION_COMPRESSED)
508 && (form != POINT_CONVERSION_UNCOMPRESSED)
509 && (form != POINT_CONVERSION_HYBRID))
510 {
511 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
512 goto err;
513 }
514
515 if (EC_POINT_is_at_infinity(group, point))
516 {
517 /* encodes to a single 0 octet */
518 if (buf != NULL)
519 {
520 if (len < 1)
521 {
522 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
523 return 0;
524 }
525 buf[0] = 0;
526 }
527 return 1;
528 }
529
530
531 /* ret := required output buffer length */
532 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
533 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
534
535 /* if 'buf' is NULL, just return required length */
536 if (buf != NULL)
537 {
538 if (len < ret)
539 {
540 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
541 goto err;
542 }
543
544 if (ctx == NULL)
545 {
546 ctx = new_ctx = BN_CTX_new();
547 if (ctx == NULL)
548 return 0;
549 }
550
551 BN_CTX_start(ctx);
552 used_ctx = 1;
553 x = BN_CTX_get(ctx);
554 y = BN_CTX_get(ctx);
555 yxi = BN_CTX_get(ctx);
556 if (yxi == NULL) goto err;
557
558 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
559
560 buf[0] = form;
561 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
562 {
563 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
564 if (BN_is_odd(yxi)) buf[0]++;
565 }
566
567 i = 1;
568
569 skip = field_len - BN_num_bytes(x);
570 if (skip > field_len)
571 {
572 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
573 goto err;
574 }
575 while (skip > 0)
576 {
577 buf[i++] = 0;
578 skip--;
579 }
580 skip = BN_bn2bin(x, buf + i);
581 i += skip;
582 if (i != 1 + field_len)
583 {
584 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
585 goto err;
586 }
587
588 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
589 {
590 skip = field_len - BN_num_bytes(y);
591 if (skip > field_len)
592 {
593 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
594 goto err;
595 }
596 while (skip > 0)
597 {
598 buf[i++] = 0;
599 skip--;
600 }
601 skip = BN_bn2bin(y, buf + i);
602 i += skip;
603 }
604
605 if (i != ret)
606 {
607 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
608 goto err;
609 }
610 }
611
612 if (used_ctx)
613 BN_CTX_end(ctx);
614 if (new_ctx != NULL)
615 BN_CTX_free(new_ctx);
616 return ret;
617
618 err:
619 if (used_ctx)
620 BN_CTX_end(ctx);
621 if (new_ctx != NULL)
622 BN_CTX_free(new_ctx);
623 return 0;
624 }
625
626
627/* Converts an octet string representation to an EC_POINT.
628 * Note that the simple implementation only uses affine coordinates.
629 */
630int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
631 const unsigned char *buf, size_t len, BN_CTX *ctx)
632 {
633 point_conversion_form_t form;
634 int y_bit;
635 BN_CTX *new_ctx = NULL;
636 BIGNUM *x, *y, *yxi;
637 size_t field_len, enc_len;
638 int ret = 0;
639
640 if (len == 0)
641 {
642 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
643 return 0;
644 }
645 form = buf[0];
646 y_bit = form & 1;
647 form = form & ~1U;
648 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
649 && (form != POINT_CONVERSION_UNCOMPRESSED)
650 && (form != POINT_CONVERSION_HYBRID))
651 {
652 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
653 return 0;
654 }
655 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
656 {
657 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
658 return 0;
659 }
660
661 if (form == 0)
662 {
663 if (len != 1)
664 {
665 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
666 return 0;
667 }
668
669 return EC_POINT_set_to_infinity(group, point);
670 }
671
672 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
673 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
674
675 if (len != enc_len)
676 {
677 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
678 return 0;
679 }
680
681 if (ctx == NULL)
682 {
683 ctx = new_ctx = BN_CTX_new();
684 if (ctx == NULL)
685 return 0;
686 }
687
688 BN_CTX_start(ctx);
689 x = BN_CTX_get(ctx);
690 y = BN_CTX_get(ctx);
691 yxi = BN_CTX_get(ctx);
692 if (yxi == NULL) goto err;
693
694 if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
695 if (BN_ucmp(x, &group->field) >= 0)
696 {
697 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
698 goto err;
699 }
700
701 if (form == POINT_CONVERSION_COMPRESSED)
702 {
703 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
704 }
705 else
706 {
707 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
708 if (BN_ucmp(y, &group->field) >= 0)
709 {
710 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
711 goto err;
712 }
713 if (form == POINT_CONVERSION_HYBRID)
714 {
715 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
716 if (y_bit != BN_is_odd(yxi))
717 {
718 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
719 goto err;
720 }
721 }
722
723 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
724 }
725
726 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
727 {
728 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
729 goto err;
730 }
731
732 ret = 1;
733
734 err:
735 BN_CTX_end(ctx);
736 if (new_ctx != NULL)
737 BN_CTX_free(new_ctx);
738 return ret;
739 }
740
741
742/* Computes a + b and stores the result in r. r could be a or b, a could be b.
743 * Uses algorithm A.10.2 of IEEE P1363.
744 */
745int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
746 {
747 BN_CTX *new_ctx = NULL;
748 BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
749 int ret = 0;
750
751 if (EC_POINT_is_at_infinity(group, a))
752 {
753 if (!EC_POINT_copy(r, b)) return 0;
754 return 1;
755 }
756
757 if (EC_POINT_is_at_infinity(group, b))
758 {
759 if (!EC_POINT_copy(r, a)) return 0;
760 return 1;
761 }
762
763 if (ctx == NULL)
764 {
765 ctx = new_ctx = BN_CTX_new();
766 if (ctx == NULL)
767 return 0;
768 }
769
770 BN_CTX_start(ctx);
771 x0 = BN_CTX_get(ctx);
772 y0 = BN_CTX_get(ctx);
773 x1 = BN_CTX_get(ctx);
774 y1 = BN_CTX_get(ctx);
775 x2 = BN_CTX_get(ctx);
776 y2 = BN_CTX_get(ctx);
777 s = BN_CTX_get(ctx);
778 t = BN_CTX_get(ctx);
779 if (t == NULL) goto err;
780
781 if (a->Z_is_one)
782 {
783 if (!BN_copy(x0, &a->X)) goto err;
784 if (!BN_copy(y0, &a->Y)) goto err;
785 }
786 else
787 {
788 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
789 }
790 if (b->Z_is_one)
791 {
792 if (!BN_copy(x1, &b->X)) goto err;
793 if (!BN_copy(y1, &b->Y)) goto err;
794 }
795 else
796 {
797 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
798 }
799
800
801 if (BN_GF2m_cmp(x0, x1))
802 {
803 if (!BN_GF2m_add(t, x0, x1)) goto err;
804 if (!BN_GF2m_add(s, y0, y1)) goto err;
805 if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
806 if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
807 if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
808 if (!BN_GF2m_add(x2, x2, s)) goto err;
809 if (!BN_GF2m_add(x2, x2, t)) goto err;
810 }
811 else
812 {
813 if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
814 {
815 if (!EC_POINT_set_to_infinity(group, r)) goto err;
816 ret = 1;
817 goto err;
818 }
819 if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
820 if (!BN_GF2m_add(s, s, x1)) goto err;
821
822 if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
823 if (!BN_GF2m_add(x2, x2, s)) goto err;
824 if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
825 }
826
827 if (!BN_GF2m_add(y2, x1, x2)) goto err;
828 if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
829 if (!BN_GF2m_add(y2, y2, x2)) goto err;
830 if (!BN_GF2m_add(y2, y2, y1)) goto err;
831
832 if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
833
834 ret = 1;
835
836 err:
837 BN_CTX_end(ctx);
838 if (new_ctx != NULL)
839 BN_CTX_free(new_ctx);
840 return ret;
841 }
842
843
844/* Computes 2 * a and stores the result in r. r could be a.
845 * Uses algorithm A.10.2 of IEEE P1363.
846 */
847int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
848 {
849 return ec_GF2m_simple_add(group, r, a, a, ctx);
850 }
851
852
853int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
854 {
855 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
856 /* point is its own inverse */
857 return 1;
858
859 if (!EC_POINT_make_affine(group, point, ctx)) return 0;
860 return BN_GF2m_add(&point->Y, &point->X, &point->Y);
861 }
862
863
864/* Indicates whether the given point is the point at infinity. */
865int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
866 {
867 return BN_is_zero(&point->Z);
868 }
869
870
871/* Determines whether the given EC_POINT is an actual point on the curve defined
872 * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
873 * y^2 + x*y = x^3 + a*x^2 + b.
874 */
875int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
876 {
877 int ret = -1;
878 BN_CTX *new_ctx = NULL;
879 BIGNUM *lh, *y2;
880 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
881 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
882
883 if (EC_POINT_is_at_infinity(group, point))
884 return 1;
885
886 field_mul = group->meth->field_mul;
887 field_sqr = group->meth->field_sqr;
888
889 /* only support affine coordinates */
890 if (!point->Z_is_one) return -1;
891
892 if (ctx == NULL)
893 {
894 ctx = new_ctx = BN_CTX_new();
895 if (ctx == NULL)
896 return -1;
897 }
898
899 BN_CTX_start(ctx);
900 y2 = BN_CTX_get(ctx);
901 lh = BN_CTX_get(ctx);
902 if (lh == NULL) goto err;
903
904 /* We have a curve defined by a Weierstrass equation
905 * y^2 + x*y = x^3 + a*x^2 + b.
906 * <=> x^3 + a*x^2 + x*y + b + y^2 = 0
907 * <=> ((x + a) * x + y ) * x + b + y^2 = 0
908 */
909 if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
910 if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
911 if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
912 if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
913 if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
914 if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
915 if (!BN_GF2m_add(lh, lh, y2)) goto err;
916 ret = BN_is_zero(lh);
917 err:
918 if (ctx) BN_CTX_end(ctx);
919 if (new_ctx) BN_CTX_free(new_ctx);
920 return ret;
921 }
922
923
924/* Indicates whether two points are equal.
925 * Return values:
926 * -1 error
927 * 0 equal (in affine coordinates)
928 * 1 not equal
929 */
930int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
931 {
932 BIGNUM *aX, *aY, *bX, *bY;
933 BN_CTX *new_ctx = NULL;
934 int ret = -1;
935
936 if (EC_POINT_is_at_infinity(group, a))
937 {
938 return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
939 }
940
941 if (EC_POINT_is_at_infinity(group, b))
942 return 1;
943
944 if (a->Z_is_one && b->Z_is_one)
945 {
946 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
947 }
948
949 if (ctx == NULL)
950 {
951 ctx = new_ctx = BN_CTX_new();
952 if (ctx == NULL)
953 return -1;
954 }
955
956 BN_CTX_start(ctx);
957 aX = BN_CTX_get(ctx);
958 aY = BN_CTX_get(ctx);
959 bX = BN_CTX_get(ctx);
960 bY = BN_CTX_get(ctx);
961 if (bY == NULL) goto err;
962
963 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
964 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
965 ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
966
967 err:
968 if (ctx) BN_CTX_end(ctx);
969 if (new_ctx) BN_CTX_free(new_ctx);
970 return ret;
971 }
972
973
974/* Forces the given EC_POINT to internally use affine coordinates. */
975int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
976 {
977 BN_CTX *new_ctx = NULL;
978 BIGNUM *x, *y;
979 int ret = 0;
980
981 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
982 return 1;
983
984 if (ctx == NULL)
985 {
986 ctx = new_ctx = BN_CTX_new();
987 if (ctx == NULL)
988 return 0;
989 }
990
991 BN_CTX_start(ctx);
992 x = BN_CTX_get(ctx);
993 y = BN_CTX_get(ctx);
994 if (y == NULL) goto err;
995
996 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
997 if (!BN_copy(&point->X, x)) goto err;
998 if (!BN_copy(&point->Y, y)) goto err;
999 if (!BN_one(&point->Z)) goto err;
1000
1001 ret = 1;
1002
1003 err:
1004 if (ctx) BN_CTX_end(ctx);
1005 if (new_ctx) BN_CTX_free(new_ctx);
1006 return ret;
1007 }
1008
1009
1010/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
1011int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1012 {
1013 size_t i;
1014
1015 for (i = 0; i < num; i++)
1016 {
1017 if (!group->meth->make_affine(group, points[i], ctx)) return 0;
1018 }
1019
1020 return 1;
1021 }
1022
1023
1024/* Wrapper to simple binary polynomial field multiplication implementation. */
1025int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1026 {
1027 return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
1028 }
1029
1030
1031/* Wrapper to simple binary polynomial field squaring implementation. */
1032int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
1033 {
1034 return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
1035 }
1036
1037
1038/* Wrapper to simple binary polynomial field division implementation. */
1039int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1040 {
1041 return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
1042 }
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
deleted file mode 100644
index c00f7d746c..0000000000
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ /dev/null
@@ -1,659 +0,0 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/ec.h>
62#include <openssl/bn.h>
63#ifndef OPENSSL_NO_CMS
64#include <openssl/cms.h>
65#endif
66#include "asn1_locl.h"
67
68static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
69 {
70 const EC_GROUP *group;
71 int nid;
72 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
73 {
74 ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
75 return 0;
76 }
77 if (EC_GROUP_get_asn1_flag(group)
78 && (nid = EC_GROUP_get_curve_name(group)))
79 /* we have a 'named curve' => just set the OID */
80 {
81 *ppval = OBJ_nid2obj(nid);
82 *pptype = V_ASN1_OBJECT;
83 }
84 else /* explicit parameters */
85 {
86 ASN1_STRING *pstr = NULL;
87 pstr = ASN1_STRING_new();
88 if (!pstr)
89 return 0;
90 pstr->length = i2d_ECParameters(ec_key, &pstr->data);
91 if (pstr->length < 0)
92 {
93 ASN1_STRING_free(pstr);
94 ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
95 return 0;
96 }
97 *ppval = pstr;
98 *pptype = V_ASN1_SEQUENCE;
99 }
100 return 1;
101 }
102
103static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
104 {
105 EC_KEY *ec_key = pkey->pkey.ec;
106 void *pval = NULL;
107 int ptype;
108 unsigned char *penc = NULL, *p;
109 int penclen;
110
111 if (!eckey_param2type(&ptype, &pval, ec_key))
112 {
113 ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
114 return 0;
115 }
116 penclen = i2o_ECPublicKey(ec_key, NULL);
117 if (penclen <= 0)
118 goto err;
119 penc = OPENSSL_malloc(penclen);
120 if (!penc)
121 goto err;
122 p = penc;
123 penclen = i2o_ECPublicKey(ec_key, &p);
124 if (penclen <= 0)
125 goto err;
126 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
127 ptype, pval, penc, penclen))
128 return 1;
129 err:
130 if (ptype == V_ASN1_OBJECT)
131 ASN1_OBJECT_free(pval);
132 else
133 ASN1_STRING_free(pval);
134 if (penc)
135 OPENSSL_free(penc);
136 return 0;
137 }
138
139static EC_KEY *eckey_type2param(int ptype, void *pval)
140 {
141 EC_KEY *eckey = NULL;
142 if (ptype == V_ASN1_SEQUENCE)
143 {
144 ASN1_STRING *pstr = pval;
145 const unsigned char *pm = NULL;
146 int pmlen;
147 pm = pstr->data;
148 pmlen = pstr->length;
149 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
150 {
151 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
152 goto ecerr;
153 }
154 }
155 else if (ptype == V_ASN1_OBJECT)
156 {
157 ASN1_OBJECT *poid = pval;
158 EC_GROUP *group;
159
160 /* type == V_ASN1_OBJECT => the parameters are given
161 * by an asn1 OID
162 */
163 if ((eckey = EC_KEY_new()) == NULL)
164 {
165 ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
166 goto ecerr;
167 }
168 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
169 if (group == NULL)
170 goto ecerr;
171 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
172 if (EC_KEY_set_group(eckey, group) == 0)
173 goto ecerr;
174 EC_GROUP_free(group);
175 }
176 else
177 {
178 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
179 goto ecerr;
180 }
181
182 return eckey;
183
184 ecerr:
185 if (eckey)
186 EC_KEY_free(eckey);
187 return NULL;
188 }
189
190static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
191 {
192 const unsigned char *p = NULL;
193 void *pval;
194 int ptype, pklen;
195 EC_KEY *eckey = NULL;
196 X509_ALGOR *palg;
197
198 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
199 return 0;
200 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
201
202 eckey = eckey_type2param(ptype, pval);
203
204 if (!eckey)
205 {
206 ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
207 return 0;
208 }
209
210 /* We have parameters now set public key */
211 if (!o2i_ECPublicKey(&eckey, &p, pklen))
212 {
213 ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
214 goto ecerr;
215 }
216
217 EVP_PKEY_assign_EC_KEY(pkey, eckey);
218 return 1;
219
220 ecerr:
221 if (eckey)
222 EC_KEY_free(eckey);
223 return 0;
224 }
225
226static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
227 {
228 int r;
229 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
230 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
231 *pb = EC_KEY_get0_public_key(b->pkey.ec);
232 r = EC_POINT_cmp(group, pa, pb, NULL);
233 if (r == 0)
234 return 1;
235 if (r == 1)
236 return 0;
237 return -2;
238 }
239
240static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
241 {
242 const unsigned char *p = NULL;
243 void *pval;
244 int ptype, pklen;
245 EC_KEY *eckey = NULL;
246 X509_ALGOR *palg;
247
248 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
249 return 0;
250 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
251
252 eckey = eckey_type2param(ptype, pval);
253
254 if (!eckey)
255 goto ecliberr;
256
257 /* We have parameters now set private key */
258 if (!d2i_ECPrivateKey(&eckey, &p, pklen))
259 {
260 ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
261 goto ecerr;
262 }
263
264 /* calculate public key (if necessary) */
265 if (EC_KEY_get0_public_key(eckey) == NULL)
266 {
267 const BIGNUM *priv_key;
268 const EC_GROUP *group;
269 EC_POINT *pub_key;
270 /* the public key was not included in the SEC1 private
271 * key => calculate the public key */
272 group = EC_KEY_get0_group(eckey);
273 pub_key = EC_POINT_new(group);
274 if (pub_key == NULL)
275 {
276 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
277 goto ecliberr;
278 }
279 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
280 {
281 EC_POINT_free(pub_key);
282 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
283 goto ecliberr;
284 }
285 priv_key = EC_KEY_get0_private_key(eckey);
286 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
287 {
288 EC_POINT_free(pub_key);
289 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
290 goto ecliberr;
291 }
292 if (EC_KEY_set_public_key(eckey, pub_key) == 0)
293 {
294 EC_POINT_free(pub_key);
295 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
296 goto ecliberr;
297 }
298 EC_POINT_free(pub_key);
299 }
300
301 EVP_PKEY_assign_EC_KEY(pkey, eckey);
302 return 1;
303
304 ecliberr:
305 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
306 ecerr:
307 if (eckey)
308 EC_KEY_free(eckey);
309 return 0;
310 }
311
312static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
313{
314 EC_KEY *ec_key;
315 unsigned char *ep, *p;
316 int eplen, ptype;
317 void *pval;
318 unsigned int tmp_flags, old_flags;
319
320 ec_key = pkey->pkey.ec;
321
322 if (!eckey_param2type(&ptype, &pval, ec_key))
323 {
324 ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
325 return 0;
326 }
327
328 /* set the private key */
329
330 /* do not include the parameters in the SEC1 private key
331 * see PKCS#11 12.11 */
332 old_flags = EC_KEY_get_enc_flags(ec_key);
333 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
334 EC_KEY_set_enc_flags(ec_key, tmp_flags);
335 eplen = i2d_ECPrivateKey(ec_key, NULL);
336 if (!eplen)
337 {
338 EC_KEY_set_enc_flags(ec_key, old_flags);
339 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
340 return 0;
341 }
342 ep = (unsigned char *) OPENSSL_malloc(eplen);
343 if (!ep)
344 {
345 EC_KEY_set_enc_flags(ec_key, old_flags);
346 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
347 return 0;
348 }
349 p = ep;
350 if (!i2d_ECPrivateKey(ec_key, &p))
351 {
352 EC_KEY_set_enc_flags(ec_key, old_flags);
353 OPENSSL_free(ep);
354 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
355 }
356 /* restore old encoding flags */
357 EC_KEY_set_enc_flags(ec_key, old_flags);
358
359 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
360 ptype, pval, ep, eplen))
361 return 0;
362
363 return 1;
364}
365
366static int int_ec_size(const EVP_PKEY *pkey)
367 {
368 return ECDSA_size(pkey->pkey.ec);
369 }
370
371static int ec_bits(const EVP_PKEY *pkey)
372 {
373 BIGNUM *order = BN_new();
374 const EC_GROUP *group;
375 int ret;
376
377 if (!order)
378 {
379 ERR_clear_error();
380 return 0;
381 }
382 group = EC_KEY_get0_group(pkey->pkey.ec);
383 if (!EC_GROUP_get_order(group, order, NULL))
384 {
385 ERR_clear_error();
386 return 0;
387 }
388
389 ret = BN_num_bits(order);
390 BN_free(order);
391 return ret;
392 }
393
394static int ec_missing_parameters(const EVP_PKEY *pkey)
395 {
396 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
397 return 1;
398 return 0;
399 }
400
401static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
402 {
403 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
404 if (group == NULL)
405 return 0;
406 if (EC_KEY_set_group(to->pkey.ec, group) == 0)
407 return 0;
408 EC_GROUP_free(group);
409 return 1;
410 }
411
412static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
413 {
414 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
415 *group_b = EC_KEY_get0_group(b->pkey.ec);
416 if (EC_GROUP_cmp(group_a, group_b, NULL))
417 return 0;
418 else
419 return 1;
420 }
421
422static void int_ec_free(EVP_PKEY *pkey)
423 {
424 EC_KEY_free(pkey->pkey.ec);
425 }
426
427static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
428 {
429 unsigned char *buffer=NULL;
430 const char *ecstr;
431 size_t buf_len=0, i;
432 int ret=0, reason=ERR_R_BIO_LIB;
433 BIGNUM *pub_key=NULL, *order=NULL;
434 BN_CTX *ctx=NULL;
435 const EC_GROUP *group;
436 const EC_POINT *public_key;
437 const BIGNUM *priv_key;
438
439 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
440 {
441 reason = ERR_R_PASSED_NULL_PARAMETER;
442 goto err;
443 }
444
445 ctx = BN_CTX_new();
446 if (ctx == NULL)
447 {
448 reason = ERR_R_MALLOC_FAILURE;
449 goto err;
450 }
451
452 if (ktype > 0)
453 {
454 public_key = EC_KEY_get0_public_key(x);
455 if ((pub_key = EC_POINT_point2bn(group, public_key,
456 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
457 {
458 reason = ERR_R_EC_LIB;
459 goto err;
460 }
461 if (pub_key)
462 buf_len = (size_t)BN_num_bytes(pub_key);
463 }
464
465 if (ktype == 2)
466 {
467 priv_key = EC_KEY_get0_private_key(x);
468 if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
469 buf_len = i;
470 }
471 else
472 priv_key = NULL;
473
474 if (ktype > 0)
475 {
476 buf_len += 10;
477 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
478 {
479 reason = ERR_R_MALLOC_FAILURE;
480 goto err;
481 }
482 }
483 if (ktype == 2)
484 ecstr = "Private-Key";
485 else if (ktype == 1)
486 ecstr = "Public-Key";
487 else
488 ecstr = "ECDSA-Parameters";
489
490 if (!BIO_indent(bp, off, 128))
491 goto err;
492 if ((order = BN_new()) == NULL)
493 goto err;
494 if (!EC_GROUP_get_order(group, order, NULL))
495 goto err;
496 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
497 BN_num_bits(order)) <= 0) goto err;
498
499 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
500 buffer, off))
501 goto err;
502 if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
503 buffer, off))
504 goto err;
505 if (!ECPKParameters_print(bp, group, off))
506 goto err;
507 ret=1;
508err:
509 if (!ret)
510 ECerr(EC_F_DO_EC_KEY_PRINT, reason);
511 if (pub_key)
512 BN_free(pub_key);
513 if (order)
514 BN_free(order);
515 if (ctx)
516 BN_CTX_free(ctx);
517 if (buffer != NULL)
518 OPENSSL_free(buffer);
519 return(ret);
520 }
521
522static int eckey_param_decode(EVP_PKEY *pkey,
523 const unsigned char **pder, int derlen)
524 {
525 EC_KEY *eckey;
526 if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
527 {
528 ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
529 return 0;
530 }
531 EVP_PKEY_assign_EC_KEY(pkey, eckey);
532 return 1;
533 }
534
535static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
536 {
537 return i2d_ECParameters(pkey->pkey.ec, pder);
538 }
539
540static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
541 ASN1_PCTX *ctx)
542 {
543 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
544 }
545
546static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
547 ASN1_PCTX *ctx)
548 {
549 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
550 }
551
552
553static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
554 ASN1_PCTX *ctx)
555 {
556 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
557 }
558
559static int old_ec_priv_decode(EVP_PKEY *pkey,
560 const unsigned char **pder, int derlen)
561 {
562 EC_KEY *ec;
563 if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
564 {
565 ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
566 return 0;
567 }
568 EVP_PKEY_assign_EC_KEY(pkey, ec);
569 return 1;
570 }
571
572static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
573 {
574 return i2d_ECPrivateKey(pkey->pkey.ec, pder);
575 }
576
577static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
578 {
579 switch (op)
580 {
581 case ASN1_PKEY_CTRL_PKCS7_SIGN:
582 if (arg1 == 0)
583 {
584 int snid, hnid;
585 X509_ALGOR *alg1, *alg2;
586 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
587 if (alg1 == NULL || alg1->algorithm == NULL)
588 return -1;
589 hnid = OBJ_obj2nid(alg1->algorithm);
590 if (hnid == NID_undef)
591 return -1;
592 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
593 return -1;
594 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
595 }
596 return 1;
597#ifndef OPENSSL_NO_CMS
598 case ASN1_PKEY_CTRL_CMS_SIGN:
599 if (arg1 == 0)
600 {
601 int snid, hnid;
602 X509_ALGOR *alg1, *alg2;
603 CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
604 &alg1, &alg2);
605 if (alg1 == NULL || alg1->algorithm == NULL)
606 return -1;
607 hnid = OBJ_obj2nid(alg1->algorithm);
608 if (hnid == NID_undef)
609 return -1;
610 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
611 return -1;
612 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
613 }
614 return 1;
615#endif
616
617 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
618 *(int *)arg2 = NID_sha1;
619 return 2;
620
621 default:
622 return -2;
623
624 }
625
626 }
627
628const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
629 {
630 EVP_PKEY_EC,
631 EVP_PKEY_EC,
632 0,
633 "EC",
634 "OpenSSL EC algorithm",
635
636 eckey_pub_decode,
637 eckey_pub_encode,
638 eckey_pub_cmp,
639 eckey_pub_print,
640
641 eckey_priv_decode,
642 eckey_priv_encode,
643 eckey_priv_print,
644
645 int_ec_size,
646 ec_bits,
647
648 eckey_param_decode,
649 eckey_param_encode,
650 ec_missing_parameters,
651 ec_copy_parameters,
652 ec_cmp_parameters,
653 eckey_param_print,
654
655 int_ec_free,
656 ec_pkey_ctrl,
657 old_ec_priv_decode,
658 old_ec_priv_encode
659 };
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
deleted file mode 100644
index ae55539859..0000000000
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ /dev/null
@@ -1,1429 +0,0 @@
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
deleted file mode 100644
index 0e316b4b3f..0000000000
--- a/src/lib/libcrypto/ec/ec_check.c
+++ /dev/null
@@ -1,123 +0,0 @@
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
deleted file mode 100644
index 23274e4031..0000000000
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ /dev/null
@@ -1,2059 +0,0 @@
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 {
77 int field_type, /* either NID_X9_62_prime_field or
78 * NID_X9_62_characteristic_two_field */
79 seed_len,
80 param_len;
81 unsigned int cofactor; /* promoted to BN_ULONG */
82} EC_CURVE_DATA;
83
84/* the nist prime curves */
85static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
86 _EC_NIST_PRIME_192 = {
87 { NID_X9_62_prime_field,20,24,1 },
88 { 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, /* seed */
89 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5,
90
91 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
92 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
93 0xFF,0xFF,0xFF,0xFF,
94 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
95 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
96 0xFF,0xFF,0xFF,0xFC,
97 0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7, /* b */
98 0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC,
99 0xC1,0x46,0xB9,0xB1,
100 0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF, /* x */
101 0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD,
102 0x82,0xFF,0x10,0x12,
103 0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10, /* y */
104 0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1,
105 0x1e,0x79,0x48,0x11,
106 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
107 0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1,
108 0xB4,0xD2,0x28,0x31 }
109 };
110
111static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; }
112 _EC_NIST_PRIME_224 = {
113 { NID_X9_62_prime_field,20,28,1 },
114 { 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, /* seed */
115 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5,
116
117 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
118 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
119 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
120 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
121 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
122 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
123 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
124 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
125 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
126 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
127 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
128 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
129 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
130 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
131 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
132 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
133 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
134 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
135 };
136
137static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; }
138 _EC_NIST_PRIME_384 = {
139 { NID_X9_62_prime_field,20,48,1 },
140 { 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, /* seed */
141 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73,
142
143 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
144 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
145 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
146 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
147 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
148 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
149 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
150 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
151 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
152 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC,
153 0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E, /* b */
154 0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E,
155 0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13,
156 0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D,
157 0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF,
158 0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1, /* x */
159 0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62,
160 0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54,
161 0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C,
162 0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7,
163 0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e, /* y */
164 0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd,
165 0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0,
166 0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d,
167 0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f,
168 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
169 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
170 0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37,
171 0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A,
172 0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 }
173 };
174
175static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; }
176 _EC_NIST_PRIME_521 = {
177 { NID_X9_62_prime_field,20,66,1 },
178 { 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, /* seed */
179 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA,
180
181 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
182 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
183 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
184 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
185 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
186 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
187 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
188 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
189 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
190 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
191 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
192 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
193 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
194 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
195 0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F, /* b */
196 0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA,
197 0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91,
198 0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E,
199 0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07,
200 0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45,
201 0x1F,0xD4,0x6B,0x50,0x3F,0x00,
202 0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD, /* x */
203 0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64,
204 0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60,
205 0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7,
206 0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE,
207 0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E,
208 0x7E,0x31,0xC2,0xE5,0xBD,0x66,
209 0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04, /* y */
210 0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5,
211 0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17,
212 0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4,
213 0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61,
214 0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe,
215 0x94,0x76,0x9f,0xd1,0x66,0x50,
216 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
217 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
218 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
219 0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F,
220 0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0,
221 0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F,
222 0xB7,0x1E,0x91,0x38,0x64,0x09 }
223 };
224
225/* the x9.62 prime curves (minus the nist prime curves) */
226static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
227 _EC_X9_62_PRIME_192V2 = {
228 { NID_X9_62_prime_field,20,24,1 },
229 { 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, /* seed */
230 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6,
231
232 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
233 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
234 0xFF,0xFF,0xFF,0xFF,
235 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
236 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
237 0xFF,0xFF,0xFF,0xFC,
238 0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C, /* b */
239 0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2,
240 0x16,0x68,0xD9,0x53,
241 0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE, /* x */
242 0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69,
243 0x6F,0x48,0x03,0x4A,
244 0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b, /* y */
245 0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9,
246 0x70,0xb2,0xde,0x15,
247 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
248 0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86,
249 0x48,0xD8,0xDD,0x31 }
250 };
251
252static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
253 _EC_X9_62_PRIME_192V3 = {
254 { NID_X9_62_prime_field,20,24,1 },
255 { 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, /* seed */
256 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E,
257
258 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
259 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
260 0xFF,0xFF,0xFF,0xFF,
261 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
262 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
263 0xFF,0xFF,0xFF,0xFC,
264 0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42, /* b */
265 0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25,
266 0x6B,0xD5,0x69,0x16,
267 0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78, /* x */
268 0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E,
269 0x22,0x8F,0x18,0x96,
270 0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49, /* y */
271 0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76,
272 0x48,0xa9,0x43,0xb0,
273 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
274 0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94,
275 0xF6,0x40,0xEC,0x13 }
276 };
277
278static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
279 _EC_X9_62_PRIME_239V1 = {
280 { NID_X9_62_prime_field,20,30,1 },
281 { 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, /* seed */
282 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D,
283
284 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
285 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
286 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
287
288 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
289 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
290 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
291
292 0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6, /* b */
293 0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2,
294 0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A,
295
296 0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33, /* x */
297 0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57,
298 0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF,
299
300 0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40, /* y */
301 0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18,
302 0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae,
303
304 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
305 0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D,
306 0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B }
307 };
308
309static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
310 _EC_X9_62_PRIME_239V2 = {
311 { NID_X9_62_prime_field,20,30,1 },
312 { 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, /* seed */
313 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16,
314
315 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
316 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
317 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
318
319 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
320 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
321 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
322
323 0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5, /* b */
324 0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B,
325 0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C,
326
327 0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9, /* x */
328 0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2,
329 0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7,
330
331 0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d, /* y */
332 0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55,
333 0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba,
334
335 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
336 0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43,
337 0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 }
338 };
339
340static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
341 _EC_X9_62_PRIME_239V3 = {
342 { NID_X9_62_prime_field,20,30,1 },
343 { 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, /* seed */
344 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF,
345
346 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
347 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
348 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
349
350 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
351 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
352 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
353
354 0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4, /* b */
355 0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02,
356 0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E,
357
358 0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00, /* x */
359 0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6,
360 0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A,
361
362 0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d, /* y */
363 0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b,
364 0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3,
365
366 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
367 0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3,
368 0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 }
369 };
370
371
372static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; }
373 _EC_X9_62_PRIME_256V1 = {
374 { NID_X9_62_prime_field,20,32,1 },
375 { 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, /* seed */
376 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90,
377
378 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* p */
379 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
380 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
381 0xFF,0xFF,
382 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* a */
383 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
384 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
385 0xFF,0xFC,
386 0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB, /* b */
387 0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,
388 0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2,
389 0x60,0x4B,
390 0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC, /* x */
391 0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,
392 0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,
393 0xC2,0x96,
394 0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7, /* y */
395 0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57,
396 0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,
397 0x51,0xf5,
398 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF, /* order */
399 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,
400 0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63,
401 0x25,0x51 }
402 };
403
404/* the secg prime curves (minus the nist and x9.62 prime curves) */
405static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
406 _EC_SECG_PRIME_112R1 = {
407 { NID_X9_62_prime_field,20,14,1 },
408 { 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, /* seed */
409 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1,
410
411 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */
412 0xBE,0xAD,0x20,0x8B,
413 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* a */
414 0xBE,0xAD,0x20,0x88,
415 0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89, /* b */
416 0x11,0x70,0x2B,0x22,
417 0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55, /* x */
418 0xF9,0xC2,0xF0,0x98,
419 0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e, /* y */
420 0x0f,0xf7,0x75,0x00,
421 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF, /* order */
422 0xAC,0x65,0x61,0xC5 }
423 };
424
425static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
426 _EC_SECG_PRIME_112R2 = {
427 { NID_X9_62_prime_field,20,14,4 },
428 { 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, /* seed */
429 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4,
430
431 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */
432 0xBE,0xAD,0x20,0x8B,
433 0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6, /* a */
434 0x5C,0x0E,0xF0,0x2C,
435 0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3, /* b */
436 0x4C,0x85,0xD7,0x09,
437 0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D, /* x */
438 0xD0,0x92,0x86,0x43,
439 0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3, /* y */
440 0x6e,0x95,0x6e,0x97,
441 0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1, /* order */
442 0x05,0x20,0xD0,0x4B }
443 };
444
445static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
446 _EC_SECG_PRIME_128R1 = {
447 { NID_X9_62_prime_field,20,16,1 },
448 { 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
449 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79,
450
451 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
452 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
453 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
454 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
455 0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24, /* b */
456 0x99,0x3C,0x2C,0xEE,0x5E,0xD3,
457 0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28, /* x */
458 0x60,0x7C,0xA5,0x2C,0x5B,0x86,
459 0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d, /* y */
460 0xa2,0x92,0xdd,0xed,0x7a,0x83,
461 0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3, /* order */
462 0x0D,0x1B,0x90,0x38,0xA1,0x15 }
463 };
464
465static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
466 _EC_SECG_PRIME_128R2 = {
467 { NID_X9_62_prime_field,20,16,4 },
468 { 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, /* seed */
469 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4,
470
471 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
472 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
473 0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59, /* a */
474 0xCC,0x9B,0xBF,0xF9,0xAE,0xE1,
475 0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C, /* b */
476 0x65,0x58,0xBB,0x6D,0x8A,0x5D,
477 0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB, /* x */
478 0x32,0xA7,0xCD,0xEB,0xC1,0x40,
479 0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06, /* y */
480 0xfe,0x80,0x5f,0xc3,0x4b,0x44,
481 0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00, /* order */
482 0x24,0x72,0x06,0x13,0xB5,0xA3 }
483 };
484
485static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
486 _EC_SECG_PRIME_160K1 = {
487 { NID_X9_62_prime_field,0,21,1 },
488 { /* no seed */
489 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
490 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
491 0x73,
492 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
493 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
494 0x00,
495 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
496 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
497 0x07,
498 0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4, /* x */
499 0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E,
500 0xBB,
501 0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b, /* y */
502 0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f,
503 0xee,
504 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
505 0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6,
506 0xB3 }
507 };
508
509static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
510 _EC_SECG_PRIME_160R1 = {
511 { NID_X9_62_prime_field,20,21,1 },
512 { 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, /* seed */
513 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45,
514
515 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
516 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
517 0xFF,
518 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
519 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
520 0xFC,
521 0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65, /* b */
522 0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA,
523 0x45,
524 0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46, /* x */
525 0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC,
526 0x82,
527 0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59, /* y */
528 0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb,
529 0x32,
530 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
531 0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22,
532 0x57 }
533 };
534
535static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
536 _EC_SECG_PRIME_160R2 = {
537 { NID_X9_62_prime_field,20,21,1 },
538 { 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, /* seed */
539 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51,
540
541 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
542 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
543 0x73,
544 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
545 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
546 0x70,
547 0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB, /* b */
548 0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88,
549 0xBA,
550 0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F, /* x */
551 0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE,
552 0x6D,
553 0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0, /* y */
554 0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f,
555 0x2e,
556 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
557 0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1,
558 0x6B }
559 };
560
561static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
562 _EC_SECG_PRIME_192K1 = {
563 { NID_X9_62_prime_field,0,24,1 },
564 { /* no seed */
565 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
566 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
567 0xFF,0xFF,0xEE,0x37,
568 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
570 0x00,0x00,0x00,0x00,
571 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
573 0x00,0x00,0x00,0x03,
574 0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0, /* x */
575 0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1,
576 0xEA,0xE0,0x6C,0x7D,
577 0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41, /* y */
578 0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88,
579 0xd9,0x5e,0x2f,0x9d,
580 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
581 0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A,
582 0x74,0xDE,0xFD,0x8D }
583 };
584
585static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; }
586 _EC_SECG_PRIME_224K1 = {
587 { NID_X9_62_prime_field,0,29,1 },
588 { /* no seed */
589 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
590 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
591 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D,
592 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
593 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
594 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
595 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
596 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
597 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
598 0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30, /* x */
599 0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75,
600 0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C,
601 0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82, /* y */
602 0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd,
603 0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5,
604 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
605 0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61,
606 0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 }
607 };
608
609static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; }
610 _EC_SECG_PRIME_256K1 = {
611 { NID_X9_62_prime_field,0,32,1 },
612 { /* no seed */
613 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
614 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
615 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,
616 0xFC,0x2F,
617 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
618 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
619 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
620 0x00,0x00,
621 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
622 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
623 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
624 0x00,0x07,
625 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0, /* x */
626 0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB,
627 0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
628 0x17,0x98,
629 0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4, /* y */
630 0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,
631 0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,
632 0xd4,0xb8,
633 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
634 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,
635 0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36,
636 0x41,0x41 }
637 };
638
639/* some wap/wtls curves */
640static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
641 _EC_WTLS_8 = {
642 { NID_X9_62_prime_field,0,15,1 },
643 { /* no seed */
644 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
645 0xFF,0xFF,0xFF,0xFD,0xE7,
646 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
647 0x00,0x00,0x00,0x00,0x00,
648 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
649 0x00,0x00,0x00,0x00,0x03,
650 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
651 0x00,0x00,0x00,0x00,0x01,
652 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
653 0x00,0x00,0x00,0x00,0x02,
654 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA, /* order */
655 0x55,0x1A,0xD8,0x37,0xE9 }
656 };
657
658static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
659 _EC_WTLS_9 = {
660 { NID_X9_62_prime_field,0,21,1 },
661 { /* no seed */
662 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
663 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80,
664 0x8F,
665 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
666 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
667 0x00,
668 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
669 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
670 0x03,
671 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
672 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
673 0x01,
674 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
675 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
676 0x02,
677 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
678 0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF,
679 0x33 }
680 };
681
682static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; }
683 _EC_WTLS_12 = {
684 { NID_X9_62_prime_field,0,28,1 },
685 { /* no seed */
686 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
687 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
688 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
689 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
690 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
691 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
692 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
693 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
694 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
695 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
696 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
697 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
698 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
699 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
700 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
701 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
702 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
703 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
704 };
705
706/* characteristic two curves */
707static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
708 _EC_SECG_CHAR2_113R1 = {
709 { NID_X9_62_characteristic_two_field,20,15,2 },
710 { 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, /* seed */
711 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9,
712
713 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
714 0x00,0x00,0x00,0x02,0x01,
715 0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64, /* a */
716 0x9C,0xE8,0x58,0x20,0xF7,
717 0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18, /* b */
718 0x8B,0xE0,0xE9,0xC7,0x23,
719 0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07, /* x */
720 0xD7,0x35,0x62,0xC1,0x0F,
721 0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1, /* y */
722 0x31,0x5E,0xD3,0x18,0x86,
723 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC, /* order */
724 0xEC,0x8A,0x39,0xE5,0x6F }
725 };
726
727static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
728 _EC_SECG_CHAR2_113R2 = {
729 { NID_X9_62_characteristic_two_field,20,15,2 },
730 { 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, /* seed */
731 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D,
732
733 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
734 0x00,0x00,0x00,0x02,0x01,
735 0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6, /* a */
736 0xDF,0xC0,0xAA,0x55,0xC7,
737 0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF, /* b */
738 0x36,0xE0,0x59,0x18,0x4F,
739 0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F, /* x */
740 0xCD,0xB8,0x16,0x47,0x97,
741 0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06, /* y */
742 0xE6,0x95,0xBA,0xBA,0x1D,
743 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78, /* order */
744 0x9B,0x24,0x96,0xAF,0x93 }
745 };
746
747static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
748 _EC_SECG_CHAR2_131R1 = {
749 { NID_X9_62_characteristic_two_field,20,17,2 },
750 { 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, /* seed */
751 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2,
752
753 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
754 0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
755 0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41, /* a */
756 0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8,
757 0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6, /* b */
758 0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41,
759 0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F, /* x */
760 0x9C,0x18,0x13,0x43,0x63,0x83,0x99,
761 0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8, /* y */
762 0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50,
763 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31, /* order */
764 0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D }
765 };
766
767static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
768 _EC_SECG_CHAR2_131R2 = {
769 { NID_X9_62_characteristic_two_field,20,17,2 },
770 { 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, /* seed */
771 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3,
772
773 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
774 0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
775 0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41, /* a */
776 0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2,
777 0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73, /* b */
778 0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92,
779 0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65, /* x */
780 0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8,
781 0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D, /* y */
782 0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F,
783 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69, /* order */
784 0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F }
785 };
786
787static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
788 _EC_NIST_CHAR2_163K = {
789 { NID_X9_62_characteristic_two_field,0,21,2 },
790 { /* no seed */
791 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
792 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
793 0xC9,
794 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
795 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
796 0x01,
797 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
798 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
799 0x01,
800 0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA, /* x */
801 0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE,
802 0xE8,
803 0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32, /* y */
804 0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3,
805 0xD9,
806 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
807 0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5,
808 0xEF }
809 };
810
811static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
812 _EC_SECG_CHAR2_163R1 = {
813 { NID_X9_62_characteristic_two_field,0,21,2 },
814 { /* no seed */
815#if 0
816/* The algorithm used to derive the curve parameters from
817 * the seed used here is slightly different than the
818 * algorithm described in X9.62 . */
819 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
820 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C,
821#endif
822 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
823 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
824 0xC9,
825 0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54, /* a */
826 0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A,
827 0xE2,
828 0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94, /* b */
829 0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF,
830 0xD9,
831 0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89, /* x */
832 0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6,
833 0x54,
834 0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D, /* y */
835 0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8,
836 0x83,
837 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
838 0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27,
839 0x9B }
840 };
841
842static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
843 _EC_NIST_CHAR2_163B = {
844 { NID_X9_62_characteristic_two_field,0,21,2 },
845 { /* no seed */
846#if 0
847/* The seed here was used to created the curve parameters in normal
848 * basis representation (and not the polynomial representation used here) */
849 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
850 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68,
851#endif
852 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
853 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
854 0xC9,
855 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
856 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
857 0x01,
858 0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14, /* b */
859 0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05,
860 0xFD,
861 0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0, /* x */
862 0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E,
863 0x36,
864 0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2, /* y */
865 0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24,
866 0xF1,
867 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
868 0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C,
869 0x33 }
870 };
871
872static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
873 _EC_SECG_CHAR2_193R1 = {
874 { NID_X9_62_characteristic_two_field,20,25,2 },
875 { 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, /* seed */
876 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30,
877
878 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
879 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
880 0x00,0x00,0x00,0x80,0x01,
881 0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69, /* a */
882 0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8,
883 0xA9,0x11,0xDF,0x7B,0x01,
884 0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC, /* b */
885 0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5,
886 0xD8,0x31,0x47,0x88,0x14,
887 0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD, /* x */
888 0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53,
889 0x72,0xD8,0xC0,0xC5,0xE1,
890 0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3, /* y */
891 0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B,
892 0x6A,0xF7,0xCE,0x1B,0x05,
893 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
894 0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A,
895 0xCC,0x92,0x0E,0xBA,0x49 }
896 };
897
898static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
899 _EC_SECG_CHAR2_193R2 = {
900 { NID_X9_62_characteristic_two_field,20,25,2 },
901 { 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, /* seed */
902 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11,
903
904 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
905 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
906 0x00,0x00,0x00,0x80,0x01,
907 0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6, /* a */
908 0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69,
909 0x97,0x77,0x02,0x70,0x9B,
910 0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37, /* b */
911 0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7,
912 0xF6,0x1D,0x43,0x16,0xAE,
913 0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03, /* x */
914 0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35,
915 0x0A,0xAE,0x61,0x7E,0x8F,
916 0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29, /* y */
917 0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27,
918 0x22,0x4C,0xDE,0xCF,0x6C,
919 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
920 0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13,
921 0xCC,0xD4,0xEE,0x99,0xD5 }
922 };
923
924static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
925 _EC_NIST_CHAR2_233K = {
926 { NID_X9_62_characteristic_two_field,0,30,4 },
927 { /* no seed */
928 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
929 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
930 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
931
932 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
933 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
934 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
935
936 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
937 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
938 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
939
940 0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1, /* x */
941 0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2,
942 0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26,
943
944 0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F, /* y */
945 0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A,
946 0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3,
947
948 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
949 0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15,
950 0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF }
951 };
952
953static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
954 _EC_NIST_CHAR2_233B = {
955 { NID_X9_62_characteristic_two_field,20,30,2 },
956 { 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, /* seed */
957 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3,
958
959 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
960 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
961 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
962
963 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
964 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
965 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
966
967 0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C, /* b */
968 0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9,
969 0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD,
970
971 0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21, /* x */
972 0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F,
973 0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B,
974
975 0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78, /* y */
976 0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67,
977 0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52,
978
979 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
980 0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F,
981 0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 }
982 };
983
984static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
985 _EC_SECG_CHAR2_239K1 = {
986 { NID_X9_62_characteristic_two_field,0,30,4 },
987 { /* no seed */
988 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
989 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
990 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
991
992 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
993 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
994 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
995
996 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
997 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
998 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
999
1000 0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09, /* x */
1001 0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C,
1002 0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC,
1003
1004 0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01, /* y */
1005 0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75,
1006 0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA,
1007
1008 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1009 0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C,
1010 0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 }
1011 };
1012
1013static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; }
1014 _EC_NIST_CHAR2_283K = {
1015 { NID_X9_62_characteristic_two_field,0,36,4 },
1016 { /* no seed */
1017 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1018 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1019 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1020 0x00,0x00,0x00,0x00,0x10,0xA1,
1021 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1022 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1023 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1024 0x00,0x00,0x00,0x00,0x00,0x00,
1025 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1026 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1027 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1028 0x00,0x00,0x00,0x00,0x00,0x01,
1029 0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A, /* x */
1030 0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F,
1031 0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2,
1032 0xAC,0x24,0x58,0x49,0x28,0x36,
1033 0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90, /* y */
1034 0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0,
1035 0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34,
1036 0x11,0x61,0x77,0xDD,0x22,0x59,
1037 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1038 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE,
1039 0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45,
1040 0x1E,0x06,0x1E,0x16,0x3C,0x61 }
1041 };
1042
1043static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; }
1044 _EC_NIST_CHAR2_283B = {
1045 { NID_X9_62_characteristic_two_field,20,36,2 },
1046 { 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, /* no seed */
1047 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE,
1048
1049 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1050 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1051 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1052 0x00,0x00,0x00,0x00,0x10,0xA1,
1053 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1054 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1055 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1056 0x00,0x00,0x00,0x00,0x00,0x01,
1057 0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4, /* b */
1058 0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76,
1059 0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26,
1060 0x3E,0x31,0x3B,0x79,0xA2,0xF5,
1061 0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93, /* x */
1062 0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8,
1063 0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD,
1064 0xBE,0xCD,0x86,0xB1,0x20,0x53,
1065 0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F, /* y */
1066 0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02,
1067 0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0,
1068 0xDF,0x45,0xBE,0x81,0x12,0xF4,
1069 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1070 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90,
1071 0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04,
1072 0x2A,0x7C,0xEF,0xAD,0xB3,0x07 }
1073 };
1074
1075static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; }
1076 _EC_NIST_CHAR2_409K = {
1077 { NID_X9_62_characteristic_two_field,0,52,4 },
1078 { /* no seed */
1079 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1080 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1081 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1082 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1083 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1084 0x00,0x01,
1085 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1086 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1087 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1088 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1089 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1090 0x00,0x00,
1091 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1092 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1093 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1094 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1095 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1096 0x00,0x01,
1097 0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A, /* x */
1098 0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87,
1099 0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6,
1100 0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62,
1101 0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02,
1102 0x37,0x46,
1103 0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA, /* y */
1104 0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F,
1105 0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA,
1106 0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15,
1107 0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0,
1108 0x28,0x6B,
1109 0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1110 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1111 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2,
1112 0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3,
1113 0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E,
1114 0x5F,0xCF }
1115 };
1116
1117static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; }
1118 _EC_NIST_CHAR2_409B = {
1119 { NID_X9_62_characteristic_two_field,20,52,2 },
1120 { 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, /* seed */
1121 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B,
1122
1123 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1124 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1125 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1127 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1128 0x00,0x01,
1129 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1130 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1131 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1132 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1133 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1134 0x00,0x01,
1135 0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B, /* b */
1136 0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E,
1137 0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC,
1138 0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C,
1139 0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13,
1140 0x54,0x5F,
1141 0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B, /* x */
1142 0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A,
1143 0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5,
1144 0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51,
1145 0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79,
1146 0x96,0xA7,
1147 0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF, /* y */
1148 0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5,
1149 0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88,
1150 0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40,
1151 0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73,
1152 0xC7,0x06,
1153 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1154 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1155 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6,
1156 0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C,
1157 0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2,
1158 0x11,0x73 }
1159 };
1160
1161static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; }
1162 _EC_NIST_CHAR2_571K = {
1163 { NID_X9_62_characteristic_two_field,0,72,4 },
1164 { /* no seed */
1165 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1166 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1167 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1168 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1169 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1170 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1171 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1172 0x04,0x25,
1173 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1174 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1175 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1176 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1177 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1178 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1179 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1180 0x00,0x00,
1181 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1182 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1183 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1186 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1187 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1188 0x00,0x01,
1189 0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18, /* x */
1190 0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97,
1191 0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84,
1192 0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6,
1193 0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1,
1194 0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17,
1195 0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C,
1196 0x89,0x72,
1197 0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A, /* y */
1198 0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC,
1199 0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D,
1200 0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7,
1201 0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20,
1202 0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8,
1203 0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1,
1204 0xC7,0xA3,
1205 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1206 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1207 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1208 0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1,
1209 0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F,
1210 0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38,
1211 0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C,
1212 0x10,0x01 }
1213 };
1214
1215static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; }
1216 _EC_NIST_CHAR2_571B = {
1217 { NID_X9_62_characteristic_two_field,20,72,2 },
1218 { 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, /* seed */
1219 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10,
1220
1221 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1222 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1223 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1224 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1225 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1226 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1227 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1228 0x04,0x25,
1229 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1230 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1231 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1232 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1233 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1234 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1235 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1236 0x00,0x01,
1237 0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29, /* b */
1238 0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF,
1239 0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A,
1240 0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33,
1241 0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD,
1242 0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7,
1243 0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55,
1244 0x72,0x7A,
1245 0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16, /* x */
1246 0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2,
1247 0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B,
1248 0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93,
1249 0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE,
1250 0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4,
1251 0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC,
1252 0x2D,0x19,
1253 0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC, /* y */
1254 0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6,
1255 0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21,
1256 0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57,
1257 0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53,
1258 0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51,
1259 0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A,
1260 0xC1,0x5B,
1261 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1262 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1263 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1264 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18,
1265 0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23,
1266 0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D,
1267 0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8,
1268 0x4E,0x47 }
1269 };
1270
1271static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
1272 _EC_X9_62_CHAR2_163V1 = {
1273 { NID_X9_62_characteristic_two_field,20,21,2 },
1274 { 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
1275 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54, /* seed */
1276
1277 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1278 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1279 0x07,
1280 0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0, /* a */
1281 0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52,
1282 0x42,
1283 0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF, /* b */
1284 0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4,
1285 0xD9,
1286 0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32, /* x */
1287 0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03,
1288 0xCB,
1289 0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D, /* y */
1290 0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA,
1291 0x9F,
1292 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1293 0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF,
1294 0xC1 }
1295 };
1296
1297static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
1298 _EC_X9_62_CHAR2_163V2 = {
1299 { NID_X9_62_characteristic_two_field,20,21,2 },
1300 { 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, /* seed */
1301 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD,
1302
1303 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1304 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1305 0x07,
1306 0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9, /* a */
1307 0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0,
1308 0x72,
1309 0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40, /* b */
1310 0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF,
1311 0x20,
1312 0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96, /* x */
1313 0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C,
1314 0xC5,
1315 0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25, /* y */
1316 0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F,
1317 0xC5,
1318 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1319 0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10,
1320 0xA7 }
1321 };
1322
1323static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
1324 _EC_X9_62_CHAR2_163V3 = {
1325 { NID_X9_62_characteristic_two_field,20,21,2 },
1326 { 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, /* seed */
1327 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8,
1328
1329 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1330 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1331 0x07,
1332 0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0, /* a */
1333 0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5,
1334 0x0E,
1335 0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD, /* b */
1336 0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25,
1337 0x2B,
1338 0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF, /* x */
1339 0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD,
1340 0xCB,
1341 0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48, /* y */
1342 0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05,
1343 0xD0,
1344 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1345 0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13,
1346 0x09 }
1347 };
1348
1349static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; }
1350 _EC_X9_62_CHAR2_176V1 = {
1351 { NID_X9_62_characteristic_two_field,0,23,0xFF6E },
1352 { /* no seed */
1353 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1354 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
1355 0x00,0x00,0x07,
1356 0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D, /* a */
1357 0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8,
1358 0xE9,0xC9,0x0B,
1359 0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E, /* b */
1360 0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A,
1361 0xE0,0xFF,0xF2,
1362 0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9, /* x */
1363 0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0,
1364 0x4A,0x57,0x98,
1365 0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA, /* y */
1366 0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1,
1367 0x6A,0x56,0x2C,
1368 0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4, /* order */
1369 0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06,
1370 0xFE,0x26,0xAD }
1371 };
1372
1373static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
1374 _EC_X9_62_CHAR2_191V1 = {
1375 { NID_X9_62_characteristic_two_field,20,24,2 },
1376 { 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, /* seed */
1377 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84,
1378
1379 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1380 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1381 0x00,0x00,0x02,0x01,
1382 0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68, /* a */
1383 0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E,
1384 0xF7,0x52,0x62,0x67,
1385 0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0, /* b */
1386 0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE,
1387 0x0A,0xA1,0x85,0xEC,
1388 0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2, /* x */
1389 0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8,
1390 0x4A,0xE1,0xAA,0x0D,
1391 0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29, /* y */
1392 0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E,
1393 0xF9,0x80,0x18,0xFB,
1394 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1395 0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8,
1396 0x93,0xBB,0xB9,0xA5 }
1397 };
1398
1399static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
1400 _EC_X9_62_CHAR2_191V2 = {
1401 { NID_X9_62_characteristic_two_field,20,24,4 },
1402 { 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, /* seed */
1403 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15,
1404
1405 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1406 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1407 0x00,0x00,0x02,0x01,
1408 0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66, /* a */
1409 0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89,
1410 0xFF,0x01,0xE7,0x18,
1411 0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24, /* b */
1412 0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3,
1413 0x62,0xC4,0x6A,0x01,
1414 0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87, /* x */
1415 0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2,
1416 0xC9,0xE3,0xBF,0x10,
1417 0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0, /* y */
1418 0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC,
1419 0x43,0x7D,0x66,0x8A,
1420 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1421 0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24,
1422 0xE0,0x6B,0x81,0x73 }
1423 };
1424
1425static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
1426 _EC_X9_62_CHAR2_191V3 = {
1427 { NID_X9_62_characteristic_two_field,20,24,6 },
1428 { 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, /* seed */
1429 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F,
1430
1431 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1432 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1433 0x00,0x00,0x02,0x01,
1434 0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10, /* a */
1435 0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7,
1436 0xE7,0xE7,0x7F,0xCB,
1437 0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF, /* b */
1438 0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32,
1439 0xAD,0x3F,0x15,0xE8,
1440 0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE, /* x */
1441 0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E,
1442 0x38,0xA9,0x26,0xDD,
1443 0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59, /* y */
1444 0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7,
1445 0x12,0x7B,0x06,0xBE,
1446 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */
1447 0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6,
1448 0x28,0x8A,0x3E,0xA3 }
1449 };
1450
1451static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; }
1452 _EC_X9_62_CHAR2_208W1 = {
1453 { NID_X9_62_characteristic_two_field,0,27,0xFE48 },
1454 { /* no seed */
1455 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1456 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
1457 0x00,0x00,0x00,0x00,0x00,0x00,0x07,
1458 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1459 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1460 0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1461 0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E, /* b */
1462 0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA,
1463 0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E,
1464 0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95, /* x */
1465 0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27,
1466 0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A,
1467 0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3, /* y */
1468 0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE,
1469 0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3,
1470 0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5, /* order */
1471 0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88,
1472 0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D }
1473 };
1474
1475static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
1476 _EC_X9_62_CHAR2_239V1 = {
1477 { NID_X9_62_characteristic_two_field,20,30,4 },
1478 { 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
1479 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D,
1480
1481 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1482 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1483 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
1484
1485 0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A, /* a */
1486 0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E,
1487 0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76,
1488
1489 0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12, /* b */
1490 0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C,
1491 0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16,
1492
1493 0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96, /* x */
1494 0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56,
1495 0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D,
1496
1497 0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1, /* y */
1498 0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E,
1499 0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05,
1500
1501 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1502 0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1,
1503 0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 }
1504 };
1505
1506static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
1507 _EC_X9_62_CHAR2_239V2 = {
1508 { NID_X9_62_characteristic_two_field,20,30,6 },
1509 { 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, /* seed */
1510 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D,
1511
1512 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1513 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1514 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
1515
1516 0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23, /* a */
1517 0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF,
1518 0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F,
1519
1520 0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82, /* b */
1521 0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52,
1522 0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B,
1523
1524 0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47, /* x */
1525 0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7,
1526 0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05,
1527
1528 0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B, /* y */
1529 0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56,
1530 0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33,
1531
1532 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */
1533 0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25,
1534 0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D }
1535 };
1536
1537static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
1538 _EC_X9_62_CHAR2_239V3 = {
1539 { NID_X9_62_characteristic_two_field,20,30,0xA },
1540 { 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
1541 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41,
1542
1543 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1544 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1545 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
1546
1547 0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66, /* a */
1548 0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66,
1549 0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F,
1550
1551 0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99, /* b */
1552 0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5,
1553 0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40,
1554
1555 0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91, /* x */
1556 0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42,
1557 0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92,
1558
1559 0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00, /* y */
1560 0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08,
1561 0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61,
1562
1563 0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, /* order */
1564 0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9,
1565 0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF }
1566 };
1567
1568static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; }
1569 _EC_X9_62_CHAR2_272W1 = {
1570 { NID_X9_62_characteristic_two_field,0,35,0xFF06 },
1571 { /* no seed */
1572 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1574 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
1575 0x00,0x00,0x00,0x00,0x0B,
1576 0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2, /* a */
1577 0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71,
1578 0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA,
1579 0xCD,0xB5,0x86,0xFB,0x20,
1580 0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C, /* b */
1581 0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03,
1582 0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC,
1583 0x84,0x82,0xE5,0x40,0xF7,
1584 0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87, /* x */
1585 0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77,
1586 0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D,
1587 0x10,0xD1,0x71,0xDD,0x8D,
1588 0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B, /* y */
1589 0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8,
1590 0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02,
1591 0x00,0x5D,0xDE,0x9D,0x23,
1592 0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3, /* order */
1593 0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16,
1594 0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B,
1595 0x8F,0x1E,0x62,0x95,0x21 }
1596 };
1597
1598static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; }
1599 _EC_X9_62_CHAR2_304W1 = {
1600 { NID_X9_62_characteristic_two_field,0,39,0xFE2E },
1601 { /* no seed */
1602 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1603 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1604 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1605 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07,
1606 0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51, /* a */
1607 0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88,
1608 0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28,
1609 0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81,
1610 0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E, /* b */
1611 0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F,
1612 0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1,
1613 0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE,
1614 0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A, /* x */
1615 0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E,
1616 0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD,
1617 0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14,
1618 0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51, /* y */
1619 0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10,
1620 0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80,
1621 0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B,
1622 0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC, /* order */
1623 0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80,
1624 0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5,
1625 0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D }
1626 };
1627
1628static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; }
1629 _EC_X9_62_CHAR2_359V1 = {
1630 { NID_X9_62_characteristic_two_field,20,45,0x4C },
1631 { 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, /* seed */
1632 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6,
1633
1634 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1635 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1636 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1637 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
1638 0x00,0x00,0x00,0x00,0x01,
1639 0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35, /* a */
1640 0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67,
1641 0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67,
1642 0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16,
1643 0xA9,0x66,0x56,0xA5,0x57,
1644 0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F, /* b */
1645 0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D,
1646 0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34,
1647 0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7,
1648 0x06,0x80,0x23,0x19,0x88,
1649 0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0, /* x */
1650 0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A,
1651 0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF,
1652 0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A,
1653 0x22,0x39,0xB1,0xB0,0x97,
1654 0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E, /* y */
1655 0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48,
1656 0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC,
1657 0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30,
1658 0x5A,0x40,0x71,0x04,0xBD,
1659 0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1, /* order */
1660 0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF,
1661 0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89,
1662 0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74,
1663 0xF4,0x90,0x75,0x8D,0x3B }
1664 };
1665
1666static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; }
1667 _EC_X9_62_CHAR2_368W1 = {
1668 { NID_X9_62_characteristic_two_field,0,47,0xFF70 },
1669 { /* no seed */
1670 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1671 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1672 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1673 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
1674 0x00,0x00,0x00,0x00,0x00,0x00,0x07,
1675 0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2, /* a */
1676 0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0,
1677 0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9,
1678 0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C,
1679 0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D,
1680 0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C, /* b */
1681 0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B,
1682 0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5,
1683 0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4,
1684 0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A,
1685 0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3, /* x */
1686 0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82,
1687 0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B,
1688 0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21,
1689 0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F,
1690 0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8, /* y */
1691 0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C,
1692 0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE,
1693 0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A,
1694 0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10,
1695 0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72, /* order */
1696 0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53,
1697 0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A,
1698 0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1,
1699 0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 }
1700 };
1701
1702static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; }
1703 _EC_X9_62_CHAR2_431R1 = {
1704 { NID_X9_62_characteristic_two_field,0,54,0x2760 },
1705 { /* no seed */
1706 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1707 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1708 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1709 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
1710 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1711 0x00,0x00,0x00,0x01,
1712 0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C, /* a */
1713 0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23,
1714 0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9,
1715 0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F,
1716 0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D,
1717 0xE2,0x96,0xCD,0x8F,
1718 0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43, /* b */
1719 0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB,
1720 0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67,
1721 0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD,
1722 0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8,
1723 0x07,0xBF,0x26,0x18,
1724 0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61, /* x */
1725 0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4,
1726 0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2,
1727 0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65,
1728 0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB,
1729 0xD7,0x0C,0xE6,0xB7,
1730 0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2, /* y */
1731 0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93,
1732 0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B,
1733 0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C,
1734 0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A,
1735 0x59,0x8B,0x37,0x60,
1736 0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34, /* order */
1737 0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,
1738 0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23,
1739 0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6,
1740 0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49,
1741 0xC1,0xAD,0x4A,0x91 }
1742 };
1743
1744static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
1745 _EC_WTLS_1 = {
1746 { NID_X9_62_characteristic_two_field,0,15,2 },
1747 { /* no seed */
1748 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1749 0x00,0x00,0x00,0x02,0x01,
1750 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1751 0x00,0x00,0x00,0x00,0x01,
1752 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1753 0x00,0x00,0x00,0x00,0x01,
1754 0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5, /* x */
1755 0xC2,0x70,0x78,0x06,0x17,
1756 0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08, /* y */
1757 0x78,0x5C,0xEB,0xCC,0x15,
1758 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF, /* order */
1759 0x91,0xAF,0x6D,0xEA,0x73 }
1760 };
1761
1762/* IPSec curves */
1763/* NOTE: The of curves over a extension field of non prime degree
1764 * is not recommended (Weil-descent).
1765 * As the group order is not a prime this curve is not suitable
1766 * for ECDSA.
1767 */
1768static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; }
1769 _EC_IPSEC_155_ID3 = {
1770 { NID_X9_62_characteristic_two_field,0,20,3 },
1771 { /* no seed */
1772 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1773 0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1774
1775 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1776 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1777
1778 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1779 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f,
1780
1781 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
1782 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,
1783
1784 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
1785 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8,
1786
1787 0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, /* order */
1788 0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C }
1789 };
1790
1791/* NOTE: The of curves over a extension field of non prime degree
1792 * is not recommended (Weil-descent).
1793 * As the group order is not a prime this curve is not suitable
1794 * for ECDSA.
1795 */
1796static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
1797 _EC_IPSEC_185_ID4 = {
1798 { NID_X9_62_characteristic_two_field,0,24,2 },
1799 { /* no seed */
1800 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1801 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,
1802 0x00,0x00,0x00,0x01,
1803 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1804 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1805 0x00,0x00,0x00,0x00,
1806 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1807 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1808 0x00,0x00,0x1e,0xe9,
1809 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
1810 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1811 0x00,0x00,0x00,0x18,
1812 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
1813 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1814 0x00,0x00,0x00,0x0d,
1815 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1816 0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20,
1817 0xBA,0xFC,0xA7,0x5E }
1818 };
1819
1820typedef struct _ec_list_element_st {
1821 int nid;
1822 const EC_CURVE_DATA *data;
1823 const char *comment;
1824 } ec_list_element;
1825
1826static const ec_list_element curve_list[] = {
1827 /* prime field curves */
1828 /* secg curves */
1829 { NID_secp112r1, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
1830 { NID_secp112r2, &_EC_SECG_PRIME_112R2.h, "SECG curve over a 112 bit prime field"},
1831 { NID_secp128r1, &_EC_SECG_PRIME_128R1.h, "SECG curve over a 128 bit prime field"},
1832 { NID_secp128r2, &_EC_SECG_PRIME_128R2.h, "SECG curve over a 128 bit prime field"},
1833 { NID_secp160k1, &_EC_SECG_PRIME_160K1.h, "SECG curve over a 160 bit prime field"},
1834 { NID_secp160r1, &_EC_SECG_PRIME_160R1.h, "SECG curve over a 160 bit prime field"},
1835 { NID_secp160r2, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
1836 /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
1837 { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, "SECG curve over a 192 bit prime field"},
1838 { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, "SECG curve over a 224 bit prime field"},
1839 { NID_secp224r1, &_EC_NIST_PRIME_224.h, "NIST/SECG curve over a 224 bit prime field"},
1840 { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, "SECG curve over a 256 bit prime field"},
1841 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
1842 { NID_secp384r1, &_EC_NIST_PRIME_384.h, "NIST/SECG curve over a 384 bit prime field"},
1843 { NID_secp521r1, &_EC_NIST_PRIME_521.h, "NIST/SECG curve over a 521 bit prime field"},
1844 /* X9.62 curves */
1845 { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, "NIST/X9.62/SECG curve over a 192 bit prime field"},
1846 { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, "X9.62 curve over a 192 bit prime field"},
1847 { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, "X9.62 curve over a 192 bit prime field"},
1848 { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, "X9.62 curve over a 239 bit prime field"},
1849 { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, "X9.62 curve over a 239 bit prime field"},
1850 { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, "X9.62 curve over a 239 bit prime field"},
1851 { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, "X9.62/SECG curve over a 256 bit prime field"},
1852 /* characteristic two field curves */
1853 /* NIST/SECG curves */
1854 { NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
1855 { NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, "SECG curve over a 113 bit binary field"},
1856 { NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, "SECG/WTLS curve over a 131 bit binary field"},
1857 { NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, "SECG curve over a 131 bit binary field"},
1858 { NID_sect163k1, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field" },
1859 { NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, "SECG curve over a 163 bit binary field"},
1860 { NID_sect163r2, &_EC_NIST_CHAR2_163B.h, "NIST/SECG curve over a 163 bit binary field" },
1861 { NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, "SECG curve over a 193 bit binary field"},
1862 { NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, "SECG curve over a 193 bit binary field"},
1863 { NID_sect233k1, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1864 { NID_sect233r1, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1865 { NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, "SECG curve over a 239 bit binary field"},
1866 { NID_sect283k1, &_EC_NIST_CHAR2_283K.h, "NIST/SECG curve over a 283 bit binary field" },
1867 { NID_sect283r1, &_EC_NIST_CHAR2_283B.h, "NIST/SECG curve over a 283 bit binary field" },
1868 { NID_sect409k1, &_EC_NIST_CHAR2_409K.h, "NIST/SECG curve over a 409 bit binary field" },
1869 { NID_sect409r1, &_EC_NIST_CHAR2_409B.h, "NIST/SECG curve over a 409 bit binary field" },
1870 { NID_sect571k1, &_EC_NIST_CHAR2_571K.h, "NIST/SECG curve over a 571 bit binary field" },
1871 { NID_sect571r1, &_EC_NIST_CHAR2_571B.h, "NIST/SECG curve over a 571 bit binary field" },
1872 /* X9.62 curves */
1873 { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
1874 { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, "X9.62 curve over a 163 bit binary field"},
1875 { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, "X9.62 curve over a 163 bit binary field"},
1876 { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, "X9.62 curve over a 176 bit binary field"},
1877 { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, "X9.62 curve over a 191 bit binary field"},
1878 { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, "X9.62 curve over a 191 bit binary field"},
1879 { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, "X9.62 curve over a 191 bit binary field"},
1880 { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, "X9.62 curve over a 208 bit binary field"},
1881 { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, "X9.62 curve over a 239 bit binary field"},
1882 { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, "X9.62 curve over a 239 bit binary field"},
1883 { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, "X9.62 curve over a 239 bit binary field"},
1884 { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, "X9.62 curve over a 272 bit binary field"},
1885 { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, "X9.62 curve over a 304 bit binary field"},
1886 { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, "X9.62 curve over a 359 bit binary field"},
1887 { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, "X9.62 curve over a 368 bit binary field"},
1888 { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, "X9.62 curve over a 431 bit binary field"},
1889 /* the WAP/WTLS curves
1890 * [unlike SECG, spec has its own OIDs for curves from X9.62] */
1891 { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, "WTLS curve over a 113 bit binary field"},
1892 { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field"},
1893 { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
1894 { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
1895 { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
1896 { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
1897 { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, "WTLS curve over a 112 bit prime field"},
1898 { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, "WTLS curve over a 160 bit prime field" },
1899 { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
1900 { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
1901 { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, "WTLS curvs over a 224 bit prime field"},
1902 /* IPSec curves */
1903 { NID_ipsec3, &_EC_IPSEC_155_ID3.h, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
1904 { NID_ipsec4, &_EC_IPSEC_185_ID4.h, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
1905};
1906
1907#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
1908
1909static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1910 {
1911 EC_GROUP *group=NULL;
1912 EC_POINT *P=NULL;
1913 BN_CTX *ctx=NULL;
1914 BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
1915 int ok=0;
1916 int seed_len,param_len;
1917 const unsigned char *params;
1918
1919 if ((ctx = BN_CTX_new()) == NULL)
1920 {
1921 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
1922 goto err;
1923 }
1924
1925 seed_len = data->seed_len;
1926 param_len = data->param_len;
1927 params = (const unsigned char *)(data+1); /* skip header */
1928 params += seed_len; /* skip seed */
1929
1930 if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
1931 || !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
1932 || !(b = BN_bin2bn(params+2*param_len, param_len, NULL)))
1933 {
1934 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1935 goto err;
1936 }
1937
1938 if (data->field_type == NID_X9_62_prime_field)
1939 {
1940 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
1941 {
1942 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1943 goto err;
1944 }
1945 }
1946 else /* field_type == NID_X9_62_characteristic_two_field */
1947 {
1948 if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
1949 {
1950 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1951 goto err;
1952 }
1953 }
1954
1955 if ((P = EC_POINT_new(group)) == NULL)
1956 {
1957 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1958 goto err;
1959 }
1960
1961 if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
1962 || !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
1963 {
1964 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1965 goto err;
1966 }
1967 if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
1968 {
1969 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1970 goto err;
1971 }
1972 if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
1973 || !BN_set_word(x, (BN_ULONG)data->cofactor))
1974 {
1975 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1976 goto err;
1977 }
1978 if (!EC_GROUP_set_generator(group, P, order, x))
1979 {
1980 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1981 goto err;
1982 }
1983 if (seed_len)
1984 {
1985 if (!EC_GROUP_set_seed(group, params-seed_len, seed_len))
1986 {
1987 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1988 goto err;
1989 }
1990 }
1991 ok=1;
1992err:
1993 if (!ok)
1994 {
1995 EC_GROUP_free(group);
1996 group = NULL;
1997 }
1998 if (P)
1999 EC_POINT_free(P);
2000 if (ctx)
2001 BN_CTX_free(ctx);
2002 if (p)
2003 BN_free(p);
2004 if (a)
2005 BN_free(a);
2006 if (b)
2007 BN_free(b);
2008 if (order)
2009 BN_free(order);
2010 if (x)
2011 BN_free(x);
2012 if (y)
2013 BN_free(y);
2014 return group;
2015 }
2016
2017EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
2018 {
2019 size_t i;
2020 EC_GROUP *ret = NULL;
2021
2022 if (nid <= 0)
2023 return NULL;
2024
2025 for (i=0; i<curve_list_length; i++)
2026 if (curve_list[i].nid == nid)
2027 {
2028 ret = ec_group_new_from_data(curve_list[i].data);
2029 break;
2030 }
2031
2032 if (ret == NULL)
2033 {
2034 ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
2035 return NULL;
2036 }
2037
2038 EC_GROUP_set_curve_name(ret, nid);
2039
2040 return ret;
2041 }
2042
2043size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
2044 {
2045 size_t i, min;
2046
2047 if (r == NULL || nitems == 0)
2048 return curve_list_length;
2049
2050 min = nitems < curve_list_length ? nitems : curve_list_length;
2051
2052 for (i = 0; i < min; i++)
2053 {
2054 r[i].nid = curve_list[i].nid;
2055 r[i].comment = curve_list[i].comment;
2056 }
2057
2058 return curve_list_length;
2059 }
diff --git a/src/lib/libcrypto/ec/ec_cvt.c b/src/lib/libcrypto/ec/ec_cvt.c
deleted file mode 100644
index d45640bab9..0000000000
--- a/src/lib/libcrypto/ec/ec_cvt.c
+++ /dev/null
@@ -1,144 +0,0 @@
1/* crypto/ec/ec_cvt.c */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2002 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 <openssl/err.h>
73#include "ec_lcl.h"
74
75
76EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
77 {
78 const EC_METHOD *meth;
79 EC_GROUP *ret;
80
81 meth = EC_GFp_nist_method();
82
83 ret = EC_GROUP_new(meth);
84 if (ret == NULL)
85 return NULL;
86
87 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
88 {
89 unsigned long err;
90
91 err = ERR_peek_last_error();
92
93 if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
94 ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
95 (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME))))
96 {
97 /* real error */
98
99 EC_GROUP_clear_free(ret);
100 return NULL;
101 }
102
103
104 /* not an actual error, we just cannot use EC_GFp_nist_method */
105
106 ERR_clear_error();
107
108 EC_GROUP_clear_free(ret);
109 meth = EC_GFp_mont_method();
110
111 ret = EC_GROUP_new(meth);
112 if (ret == NULL)
113 return NULL;
114
115 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
116 {
117 EC_GROUP_clear_free(ret);
118 return NULL;
119 }
120 }
121
122 return ret;
123 }
124
125
126EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
127 {
128 const EC_METHOD *meth;
129 EC_GROUP *ret;
130
131 meth = EC_GF2m_simple_method();
132
133 ret = EC_GROUP_new(meth);
134 if (ret == NULL)
135 return NULL;
136
137 if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx))
138 {
139 EC_GROUP_clear_free(ret);
140 return NULL;
141 }
142
143 return ret;
144 }
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
deleted file mode 100644
index 84b4833371..0000000000
--- a/src/lib/libcrypto/ec/ec_err.c
+++ /dev/null
@@ -1,258 +0,0 @@
1/* crypto/ec/ec_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2007 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/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include <openssl/ec.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
70
71static ERR_STRING_DATA EC_str_functs[]=
72 {
73{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
74{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
75{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
76{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
77{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"},
78{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"},
79{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"},
80{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"},
81{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"},
82{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"},
83{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"},
84{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"},
85{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
86{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
87{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
88{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
89{ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"},
90{ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"},
91{ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"},
92{ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"},
93{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"},
94{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"},
95{ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"},
96{ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"},
97{ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"},
98{ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"},
99{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"},
100{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
101{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GF2m_simple_group_check_discriminant"},
102{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), "ec_GF2m_simple_group_set_curve"},
103{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
104{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
105{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GF2m_simple_point_get_affine_coordinates"},
106{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GF2m_simple_point_set_affine_coordinates"},
107{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GF2m_simple_set_compressed_coordinates"},
108{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
109{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
110{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
111{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), "ec_GFp_mont_field_set_to_one"},
112{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
113{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), "ec_GFp_mont_group_set_curve"},
114{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), "EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
115{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
116{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
117{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
118{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GFp_simple_group_check_discriminant"},
119{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), "ec_GFp_simple_group_set_curve"},
120{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
121{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
122{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
123{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
124{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
125{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), "ec_GFp_simple_points_make_affine"},
126{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GFp_simple_point_get_affine_coordinates"},
127{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
128{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GFp_simple_point_set_affine_coordinates"},
129{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
130{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GFp_simple_set_compressed_coordinates"},
131{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
132{ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
133{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), "EC_GROUP_check_discriminant"},
134{ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
135{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"},
136{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"},
137{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
138{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
139{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
140{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
141{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), "EC_GROUP_get_pentanomial_basis"},
142{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"},
143{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
144{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
145{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
146{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"},
147{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
148{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
149{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"},
150{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
151{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
152{ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
153{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
154{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
155{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
156{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
157{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
158{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
159{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
160{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
161{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
162{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), "EC_POINT_get_affine_coordinates_GF2m"},
163{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), "EC_POINT_get_affine_coordinates_GFp"},
164{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"},
165{ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
166{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
167{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
168{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
169{ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"},
170{ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
171{ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
172{ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
173{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), "EC_POINT_set_affine_coordinates_GF2m"},
174{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), "EC_POINT_set_affine_coordinates_GFp"},
175{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), "EC_POINT_set_compressed_coordinates_GF2m"},
176{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), "EC_POINT_set_compressed_coordinates_GFp"},
177{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_set_Jprojective_coordinates_GFp"},
178{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
179{ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"},
180{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"},
181{ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
182{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
183{ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
184{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
185{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
186{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
187{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
188{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
189{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
190{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"},
191{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"},
192{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
193{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
194{ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
195{0,NULL}
196 };
197
198static ERR_STRING_DATA EC_str_reasons[]=
199 {
200{ERR_REASON(EC_R_ASN1_ERROR) ,"asn1 error"},
201{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"},
202{ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"},
203{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
204{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"},
205{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"},
206{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
207{ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"},
208{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
209{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
210{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"},
211{ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"},
212{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
213{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"},
214{ERR_REASON(EC_R_INVALID_CURVE) ,"invalid curve"},
215{ERR_REASON(EC_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
216{ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"},
217{ERR_REASON(EC_R_INVALID_FIELD) ,"invalid field"},
218{ERR_REASON(EC_R_INVALID_FORM) ,"invalid form"},
219{ERR_REASON(EC_R_INVALID_GROUP_ORDER) ,"invalid group order"},
220{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"},
221{ERR_REASON(EC_R_INVALID_PRIVATE_KEY) ,"invalid private key"},
222{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"},
223{ERR_REASON(EC_R_KEYS_NOT_SET) ,"keys not set"},
224{ERR_REASON(EC_R_MISSING_PARAMETERS) ,"missing parameters"},
225{ERR_REASON(EC_R_MISSING_PRIVATE_KEY) ,"missing private key"},
226{ERR_REASON(EC_R_NOT_A_NIST_PRIME) ,"not a NIST prime"},
227{ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME),"not a supported NIST prime"},
228{ERR_REASON(EC_R_NOT_IMPLEMENTED) ,"not implemented"},
229{ERR_REASON(EC_R_NOT_INITIALIZED) ,"not initialized"},
230{ERR_REASON(EC_R_NO_FIELD_MOD) ,"no field mod"},
231{ERR_REASON(EC_R_NO_PARAMETERS_SET) ,"no parameters set"},
232{ERR_REASON(EC_R_PASSED_NULL_PARAMETER) ,"passed null parameter"},
233{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"},
234{ERR_REASON(EC_R_POINT_AT_INFINITY) ,"point at infinity"},
235{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE) ,"point is not on curve"},
236{ERR_REASON(EC_R_SLOT_FULL) ,"slot full"},
237{ERR_REASON(EC_R_UNDEFINED_GENERATOR) ,"undefined generator"},
238{ERR_REASON(EC_R_UNDEFINED_ORDER) ,"undefined order"},
239{ERR_REASON(EC_R_UNKNOWN_GROUP) ,"unknown group"},
240{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"},
241{ERR_REASON(EC_R_UNSUPPORTED_FIELD) ,"unsupported field"},
242{ERR_REASON(EC_R_WRONG_ORDER) ,"wrong order"},
243{0,NULL}
244 };
245
246#endif
247
248void ERR_load_EC_strings(void)
249 {
250#ifndef OPENSSL_NO_ERR
251
252 if (ERR_func_error_string(EC_str_functs[0].error) == NULL)
253 {
254 ERR_load_strings(0,EC_str_functs);
255 ERR_load_strings(0,EC_str_reasons);
256 }
257#endif
258 }
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
deleted file mode 100644
index 522802c07a..0000000000
--- a/src/lib/libcrypto/ec/ec_key.c
+++ /dev/null
@@ -1,463 +0,0 @@
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 const 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 (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key))
309 {
310 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
311 goto err;
312 }
313
314 if ((ctx = BN_CTX_new()) == NULL)
315 goto err;
316 if ((point = EC_POINT_new(eckey->group)) == NULL)
317 goto err;
318
319 /* testing whether the pub_key is on the elliptic curve */
320 if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
321 {
322 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
323 goto err;
324 }
325 /* testing whether pub_key * order is the point at infinity */
326 order = &eckey->group->order;
327 if (BN_is_zero(order))
328 {
329 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
330 goto err;
331 }
332 if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, 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 (point != NULL)
370 EC_POINT_free(point);
371 return(ok);
372 }
373
374const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
375 {
376 return key->group;
377 }
378
379int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
380 {
381 if (key->group != NULL)
382 EC_GROUP_free(key->group);
383 key->group = EC_GROUP_dup(group);
384 return (key->group == NULL) ? 0 : 1;
385 }
386
387const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
388 {
389 return key->priv_key;
390 }
391
392int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
393 {
394 if (key->priv_key)
395 BN_clear_free(key->priv_key);
396 key->priv_key = BN_dup(priv_key);
397 return (key->priv_key == NULL) ? 0 : 1;
398 }
399
400const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
401 {
402 return key->pub_key;
403 }
404
405int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
406 {
407 if (key->pub_key != NULL)
408 EC_POINT_free(key->pub_key);
409 key->pub_key = EC_POINT_dup(pub_key, key->group);
410 return (key->pub_key == NULL) ? 0 : 1;
411 }
412
413unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
414 {
415 return key->enc_flag;
416 }
417
418void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
419 {
420 key->enc_flag = flags;
421 }
422
423point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
424 {
425 return key->conv_form;
426 }
427
428void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
429 {
430 key->conv_form = cform;
431 if (key->group != NULL)
432 EC_GROUP_set_point_conversion_form(key->group, cform);
433 }
434
435void *EC_KEY_get_key_method_data(EC_KEY *key,
436 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
437 {
438 return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
439 }
440
441void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
442 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
443 {
444 EC_EXTRA_DATA *ex_data;
445 CRYPTO_w_lock(CRYPTO_LOCK_EC);
446 ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
447 if (ex_data == NULL)
448 EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
449 CRYPTO_w_unlock(CRYPTO_LOCK_EC);
450 }
451
452void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
453 {
454 if (key->group != NULL)
455 EC_GROUP_set_asn1_flag(key->group, flag);
456 }
457
458int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
459 {
460 if (key->group == NULL)
461 return 0;
462 return EC_GROUP_precompute_mult(key->group, ctx);
463 }
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h
deleted file mode 100644
index 3e2c34b0bc..0000000000
--- a/src/lib/libcrypto/ec/ec_lcl.h
+++ /dev/null
@@ -1,393 +0,0 @@
1/* crypto/ec/ec_lcl.h */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-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 * 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
73#include <stdlib.h>
74
75#include <openssl/obj_mac.h>
76#include <openssl/ec.h>
77#include <openssl/bn.h>
78
79#if defined(__SUNPRO_C)
80# if __SUNPRO_C >= 0x520
81# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
82# endif
83#endif
84
85/* Structure details are not part of the exported interface,
86 * so all this may change in future versions. */
87
88struct ec_method_st {
89 /* used by EC_METHOD_get_field_type: */
90 int field_type; /* a NID */
91
92 /* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
93 int (*group_init)(EC_GROUP *);
94 void (*group_finish)(EC_GROUP *);
95 void (*group_clear_finish)(EC_GROUP *);
96 int (*group_copy)(EC_GROUP *, const EC_GROUP *);
97
98 /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
99 /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
100 int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
101 int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
102
103 /* used by EC_GROUP_get_degree: */
104 int (*group_get_degree)(const EC_GROUP *);
105
106 /* used by EC_GROUP_check: */
107 int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
108
109 /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
110 int (*point_init)(EC_POINT *);
111 void (*point_finish)(EC_POINT *);
112 void (*point_clear_finish)(EC_POINT *);
113 int (*point_copy)(EC_POINT *, const EC_POINT *);
114
115 /* used by EC_POINT_set_to_infinity,
116 * EC_POINT_set_Jprojective_coordinates_GFp,
117 * EC_POINT_get_Jprojective_coordinates_GFp,
118 * EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
119 * EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
120 * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
121 */
122 int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
123 int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
124 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
125 int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
126 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
127 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
128 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
129 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
130 BIGNUM *x, BIGNUM *y, BN_CTX *);
131 int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
132 const BIGNUM *x, int y_bit, BN_CTX *);
133
134 /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
135 size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
136 unsigned char *buf, size_t len, BN_CTX *);
137 int (*oct2point)(const EC_GROUP *, EC_POINT *,
138 const unsigned char *buf, size_t len, BN_CTX *);
139
140 /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
141 int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
142 int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
143 int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
144
145 /* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
146 int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
147 int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
148 int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
149
150 /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
151 int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
152 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
153
154 /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
155 * (default implementations are used if the 'mul' pointer is 0): */
156 int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
157 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
158 int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
159 int (*have_precompute_mult)(const EC_GROUP *group);
160
161
162 /* internal functions */
163
164 /* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that
165 * the same implementations of point operations can be used with different
166 * optimized implementations of expensive field operations: */
167 int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
168 int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
169 int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
170
171 int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
172 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
173 int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
174} /* EC_METHOD */;
175
176typedef struct ec_extra_data_st {
177 struct ec_extra_data_st *next;
178 void *data;
179 void *(*dup_func)(void *);
180 void (*free_func)(void *);
181 void (*clear_free_func)(void *);
182} EC_EXTRA_DATA; /* used in EC_GROUP */
183
184struct ec_group_st {
185 const EC_METHOD *meth;
186
187 EC_POINT *generator; /* optional */
188 BIGNUM order, cofactor;
189
190 int curve_name;/* optional NID for named curve */
191 int asn1_flag; /* flag to control the asn1 encoding */
192 point_conversion_form_t asn1_form;
193
194 unsigned char *seed; /* optional seed for parameters (appears in ASN1) */
195 size_t seed_len;
196
197 EC_EXTRA_DATA *extra_data; /* linked list */
198
199 /* The following members are handled by the method functions,
200 * even if they appear generic */
201
202 BIGNUM field; /* Field specification.
203 * For curves over GF(p), this is the modulus;
204 * for curves over GF(2^m), this is the
205 * irreducible polynomial defining the field.
206 */
207
208 int poly[6]; /* Field specification for curves over GF(2^m).
209 * The irreducible f(t) is then of the form:
210 * t^poly[0] + t^poly[1] + ... + t^poly[k]
211 * where m = poly[0] > poly[1] > ... > poly[k] = 0.
212 * The array is terminated with poly[k+1]=-1.
213 * All elliptic curve irreducibles have at most 5
214 * non-zero terms.
215 */
216
217 BIGNUM a, b; /* Curve coefficients.
218 * (Here the assumption is that BIGNUMs can be used
219 * or abused for all kinds of fields, not just GF(p).)
220 * For characteristic > 3, the curve is defined
221 * by a Weierstrass equation of the form
222 * y^2 = x^3 + a*x + b.
223 * For characteristic 2, the curve is defined by
224 * an equation of the form
225 * y^2 + x*y = x^3 + a*x^2 + b.
226 */
227
228 int a_is_minus3; /* enable optimized point arithmetics for special case */
229
230 void *field_data1; /* method-specific (e.g., Montgomery structure) */
231 void *field_data2; /* method-specific */
232 int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */
233} /* EC_GROUP */;
234
235struct ec_key_st {
236 int version;
237
238 EC_GROUP *group;
239
240 EC_POINT *pub_key;
241 BIGNUM *priv_key;
242
243 unsigned int enc_flag;
244 point_conversion_form_t conv_form;
245
246 int references;
247
248 EC_EXTRA_DATA *method_data;
249} /* EC_KEY */;
250
251/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
252 * (with visibility limited to 'package' level for now).
253 * We use the function pointers as index for retrieval; this obviates
254 * global ex_data-style index tables.
255 */
256int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
257 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
258void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
259 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
260void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
261 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
262void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
263 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
264void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
265void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
266
267
268
269struct ec_point_st {
270 const EC_METHOD *meth;
271
272 /* All members except 'meth' are handled by the method functions,
273 * even if they appear generic */
274
275 BIGNUM X;
276 BIGNUM Y;
277 BIGNUM Z; /* Jacobian projective coordinates:
278 * (X, Y, Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
279 int Z_is_one; /* enable optimized point arithmetics for special case */
280} /* EC_POINT */;
281
282
283
284/* method functions in ec_mult.c
285 * (ec_lib.c uses these as defaults if group->method->mul is 0) */
286int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
287 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
288int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
289int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
290
291
292/* method functions in ecp_smpl.c */
293int ec_GFp_simple_group_init(EC_GROUP *);
294void ec_GFp_simple_group_finish(EC_GROUP *);
295void ec_GFp_simple_group_clear_finish(EC_GROUP *);
296int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
297int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
298int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
299int ec_GFp_simple_group_get_degree(const EC_GROUP *);
300int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
301int ec_GFp_simple_point_init(EC_POINT *);
302void ec_GFp_simple_point_finish(EC_POINT *);
303void ec_GFp_simple_point_clear_finish(EC_POINT *);
304int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
305int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
306int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
307 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
308int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
309 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
310int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
311 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
312int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
313 BIGNUM *x, BIGNUM *y, BN_CTX *);
314int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
315 const BIGNUM *x, int y_bit, BN_CTX *);
316size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
317 unsigned char *buf, size_t len, BN_CTX *);
318int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
319 const unsigned char *buf, size_t len, BN_CTX *);
320int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
321int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
322int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
323int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
324int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
325int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
326int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
327int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
328int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
329int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
330
331
332/* method functions in ecp_mont.c */
333int ec_GFp_mont_group_init(EC_GROUP *);
334int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
335void ec_GFp_mont_group_finish(EC_GROUP *);
336void ec_GFp_mont_group_clear_finish(EC_GROUP *);
337int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
338int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
339int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
340int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
341int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
342int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
343
344
345/* method functions in ecp_nist.c */
346int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
347int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
348int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
349int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
350
351
352/* method functions in ec2_smpl.c */
353int ec_GF2m_simple_group_init(EC_GROUP *);
354void ec_GF2m_simple_group_finish(EC_GROUP *);
355void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
356int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
357int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
358int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
359int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
360int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
361int ec_GF2m_simple_point_init(EC_POINT *);
362void ec_GF2m_simple_point_finish(EC_POINT *);
363void ec_GF2m_simple_point_clear_finish(EC_POINT *);
364int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
365int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
366int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
367 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
368int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
369 BIGNUM *x, BIGNUM *y, BN_CTX *);
370int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
371 const BIGNUM *x, int y_bit, BN_CTX *);
372size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
373 unsigned char *buf, size_t len, BN_CTX *);
374int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
375 const unsigned char *buf, size_t len, BN_CTX *);
376int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
377int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
378int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
379int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
380int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
381int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
382int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
383int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
384int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
385int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
386int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
387
388
389/* method functions in ec2_mult.c */
390int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
391 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
392int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
393int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
deleted file mode 100644
index dd7da0fcf9..0000000000
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ /dev/null
@@ -1,1164 +0,0 @@
1/* crypto/ec/ec_lib.c */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-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 * 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 * Binary polynomial ECC support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/err.h>
67#include <openssl/opensslv.h>
68
69#include "ec_lcl.h"
70
71static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
72
73
74/* functions for EC_GROUP objects */
75
76EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
77 {
78 EC_GROUP *ret;
79
80 if (meth == NULL)
81 {
82 ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
83 return NULL;
84 }
85 if (meth->group_init == 0)
86 {
87 ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
88 return NULL;
89 }
90
91 ret = OPENSSL_malloc(sizeof *ret);
92 if (ret == NULL)
93 {
94 ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
95 return NULL;
96 }
97
98 ret->meth = meth;
99
100 ret->extra_data = NULL;
101
102 ret->generator = NULL;
103 BN_init(&ret->order);
104 BN_init(&ret->cofactor);
105
106 ret->curve_name = 0;
107 ret->asn1_flag = 0;
108 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
109
110 ret->seed = NULL;
111 ret->seed_len = 0;
112
113 if (!meth->group_init(ret))
114 {
115 OPENSSL_free(ret);
116 return NULL;
117 }
118
119 return ret;
120 }
121
122
123void EC_GROUP_free(EC_GROUP *group)
124 {
125 if (!group) return;
126
127 if (group->meth->group_finish != 0)
128 group->meth->group_finish(group);
129
130 EC_EX_DATA_free_all_data(&group->extra_data);
131
132 if (group->generator != NULL)
133 EC_POINT_free(group->generator);
134 BN_free(&group->order);
135 BN_free(&group->cofactor);
136
137 if (group->seed)
138 OPENSSL_free(group->seed);
139
140 OPENSSL_free(group);
141 }
142
143
144void EC_GROUP_clear_free(EC_GROUP *group)
145 {
146 if (!group) return;
147
148 if (group->meth->group_clear_finish != 0)
149 group->meth->group_clear_finish(group);
150 else if (group->meth->group_finish != 0)
151 group->meth->group_finish(group);
152
153 EC_EX_DATA_clear_free_all_data(&group->extra_data);
154
155 if (group->generator != NULL)
156 EC_POINT_clear_free(group->generator);
157 BN_clear_free(&group->order);
158 BN_clear_free(&group->cofactor);
159
160 if (group->seed)
161 {
162 OPENSSL_cleanse(group->seed, group->seed_len);
163 OPENSSL_free(group->seed);
164 }
165
166 OPENSSL_cleanse(group, sizeof *group);
167 OPENSSL_free(group);
168 }
169
170
171int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
172 {
173 EC_EXTRA_DATA *d;
174
175 if (dest->meth->group_copy == 0)
176 {
177 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
178 return 0;
179 }
180 if (dest->meth != src->meth)
181 {
182 ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
183 return 0;
184 }
185 if (dest == src)
186 return 1;
187
188 EC_EX_DATA_free_all_data(&dest->extra_data);
189
190 for (d = src->extra_data; d != NULL; d = d->next)
191 {
192 void *t = d->dup_func(d->data);
193
194 if (t == NULL)
195 return 0;
196 if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func, d->free_func, d->clear_free_func))
197 return 0;
198 }
199
200 if (src->generator != NULL)
201 {
202 if (dest->generator == NULL)
203 {
204 dest->generator = EC_POINT_new(dest);
205 if (dest->generator == NULL) return 0;
206 }
207 if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
208 }
209 else
210 {
211 /* src->generator == NULL */
212 if (dest->generator != NULL)
213 {
214 EC_POINT_clear_free(dest->generator);
215 dest->generator = NULL;
216 }
217 }
218
219 if (!BN_copy(&dest->order, &src->order)) return 0;
220 if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
221
222 dest->curve_name = src->curve_name;
223 dest->asn1_flag = src->asn1_flag;
224 dest->asn1_form = src->asn1_form;
225
226 if (src->seed)
227 {
228 if (dest->seed)
229 OPENSSL_free(dest->seed);
230 dest->seed = OPENSSL_malloc(src->seed_len);
231 if (dest->seed == NULL)
232 return 0;
233 if (!memcpy(dest->seed, src->seed, src->seed_len))
234 return 0;
235 dest->seed_len = src->seed_len;
236 }
237 else
238 {
239 if (dest->seed)
240 OPENSSL_free(dest->seed);
241 dest->seed = NULL;
242 dest->seed_len = 0;
243 }
244
245
246 return dest->meth->group_copy(dest, src);
247 }
248
249
250EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
251 {
252 EC_GROUP *t = NULL;
253 int ok = 0;
254
255 if (a == NULL) return NULL;
256
257 if ((t = EC_GROUP_new(a->meth)) == NULL) return(NULL);
258 if (!EC_GROUP_copy(t, a)) goto err;
259
260 ok = 1;
261
262 err:
263 if (!ok)
264 {
265 if (t) EC_GROUP_free(t);
266 return NULL;
267 }
268 else return t;
269 }
270
271
272const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
273 {
274 return group->meth;
275 }
276
277
278int EC_METHOD_get_field_type(const EC_METHOD *meth)
279 {
280 return meth->field_type;
281 }
282
283
284int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
285 {
286 if (generator == NULL)
287 {
288 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
289 return 0 ;
290 }
291
292 if (group->generator == NULL)
293 {
294 group->generator = EC_POINT_new(group);
295 if (group->generator == NULL) return 0;
296 }
297 if (!EC_POINT_copy(group->generator, generator)) return 0;
298
299 if (order != NULL)
300 { if (!BN_copy(&group->order, order)) return 0; }
301 else
302 BN_zero(&group->order);
303
304 if (cofactor != NULL)
305 { if (!BN_copy(&group->cofactor, cofactor)) return 0; }
306 else
307 BN_zero(&group->cofactor);
308
309 return 1;
310 }
311
312
313const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
314 {
315 return group->generator;
316 }
317
318
319int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
320 {
321 if (!BN_copy(order, &group->order))
322 return 0;
323
324 return !BN_is_zero(order);
325 }
326
327
328int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
329 {
330 if (!BN_copy(cofactor, &group->cofactor))
331 return 0;
332
333 return !BN_is_zero(&group->cofactor);
334 }
335
336
337void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
338 {
339 group->curve_name = nid;
340 }
341
342
343int EC_GROUP_get_curve_name(const EC_GROUP *group)
344 {
345 return group->curve_name;
346 }
347
348
349void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
350 {
351 group->asn1_flag = flag;
352 }
353
354
355int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
356 {
357 return group->asn1_flag;
358 }
359
360
361void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
362 point_conversion_form_t form)
363 {
364 group->asn1_form = form;
365 }
366
367
368point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
369 {
370 return group->asn1_form;
371 }
372
373
374size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
375 {
376 if (group->seed)
377 {
378 OPENSSL_free(group->seed);
379 group->seed = NULL;
380 group->seed_len = 0;
381 }
382
383 if (!len || !p)
384 return 1;
385
386 if ((group->seed = OPENSSL_malloc(len)) == NULL)
387 return 0;
388 memcpy(group->seed, p, len);
389 group->seed_len = len;
390
391 return len;
392 }
393
394
395unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
396 {
397 return group->seed;
398 }
399
400
401size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
402 {
403 return group->seed_len;
404 }
405
406
407int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
408 {
409 if (group->meth->group_set_curve == 0)
410 {
411 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
412 return 0;
413 }
414 return group->meth->group_set_curve(group, p, a, b, ctx);
415 }
416
417
418int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
419 {
420 if (group->meth->group_get_curve == 0)
421 {
422 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
423 return 0;
424 }
425 return group->meth->group_get_curve(group, p, a, b, ctx);
426 }
427
428
429int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
430 {
431 if (group->meth->group_set_curve == 0)
432 {
433 ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
434 return 0;
435 }
436 return group->meth->group_set_curve(group, p, a, b, ctx);
437 }
438
439
440int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
441 {
442 if (group->meth->group_get_curve == 0)
443 {
444 ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
445 return 0;
446 }
447 return group->meth->group_get_curve(group, p, a, b, ctx);
448 }
449
450
451int EC_GROUP_get_degree(const EC_GROUP *group)
452 {
453 if (group->meth->group_get_degree == 0)
454 {
455 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
456 return 0;
457 }
458 return group->meth->group_get_degree(group);
459 }
460
461
462int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
463 {
464 if (group->meth->group_check_discriminant == 0)
465 {
466 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
467 return 0;
468 }
469 return group->meth->group_check_discriminant(group, ctx);
470 }
471
472
473int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
474 {
475 int r = 0;
476 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
477 BN_CTX *ctx_new = NULL;
478
479 /* compare the field types*/
480 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
481 EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
482 return 1;
483 /* compare the curve name (if present) */
484 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
485 EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b))
486 return 0;
487
488 if (!ctx)
489 ctx_new = ctx = BN_CTX_new();
490 if (!ctx)
491 return -1;
492
493 BN_CTX_start(ctx);
494 a1 = BN_CTX_get(ctx);
495 a2 = BN_CTX_get(ctx);
496 a3 = BN_CTX_get(ctx);
497 b1 = BN_CTX_get(ctx);
498 b2 = BN_CTX_get(ctx);
499 b3 = BN_CTX_get(ctx);
500 if (!b3)
501 {
502 BN_CTX_end(ctx);
503 if (ctx_new)
504 BN_CTX_free(ctx);
505 return -1;
506 }
507
508 /* XXX This approach assumes that the external representation
509 * of curves over the same field type is the same.
510 */
511 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
512 !b->meth->group_get_curve(b, b1, b2, b3, ctx))
513 r = 1;
514
515 if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
516 r = 1;
517
518 /* XXX EC_POINT_cmp() assumes that the methods are equal */
519 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
520 EC_GROUP_get0_generator(b), ctx))
521 r = 1;
522
523 if (!r)
524 {
525 /* compare the order and cofactor */
526 if (!EC_GROUP_get_order(a, a1, ctx) ||
527 !EC_GROUP_get_order(b, b1, ctx) ||
528 !EC_GROUP_get_cofactor(a, a2, ctx) ||
529 !EC_GROUP_get_cofactor(b, b2, ctx))
530 {
531 BN_CTX_end(ctx);
532 if (ctx_new)
533 BN_CTX_free(ctx);
534 return -1;
535 }
536 if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
537 r = 1;
538 }
539
540 BN_CTX_end(ctx);
541 if (ctx_new)
542 BN_CTX_free(ctx);
543
544 return r;
545 }
546
547
548/* this has 'package' visibility */
549int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
550 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
551 {
552 EC_EXTRA_DATA *d;
553
554 if (ex_data == NULL)
555 return 0;
556
557 for (d = *ex_data; d != NULL; d = d->next)
558 {
559 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
560 {
561 ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
562 return 0;
563 }
564 }
565
566 if (data == NULL)
567 /* no explicit entry needed */
568 return 1;
569
570 d = OPENSSL_malloc(sizeof *d);
571 if (d == NULL)
572 return 0;
573
574 d->data = data;
575 d->dup_func = dup_func;
576 d->free_func = free_func;
577 d->clear_free_func = clear_free_func;
578
579 d->next = *ex_data;
580 *ex_data = d;
581
582 return 1;
583 }
584
585/* this has 'package' visibility */
586void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
587 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
588 {
589 const EC_EXTRA_DATA *d;
590
591 for (d = ex_data; d != NULL; d = d->next)
592 {
593 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
594 return d->data;
595 }
596
597 return NULL;
598 }
599
600/* this has 'package' visibility */
601void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
602 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
603 {
604 EC_EXTRA_DATA **p;
605
606 if (ex_data == NULL)
607 return;
608
609 for (p = ex_data; *p != NULL; p = &((*p)->next))
610 {
611 if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
612 {
613 EC_EXTRA_DATA *next = (*p)->next;
614
615 (*p)->free_func((*p)->data);
616 OPENSSL_free(*p);
617
618 *p = next;
619 return;
620 }
621 }
622 }
623
624/* this has 'package' visibility */
625void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
626 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
627 {
628 EC_EXTRA_DATA **p;
629
630 if (ex_data == NULL)
631 return;
632
633 for (p = ex_data; *p != NULL; p = &((*p)->next))
634 {
635 if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
636 {
637 EC_EXTRA_DATA *next = (*p)->next;
638
639 (*p)->clear_free_func((*p)->data);
640 OPENSSL_free(*p);
641
642 *p = next;
643 return;
644 }
645 }
646 }
647
648/* this has 'package' visibility */
649void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
650 {
651 EC_EXTRA_DATA *d;
652
653 if (ex_data == NULL)
654 return;
655
656 d = *ex_data;
657 while (d)
658 {
659 EC_EXTRA_DATA *next = d->next;
660
661 d->free_func(d->data);
662 OPENSSL_free(d);
663
664 d = next;
665 }
666 *ex_data = NULL;
667 }
668
669/* this has 'package' visibility */
670void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
671 {
672 EC_EXTRA_DATA *d;
673
674 if (ex_data == NULL)
675 return;
676
677 d = *ex_data;
678 while (d)
679 {
680 EC_EXTRA_DATA *next = d->next;
681
682 d->clear_free_func(d->data);
683 OPENSSL_free(d);
684
685 d = next;
686 }
687 *ex_data = NULL;
688 }
689
690
691/* functions for EC_POINT objects */
692
693EC_POINT *EC_POINT_new(const EC_GROUP *group)
694 {
695 EC_POINT *ret;
696
697 if (group == NULL)
698 {
699 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
700 return NULL;
701 }
702 if (group->meth->point_init == 0)
703 {
704 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
705 return NULL;
706 }
707
708 ret = OPENSSL_malloc(sizeof *ret);
709 if (ret == NULL)
710 {
711 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
712 return NULL;
713 }
714
715 ret->meth = group->meth;
716
717 if (!ret->meth->point_init(ret))
718 {
719 OPENSSL_free(ret);
720 return NULL;
721 }
722
723 return ret;
724 }
725
726
727void EC_POINT_free(EC_POINT *point)
728 {
729 if (!point) return;
730
731 if (point->meth->point_finish != 0)
732 point->meth->point_finish(point);
733 OPENSSL_free(point);
734 }
735
736
737void EC_POINT_clear_free(EC_POINT *point)
738 {
739 if (!point) return;
740
741 if (point->meth->point_clear_finish != 0)
742 point->meth->point_clear_finish(point);
743 else if (point->meth->point_finish != 0)
744 point->meth->point_finish(point);
745 OPENSSL_cleanse(point, sizeof *point);
746 OPENSSL_free(point);
747 }
748
749
750int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
751 {
752 if (dest->meth->point_copy == 0)
753 {
754 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
755 return 0;
756 }
757 if (dest->meth != src->meth)
758 {
759 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
760 return 0;
761 }
762 if (dest == src)
763 return 1;
764 return dest->meth->point_copy(dest, src);
765 }
766
767
768EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
769 {
770 EC_POINT *t;
771 int r;
772
773 if (a == NULL) return NULL;
774
775 t = EC_POINT_new(group);
776 if (t == NULL) return(NULL);
777 r = EC_POINT_copy(t, a);
778 if (!r)
779 {
780 EC_POINT_free(t);
781 return NULL;
782 }
783 else return t;
784 }
785
786
787const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
788 {
789 return point->meth;
790 }
791
792
793int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
794 {
795 if (group->meth->point_set_to_infinity == 0)
796 {
797 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
798 return 0;
799 }
800 if (group->meth != point->meth)
801 {
802 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
803 return 0;
804 }
805 return group->meth->point_set_to_infinity(group, point);
806 }
807
808
809int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
810 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
811 {
812 if (group->meth->point_set_Jprojective_coordinates_GFp == 0)
813 {
814 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
815 return 0;
816 }
817 if (group->meth != point->meth)
818 {
819 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
820 return 0;
821 }
822 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
823 }
824
825
826int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
827 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
828 {
829 if (group->meth->point_get_Jprojective_coordinates_GFp == 0)
830 {
831 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
832 return 0;
833 }
834 if (group->meth != point->meth)
835 {
836 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
837 return 0;
838 }
839 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
840 }
841
842
843int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
844 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
845 {
846 if (group->meth->point_set_affine_coordinates == 0)
847 {
848 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
849 return 0;
850 }
851 if (group->meth != point->meth)
852 {
853 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
854 return 0;
855 }
856 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
857 }
858
859
860int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
861 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
862 {
863 if (group->meth->point_set_affine_coordinates == 0)
864 {
865 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
866 return 0;
867 }
868 if (group->meth != point->meth)
869 {
870 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
871 return 0;
872 }
873 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
874 }
875
876
877int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
878 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
879 {
880 if (group->meth->point_get_affine_coordinates == 0)
881 {
882 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
883 return 0;
884 }
885 if (group->meth != point->meth)
886 {
887 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
888 return 0;
889 }
890 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
891 }
892
893
894int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
895 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
896 {
897 if (group->meth->point_get_affine_coordinates == 0)
898 {
899 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
900 return 0;
901 }
902 if (group->meth != point->meth)
903 {
904 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
905 return 0;
906 }
907 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
908 }
909
910
911int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
912 const BIGNUM *x, int y_bit, BN_CTX *ctx)
913 {
914 if (group->meth->point_set_compressed_coordinates == 0)
915 {
916 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
917 return 0;
918 }
919 if (group->meth != point->meth)
920 {
921 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
922 return 0;
923 }
924 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
925 }
926
927
928int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
929 const BIGNUM *x, int y_bit, BN_CTX *ctx)
930 {
931 if (group->meth->point_set_compressed_coordinates == 0)
932 {
933 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
934 return 0;
935 }
936 if (group->meth != point->meth)
937 {
938 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
939 return 0;
940 }
941 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
942 }
943
944
945size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
946 unsigned char *buf, size_t len, BN_CTX *ctx)
947 {
948 if (group->meth->point2oct == 0)
949 {
950 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
951 return 0;
952 }
953 if (group->meth != point->meth)
954 {
955 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
956 return 0;
957 }
958 return group->meth->point2oct(group, point, form, buf, len, ctx);
959 }
960
961
962int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
963 const unsigned char *buf, size_t len, BN_CTX *ctx)
964 {
965 if (group->meth->oct2point == 0)
966 {
967 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
968 return 0;
969 }
970 if (group->meth != point->meth)
971 {
972 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
973 return 0;
974 }
975 return group->meth->oct2point(group, point, buf, len, ctx);
976 }
977
978
979int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
980 {
981 if (group->meth->add == 0)
982 {
983 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
984 return 0;
985 }
986 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth))
987 {
988 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
989 return 0;
990 }
991 return group->meth->add(group, r, a, b, ctx);
992 }
993
994
995int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
996 {
997 if (group->meth->dbl == 0)
998 {
999 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1000 return 0;
1001 }
1002 if ((group->meth != r->meth) || (r->meth != a->meth))
1003 {
1004 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
1005 return 0;
1006 }
1007 return group->meth->dbl(group, r, a, ctx);
1008 }
1009
1010
1011int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
1012 {
1013 if (group->meth->dbl == 0)
1014 {
1015 ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1016 return 0;
1017 }
1018 if (group->meth != a->meth)
1019 {
1020 ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
1021 return 0;
1022 }
1023 return group->meth->invert(group, a, ctx);
1024 }
1025
1026
1027int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1028 {
1029 if (group->meth->is_at_infinity == 0)
1030 {
1031 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1032 return 0;
1033 }
1034 if (group->meth != point->meth)
1035 {
1036 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
1037 return 0;
1038 }
1039 return group->meth->is_at_infinity(group, point);
1040 }
1041
1042
1043int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
1044 {
1045 if (group->meth->is_on_curve == 0)
1046 {
1047 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1048 return 0;
1049 }
1050 if (group->meth != point->meth)
1051 {
1052 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
1053 return 0;
1054 }
1055 return group->meth->is_on_curve(group, point, ctx);
1056 }
1057
1058
1059int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
1060 {
1061 if (group->meth->point_cmp == 0)
1062 {
1063 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1064 return 0;
1065 }
1066 if ((group->meth != a->meth) || (a->meth != b->meth))
1067 {
1068 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
1069 return 0;
1070 }
1071 return group->meth->point_cmp(group, a, b, ctx);
1072 }
1073
1074
1075int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1076 {
1077 if (group->meth->make_affine == 0)
1078 {
1079 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1080 return 0;
1081 }
1082 if (group->meth != point->meth)
1083 {
1084 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1085 return 0;
1086 }
1087 return group->meth->make_affine(group, point, ctx);
1088 }
1089
1090
1091int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1092 {
1093 size_t i;
1094
1095 if (group->meth->points_make_affine == 0)
1096 {
1097 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1098 return 0;
1099 }
1100 for (i = 0; i < num; i++)
1101 {
1102 if (group->meth != points[i]->meth)
1103 {
1104 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1105 return 0;
1106 }
1107 }
1108 return group->meth->points_make_affine(group, num, points, ctx);
1109 }
1110
1111
1112/* Functions for point multiplication.
1113 *
1114 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1115 * otherwise we dispatch through methods.
1116 */
1117
1118int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1119 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1120 {
1121 if (group->meth->mul == 0)
1122 /* use default */
1123 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
1124
1125 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
1126 }
1127
1128int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1129 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1130 {
1131 /* just a convenient interface to EC_POINTs_mul() */
1132
1133 const EC_POINT *points[1];
1134 const BIGNUM *scalars[1];
1135
1136 points[0] = point;
1137 scalars[0] = p_scalar;
1138
1139 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx);
1140 }
1141
1142int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
1143 {
1144 if (group->meth->mul == 0)
1145 /* use default */
1146 return ec_wNAF_precompute_mult(group, ctx);
1147
1148 if (group->meth->precompute_mult != 0)
1149 return group->meth->precompute_mult(group, ctx);
1150 else
1151 return 1; /* nothing to do, so report success */
1152 }
1153
1154int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1155 {
1156 if (group->meth->mul == 0)
1157 /* use default */
1158 return ec_wNAF_have_precompute_mult(group);
1159
1160 if (group->meth->have_precompute_mult != 0)
1161 return group->meth->have_precompute_mult(group);
1162 else
1163 return 0; /* cannot tell whether precomputation has been performed */
1164 }
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
deleted file mode 100644
index 19f21675fb..0000000000
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ /dev/null
@@ -1,940 +0,0 @@
1/* crypto/ec/ec_mult.c */
2/*
3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2007 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 of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/err.h>
67
68#include "ec_lcl.h"
69
70
71/*
72 * This file implements the wNAF-based interleaving multi-exponentation method
73 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
74 * for multiplication with precomputation, we use wNAF splitting
75 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
76 */
77
78
79
80
81/* structure for precomputed multiples of the generator */
82typedef struct ec_pre_comp_st {
83 const EC_GROUP *group; /* parent EC_GROUP object */
84 size_t blocksize; /* block size for wNAF splitting */
85 size_t numblocks; /* max. number of blocks for which we have precomputation */
86 size_t w; /* window size */
87 EC_POINT **points; /* array with pre-calculated multiples of generator:
88 * 'num' pointers to EC_POINT objects followed by a NULL */
89 size_t num; /* numblocks * 2^(w-1) */
90 int references;
91} EC_PRE_COMP;
92
93/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
94static void *ec_pre_comp_dup(void *);
95static void ec_pre_comp_free(void *);
96static void ec_pre_comp_clear_free(void *);
97
98static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
99 {
100 EC_PRE_COMP *ret = NULL;
101
102 if (!group)
103 return NULL;
104
105 ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
106 if (!ret)
107 {
108 ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
109 return ret;
110 }
111 ret->group = group;
112 ret->blocksize = 8; /* default */
113 ret->numblocks = 0;
114 ret->w = 4; /* default */
115 ret->points = NULL;
116 ret->num = 0;
117 ret->references = 1;
118 return ret;
119 }
120
121static void *ec_pre_comp_dup(void *src_)
122 {
123 EC_PRE_COMP *src = src_;
124
125 /* no need to actually copy, these objects never change! */
126
127 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
128
129 return src_;
130 }
131
132static void ec_pre_comp_free(void *pre_)
133 {
134 int i;
135 EC_PRE_COMP *pre = pre_;
136
137 if (!pre)
138 return;
139
140 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
141 if (i > 0)
142 return;
143
144 if (pre->points)
145 {
146 EC_POINT **p;
147
148 for (p = pre->points; *p != NULL; p++)
149 EC_POINT_free(*p);
150 OPENSSL_free(pre->points);
151 }
152 OPENSSL_free(pre);
153 }
154
155static void ec_pre_comp_clear_free(void *pre_)
156 {
157 int i;
158 EC_PRE_COMP *pre = pre_;
159
160 if (!pre)
161 return;
162
163 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
164 if (i > 0)
165 return;
166
167 if (pre->points)
168 {
169 EC_POINT **p;
170
171 for (p = pre->points; *p != NULL; p++)
172 {
173 EC_POINT_clear_free(*p);
174 OPENSSL_cleanse(p, sizeof *p);
175 }
176 OPENSSL_free(pre->points);
177 }
178 OPENSSL_cleanse(pre, sizeof *pre);
179 OPENSSL_free(pre);
180 }
181
182
183
184
185/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
186 * This is an array r[] of values that are either zero or odd with an
187 * absolute value less than 2^w satisfying
188 * scalar = \sum_j r[j]*2^j
189 * where at most one of any w+1 consecutive digits is non-zero
190 * with the exception that the most significant digit may be only
191 * w-1 zeros away from that next non-zero digit.
192 */
193static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
194 {
195 int window_val;
196 int ok = 0;
197 signed char *r = NULL;
198 int sign = 1;
199 int bit, next_bit, mask;
200 size_t len = 0, j;
201
202 if (BN_is_zero(scalar))
203 {
204 r = OPENSSL_malloc(1);
205 if (!r)
206 {
207 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
208 goto err;
209 }
210 r[0] = 0;
211 *ret_len = 1;
212 return r;
213 }
214
215 if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */
216 {
217 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
218 goto err;
219 }
220 bit = 1 << w; /* at most 128 */
221 next_bit = bit << 1; /* at most 256 */
222 mask = next_bit - 1; /* at most 255 */
223
224 if (BN_is_negative(scalar))
225 {
226 sign = -1;
227 }
228
229 if (scalar->d == NULL || scalar->top == 0)
230 {
231 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
232 goto err;
233 }
234
235 len = BN_num_bits(scalar);
236 r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation
237 * (*ret_len will be set to the actual length, i.e. at most
238 * BN_num_bits(scalar) + 1) */
239 if (r == NULL)
240 {
241 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
242 goto err;
243 }
244 window_val = scalar->d[0] & mask;
245 j = 0;
246 while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */
247 {
248 int digit = 0;
249
250 /* 0 <= window_val <= 2^(w+1) */
251
252 if (window_val & 1)
253 {
254 /* 0 < window_val < 2^(w+1) */
255
256 if (window_val & bit)
257 {
258 digit = window_val - next_bit; /* -2^w < digit < 0 */
259
260#if 1 /* modified wNAF */
261 if (j + w + 1 >= len)
262 {
263 /* special case for generating modified wNAFs:
264 * no new bits will be added into window_val,
265 * so using a positive digit here will decrease
266 * the total length of the representation */
267
268 digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
269 }
270#endif
271 }
272 else
273 {
274 digit = window_val; /* 0 < digit < 2^w */
275 }
276
277 if (digit <= -bit || digit >= bit || !(digit & 1))
278 {
279 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
280 goto err;
281 }
282
283 window_val -= digit;
284
285 /* now window_val is 0 or 2^(w+1) in standard wNAF generation;
286 * for modified window NAFs, it may also be 2^w
287 */
288 if (window_val != 0 && window_val != next_bit && window_val != bit)
289 {
290 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
291 goto err;
292 }
293 }
294
295 r[j++] = sign * digit;
296
297 window_val >>= 1;
298 window_val += bit * BN_is_bit_set(scalar, j + w);
299
300 if (window_val > next_bit)
301 {
302 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
303 goto err;
304 }
305 }
306
307 if (j > len + 1)
308 {
309 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
310 goto err;
311 }
312 len = j;
313 ok = 1;
314
315 err:
316 if (!ok)
317 {
318 OPENSSL_free(r);
319 r = NULL;
320 }
321 if (ok)
322 *ret_len = len;
323 return r;
324 }
325
326
327/* TODO: table should be optimised for the wNAF-based implementation,
328 * sometimes smaller windows will give better performance
329 * (thus the boundaries should be increased)
330 */
331#define EC_window_bits_for_scalar_size(b) \
332 ((size_t) \
333 ((b) >= 2000 ? 6 : \
334 (b) >= 800 ? 5 : \
335 (b) >= 300 ? 4 : \
336 (b) >= 70 ? 3 : \
337 (b) >= 20 ? 2 : \
338 1))
339
340/* Compute
341 * \sum scalars[i]*points[i],
342 * also including
343 * scalar*generator
344 * in the addition if scalar != NULL
345 */
346int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
347 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
348 {
349 BN_CTX *new_ctx = NULL;
350 const EC_POINT *generator = NULL;
351 EC_POINT *tmp = NULL;
352 size_t totalnum;
353 size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
354 size_t pre_points_per_block = 0;
355 size_t i, j;
356 int k;
357 int r_is_inverted = 0;
358 int r_is_at_infinity = 1;
359 size_t *wsize = NULL; /* individual window sizes */
360 signed char **wNAF = NULL; /* individual wNAFs */
361 size_t *wNAF_len = NULL;
362 size_t max_len = 0;
363 size_t num_val;
364 EC_POINT **val = NULL; /* precomputation */
365 EC_POINT **v;
366 EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */
367 const EC_PRE_COMP *pre_comp = NULL;
368 int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like other scalars,
369 * i.e. precomputation is not available */
370 int ret = 0;
371
372 if (group->meth != r->meth)
373 {
374 ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
375 return 0;
376 }
377
378 if ((scalar == NULL) && (num == 0))
379 {
380 return EC_POINT_set_to_infinity(group, r);
381 }
382
383 for (i = 0; i < num; i++)
384 {
385 if (group->meth != points[i]->meth)
386 {
387 ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
388 return 0;
389 }
390 }
391
392 if (ctx == NULL)
393 {
394 ctx = new_ctx = BN_CTX_new();
395 if (ctx == NULL)
396 goto err;
397 }
398
399 if (scalar != NULL)
400 {
401 generator = EC_GROUP_get0_generator(group);
402 if (generator == NULL)
403 {
404 ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
405 goto err;
406 }
407
408 /* look if we can use precomputed multiples of generator */
409
410 pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
411
412 if (pre_comp && pre_comp->numblocks && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0))
413 {
414 blocksize = pre_comp->blocksize;
415
416 /* determine maximum number of blocks that wNAF splitting may yield
417 * (NB: maximum wNAF length is bit length plus one) */
418 numblocks = (BN_num_bits(scalar) / blocksize) + 1;
419
420 /* we cannot use more blocks than we have precomputation for */
421 if (numblocks > pre_comp->numblocks)
422 numblocks = pre_comp->numblocks;
423
424 pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
425
426 /* check that pre_comp looks sane */
427 if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block))
428 {
429 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
430 goto err;
431 }
432 }
433 else
434 {
435 /* can't use precomputation */
436 pre_comp = NULL;
437 numblocks = 1;
438 num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
439 }
440 }
441
442 totalnum = num + numblocks;
443
444 wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
445 wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
446 wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */
447 val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
448
449 if (!wsize || !wNAF_len || !wNAF || !val_sub)
450 {
451 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
452 goto err;
453 }
454
455 wNAF[0] = NULL; /* preliminary pivot */
456
457 /* num_val will be the total number of temporarily precomputed points */
458 num_val = 0;
459
460 for (i = 0; i < num + num_scalar; i++)
461 {
462 size_t bits;
463
464 bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
465 wsize[i] = EC_window_bits_for_scalar_size(bits);
466 num_val += (size_t)1 << (wsize[i] - 1);
467 wNAF[i + 1] = NULL; /* make sure we always have a pivot */
468 wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
469 if (wNAF[i] == NULL)
470 goto err;
471 if (wNAF_len[i] > max_len)
472 max_len = wNAF_len[i];
473 }
474
475 if (numblocks)
476 {
477 /* we go here iff scalar != NULL */
478
479 if (pre_comp == NULL)
480 {
481 if (num_scalar != 1)
482 {
483 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
484 goto err;
485 }
486 /* we have already generated a wNAF for 'scalar' */
487 }
488 else
489 {
490 signed char *tmp_wNAF = NULL;
491 size_t tmp_len = 0;
492
493 if (num_scalar != 0)
494 {
495 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
496 goto err;
497 }
498
499 /* use the window size for which we have precomputation */
500 wsize[num] = pre_comp->w;
501 tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
502 if (!tmp_wNAF)
503 goto err;
504
505 if (tmp_len <= max_len)
506 {
507 /* One of the other wNAFs is at least as long
508 * as the wNAF belonging to the generator,
509 * so wNAF splitting will not buy us anything. */
510
511 numblocks = 1;
512 totalnum = num + 1; /* don't use wNAF splitting */
513 wNAF[num] = tmp_wNAF;
514 wNAF[num + 1] = NULL;
515 wNAF_len[num] = tmp_len;
516 if (tmp_len > max_len)
517 max_len = tmp_len;
518 /* pre_comp->points starts with the points that we need here: */
519 val_sub[num] = pre_comp->points;
520 }
521 else
522 {
523 /* don't include tmp_wNAF directly into wNAF array
524 * - use wNAF splitting and include the blocks */
525
526 signed char *pp;
527 EC_POINT **tmp_points;
528
529 if (tmp_len < numblocks * blocksize)
530 {
531 /* possibly we can do with fewer blocks than estimated */
532 numblocks = (tmp_len + blocksize - 1) / blocksize;
533 if (numblocks > pre_comp->numblocks)
534 {
535 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
536 goto err;
537 }
538 totalnum = num + numblocks;
539 }
540
541 /* split wNAF in 'numblocks' parts */
542 pp = tmp_wNAF;
543 tmp_points = pre_comp->points;
544
545 for (i = num; i < totalnum; i++)
546 {
547 if (i < totalnum - 1)
548 {
549 wNAF_len[i] = blocksize;
550 if (tmp_len < blocksize)
551 {
552 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
553 goto err;
554 }
555 tmp_len -= blocksize;
556 }
557 else
558 /* last block gets whatever is left
559 * (this could be more or less than 'blocksize'!) */
560 wNAF_len[i] = tmp_len;
561
562 wNAF[i + 1] = NULL;
563 wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
564 if (wNAF[i] == NULL)
565 {
566 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
567 OPENSSL_free(tmp_wNAF);
568 goto err;
569 }
570 memcpy(wNAF[i], pp, wNAF_len[i]);
571 if (wNAF_len[i] > max_len)
572 max_len = wNAF_len[i];
573
574 if (*tmp_points == NULL)
575 {
576 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
577 OPENSSL_free(tmp_wNAF);
578 goto err;
579 }
580 val_sub[i] = tmp_points;
581 tmp_points += pre_points_per_block;
582 pp += blocksize;
583 }
584 OPENSSL_free(tmp_wNAF);
585 }
586 }
587 }
588
589 /* All points we precompute now go into a single array 'val'.
590 * 'val_sub[i]' is a pointer to the subarray for the i-th point,
591 * or to a subarray of 'pre_comp->points' if we already have precomputation. */
592 val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
593 if (val == NULL)
594 {
595 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
596 goto err;
597 }
598 val[num_val] = NULL; /* pivot element */
599
600 /* allocate points for precomputation */
601 v = val;
602 for (i = 0; i < num + num_scalar; i++)
603 {
604 val_sub[i] = v;
605 for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++)
606 {
607 *v = EC_POINT_new(group);
608 if (*v == NULL) goto err;
609 v++;
610 }
611 }
612 if (!(v == val + num_val))
613 {
614 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
615 goto err;
616 }
617
618 if (!(tmp = EC_POINT_new(group)))
619 goto err;
620
621 /* prepare precomputed values:
622 * val_sub[i][0] := points[i]
623 * val_sub[i][1] := 3 * points[i]
624 * val_sub[i][2] := 5 * points[i]
625 * ...
626 */
627 for (i = 0; i < num + num_scalar; i++)
628 {
629 if (i < num)
630 {
631 if (!EC_POINT_copy(val_sub[i][0], points[i])) goto err;
632 }
633 else
634 {
635 if (!EC_POINT_copy(val_sub[i][0], generator)) goto err;
636 }
637
638 if (wsize[i] > 1)
639 {
640 if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err;
641 for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++)
642 {
643 if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err;
644 }
645 }
646 }
647
648#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */
649 if (!EC_POINTs_make_affine(group, num_val, val, ctx))
650 goto err;
651#endif
652
653 r_is_at_infinity = 1;
654
655 for (k = max_len - 1; k >= 0; k--)
656 {
657 if (!r_is_at_infinity)
658 {
659 if (!EC_POINT_dbl(group, r, r, ctx)) goto err;
660 }
661
662 for (i = 0; i < totalnum; i++)
663 {
664 if (wNAF_len[i] > (size_t)k)
665 {
666 int digit = wNAF[i][k];
667 int is_neg;
668
669 if (digit)
670 {
671 is_neg = digit < 0;
672
673 if (is_neg)
674 digit = -digit;
675
676 if (is_neg != r_is_inverted)
677 {
678 if (!r_is_at_infinity)
679 {
680 if (!EC_POINT_invert(group, r, ctx)) goto err;
681 }
682 r_is_inverted = !r_is_inverted;
683 }
684
685 /* digit > 0 */
686
687 if (r_is_at_infinity)
688 {
689 if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) goto err;
690 r_is_at_infinity = 0;
691 }
692 else
693 {
694 if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) goto err;
695 }
696 }
697 }
698 }
699 }
700
701 if (r_is_at_infinity)
702 {
703 if (!EC_POINT_set_to_infinity(group, r)) goto err;
704 }
705 else
706 {
707 if (r_is_inverted)
708 if (!EC_POINT_invert(group, r, ctx)) goto err;
709 }
710
711 ret = 1;
712
713 err:
714 if (new_ctx != NULL)
715 BN_CTX_free(new_ctx);
716 if (tmp != NULL)
717 EC_POINT_free(tmp);
718 if (wsize != NULL)
719 OPENSSL_free(wsize);
720 if (wNAF_len != NULL)
721 OPENSSL_free(wNAF_len);
722 if (wNAF != NULL)
723 {
724 signed char **w;
725
726 for (w = wNAF; *w != NULL; w++)
727 OPENSSL_free(*w);
728
729 OPENSSL_free(wNAF);
730 }
731 if (val != NULL)
732 {
733 for (v = val; *v != NULL; v++)
734 EC_POINT_clear_free(*v);
735
736 OPENSSL_free(val);
737 }
738 if (val_sub != NULL)
739 {
740 OPENSSL_free(val_sub);
741 }
742 return ret;
743 }
744
745
746/* ec_wNAF_precompute_mult()
747 * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
748 * for use with wNAF splitting as implemented in ec_wNAF_mul().
749 *
750 * 'pre_comp->points' is an array of multiples of the generator
751 * of the following form:
752 * points[0] = generator;
753 * points[1] = 3 * generator;
754 * ...
755 * points[2^(w-1)-1] = (2^(w-1)-1) * generator;
756 * points[2^(w-1)] = 2^blocksize * generator;
757 * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
758 * ...
759 * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator
760 * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator
761 * ...
762 * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
763 * points[2^(w-1)*numblocks] = NULL
764 */
765int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
766 {
767 const EC_POINT *generator;
768 EC_POINT *tmp_point = NULL, *base = NULL, **var;
769 BN_CTX *new_ctx = NULL;
770 BIGNUM *order;
771 size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
772 EC_POINT **points = NULL;
773 EC_PRE_COMP *pre_comp;
774 int ret = 0;
775
776 /* if there is an old EC_PRE_COMP object, throw it away */
777 EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
778
779 if ((pre_comp = ec_pre_comp_new(group)) == NULL)
780 return 0;
781
782 generator = EC_GROUP_get0_generator(group);
783 if (generator == NULL)
784 {
785 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
786 goto err;
787 }
788
789 if (ctx == NULL)
790 {
791 ctx = new_ctx = BN_CTX_new();
792 if (ctx == NULL)
793 goto err;
794 }
795
796 BN_CTX_start(ctx);
797 order = BN_CTX_get(ctx);
798 if (order == NULL) goto err;
799
800 if (!EC_GROUP_get_order(group, order, ctx)) goto err;
801 if (BN_is_zero(order))
802 {
803 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
804 goto err;
805 }
806
807 bits = BN_num_bits(order);
808 /* The following parameters mean we precompute (approximately)
809 * one point per bit.
810 *
811 * TBD: The combination 8, 4 is perfect for 160 bits; for other
812 * bit lengths, other parameter combinations might provide better
813 * efficiency.
814 */
815 blocksize = 8;
816 w = 4;
817 if (EC_window_bits_for_scalar_size(bits) > w)
818 {
819 /* let's not make the window too small ... */
820 w = EC_window_bits_for_scalar_size(bits);
821 }
822
823 numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */
824
825 pre_points_per_block = (size_t)1 << (w - 1);
826 num = pre_points_per_block * numblocks; /* number of points to compute and store */
827
828 points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1));
829 if (!points)
830 {
831 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
832 goto err;
833 }
834
835 var = points;
836 var[num] = NULL; /* pivot */
837 for (i = 0; i < num; i++)
838 {
839 if ((var[i] = EC_POINT_new(group)) == NULL)
840 {
841 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
842 goto err;
843 }
844 }
845
846 if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group)))
847 {
848 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
849 goto err;
850 }
851
852 if (!EC_POINT_copy(base, generator))
853 goto err;
854
855 /* do the precomputation */
856 for (i = 0; i < numblocks; i++)
857 {
858 size_t j;
859
860 if (!EC_POINT_dbl(group, tmp_point, base, ctx))
861 goto err;
862
863 if (!EC_POINT_copy(*var++, base))
864 goto err;
865
866 for (j = 1; j < pre_points_per_block; j++, var++)
867 {
868 /* calculate odd multiples of the current base point */
869 if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
870 goto err;
871 }
872
873 if (i < numblocks - 1)
874 {
875 /* get the next base (multiply current one by 2^blocksize) */
876 size_t k;
877
878 if (blocksize <= 2)
879 {
880 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
881 goto err;
882 }
883
884 if (!EC_POINT_dbl(group, base, tmp_point, ctx))
885 goto err;
886 for (k = 2; k < blocksize; k++)
887 {
888 if (!EC_POINT_dbl(group,base,base,ctx))
889 goto err;
890 }
891 }
892 }
893
894 if (!EC_POINTs_make_affine(group, num, points, ctx))
895 goto err;
896
897 pre_comp->group = group;
898 pre_comp->blocksize = blocksize;
899 pre_comp->numblocks = numblocks;
900 pre_comp->w = w;
901 pre_comp->points = points;
902 points = NULL;
903 pre_comp->num = num;
904
905 if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
906 ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
907 goto err;
908 pre_comp = NULL;
909
910 ret = 1;
911 err:
912 if (ctx != NULL)
913 BN_CTX_end(ctx);
914 if (new_ctx != NULL)
915 BN_CTX_free(new_ctx);
916 if (pre_comp)
917 ec_pre_comp_free(pre_comp);
918 if (points)
919 {
920 EC_POINT **p;
921
922 for (p = points; *p != NULL; p++)
923 EC_POINT_free(*p);
924 OPENSSL_free(points);
925 }
926 if (tmp_point)
927 EC_POINT_free(tmp_point);
928 if (base)
929 EC_POINT_free(base);
930 return ret;
931 }
932
933
934int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
935 {
936 if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
937 return 1;
938 else
939 return 0;
940 }
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
deleted file mode 100644
index f433076ca1..0000000000
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ /dev/null
@@ -1,340 +0,0 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/asn1t.h>
61#include <openssl/x509.h>
62#include <openssl/ec.h>
63#include <openssl/ecdsa.h>
64#include <openssl/evp.h>
65#include "evp_locl.h"
66
67/* EC pkey context structure */
68
69typedef struct
70 {
71 /* Key and paramgen group */
72 EC_GROUP *gen_group;
73 /* message digest */
74 const EVP_MD *md;
75 } EC_PKEY_CTX;
76
77static int pkey_ec_init(EVP_PKEY_CTX *ctx)
78 {
79 EC_PKEY_CTX *dctx;
80 dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
81 if (!dctx)
82 return 0;
83 dctx->gen_group = NULL;
84 dctx->md = NULL;
85
86 ctx->data = dctx;
87
88 return 1;
89 }
90
91static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
92 {
93 EC_PKEY_CTX *dctx, *sctx;
94 if (!pkey_ec_init(dst))
95 return 0;
96 sctx = src->data;
97 dctx = dst->data;
98 if (sctx->gen_group)
99 {
100 dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
101 if (!dctx->gen_group)
102 return 0;
103 }
104 dctx->md = sctx->md;
105 return 1;
106 }
107
108static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
109 {
110 EC_PKEY_CTX *dctx = ctx->data;
111 if (dctx)
112 {
113 if (dctx->gen_group)
114 EC_GROUP_free(dctx->gen_group);
115 OPENSSL_free(dctx);
116 }
117 }
118
119static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
120 const unsigned char *tbs, size_t tbslen)
121 {
122 int ret, type;
123 unsigned int sltmp;
124 EC_PKEY_CTX *dctx = ctx->data;
125 EC_KEY *ec = ctx->pkey->pkey.ec;
126
127 if (!sig)
128 {
129 *siglen = ECDSA_size(ec);
130 return 1;
131 }
132 else if(*siglen < (size_t)ECDSA_size(ec))
133 {
134 ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
135 return 0;
136 }
137
138 if (dctx->md)
139 type = EVP_MD_type(dctx->md);
140 else
141 type = NID_sha1;
142
143
144 ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
145
146 if (ret <= 0)
147 return ret;
148 *siglen = (size_t)sltmp;
149 return 1;
150 }
151
152static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
153 const unsigned char *sig, size_t siglen,
154 const unsigned char *tbs, size_t tbslen)
155 {
156 int ret, type;
157 EC_PKEY_CTX *dctx = ctx->data;
158 EC_KEY *ec = ctx->pkey->pkey.ec;
159
160 if (dctx->md)
161 type = EVP_MD_type(dctx->md);
162 else
163 type = NID_sha1;
164
165 ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
166
167 return ret;
168 }
169
170static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
171 {
172 int ret;
173 size_t outlen;
174 const EC_POINT *pubkey = NULL;
175 if (!ctx->pkey || !ctx->peerkey)
176 {
177 ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
178 return 0;
179 }
180
181 if (!key)
182 {
183 const EC_GROUP *group;
184 group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
185 *keylen = (EC_GROUP_get_degree(group) + 7)/8;
186 return 1;
187 }
188
189 pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
190
191 /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
192 * not an error, the result is truncated.
193 */
194
195 outlen = *keylen;
196
197 ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
198 if (ret < 0)
199 return ret;
200 *keylen = ret;
201 return 1;
202 }
203
204static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
205 {
206 EC_PKEY_CTX *dctx = ctx->data;
207 EC_GROUP *group;
208 switch (type)
209 {
210 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
211 group = EC_GROUP_new_by_curve_name(p1);
212 if (group == NULL)
213 {
214 ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
215 return 0;
216 }
217 if (dctx->gen_group)
218 EC_GROUP_free(dctx->gen_group);
219 dctx->gen_group = group;
220 return 1;
221
222 case EVP_PKEY_CTRL_MD:
223 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
224 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
225 EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
226 EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
227 EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
228 {
229 ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
230 return 0;
231 }
232 dctx->md = p2;
233 return 1;
234
235 case EVP_PKEY_CTRL_PEER_KEY:
236 /* Default behaviour is OK */
237 case EVP_PKEY_CTRL_DIGESTINIT:
238 case EVP_PKEY_CTRL_PKCS7_SIGN:
239 case EVP_PKEY_CTRL_CMS_SIGN:
240 return 1;
241
242 default:
243 return -2;
244
245 }
246 }
247
248static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
249 const char *type, const char *value)
250 {
251 if (!strcmp(type, "ec_paramgen_curve"))
252 {
253 int nid;
254 nid = OBJ_sn2nid(value);
255 if (nid == NID_undef)
256 nid = OBJ_ln2nid(value);
257 if (nid == NID_undef)
258 {
259 ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
260 return 0;
261 }
262 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
263 }
264 return -2;
265 }
266
267static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
268 {
269 EC_KEY *ec = NULL;
270 EC_PKEY_CTX *dctx = ctx->data;
271 int ret = 0;
272 if (dctx->gen_group == NULL)
273 {
274 ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
275 return 0;
276 }
277 ec = EC_KEY_new();
278 if (!ec)
279 return 0;
280 ret = EC_KEY_set_group(ec, dctx->gen_group);
281 if (ret)
282 EVP_PKEY_assign_EC_KEY(pkey, ec);
283 else
284 EC_KEY_free(ec);
285 return ret;
286 }
287
288static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
289 {
290 EC_KEY *ec = NULL;
291 if (ctx->pkey == NULL)
292 {
293 ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
294 return 0;
295 }
296 ec = EC_KEY_new();
297 if (!ec)
298 return 0;
299 EVP_PKEY_assign_EC_KEY(pkey, ec);
300 /* Note: if error return, pkey is freed by parent routine */
301 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
302 return 0;
303 return EC_KEY_generate_key(pkey->pkey.ec);
304 }
305
306const EVP_PKEY_METHOD ec_pkey_meth =
307 {
308 EVP_PKEY_EC,
309 0,
310 pkey_ec_init,
311 pkey_ec_copy,
312 pkey_ec_cleanup,
313
314 0,
315 pkey_ec_paramgen,
316
317 0,
318 pkey_ec_keygen,
319
320 0,
321 pkey_ec_sign,
322
323 0,
324 pkey_ec_verify,
325
326 0,0,
327
328 0,0,0,0,
329
330 0,0,
331
332 0,0,
333
334 0,
335 pkey_ec_derive,
336
337 pkey_ec_ctrl,
338 pkey_ec_ctrl_str
339
340 };
diff --git a/src/lib/libcrypto/ec/ec_print.c b/src/lib/libcrypto/ec/ec_print.c
deleted file mode 100644
index f7c8a303ac..0000000000
--- a/src/lib/libcrypto/ec/ec_print.c
+++ /dev/null
@@ -1,195 +0,0 @@
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 }
diff --git a/src/lib/libcrypto/ec/eck_prn.c b/src/lib/libcrypto/ec/eck_prn.c
deleted file mode 100644
index 7d3e175ae7..0000000000
--- a/src/lib/libcrypto/ec/eck_prn.c
+++ /dev/null
@@ -1,391 +0,0 @@
1/* crypto/ec/eck_prn.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 <stdio.h>
65#include "cryptlib.h"
66#include <openssl/evp.h>
67#include <openssl/ec.h>
68#include <openssl/bn.h>
69
70#ifndef OPENSSL_NO_FP_API
71int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
72 {
73 BIO *b;
74 int ret;
75
76 if ((b=BIO_new(BIO_s_file())) == NULL)
77 {
78 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
79 return(0);
80 }
81 BIO_set_fp(b, fp, BIO_NOCLOSE);
82 ret = ECPKParameters_print(b, x, off);
83 BIO_free(b);
84 return(ret);
85 }
86
87int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
88 {
89 BIO *b;
90 int ret;
91
92 if ((b=BIO_new(BIO_s_file())) == NULL)
93 {
94 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
95 return(0);
96 }
97 BIO_set_fp(b, fp, BIO_NOCLOSE);
98 ret = EC_KEY_print(b, x, off);
99 BIO_free(b);
100 return(ret);
101 }
102
103int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
104 {
105 BIO *b;
106 int ret;
107
108 if ((b=BIO_new(BIO_s_file())) == NULL)
109 {
110 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
111 return(0);
112 }
113 BIO_set_fp(b, fp, BIO_NOCLOSE);
114 ret = ECParameters_print(b, x);
115 BIO_free(b);
116 return(ret);
117 }
118#endif
119
120int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
121 {
122 EVP_PKEY *pk;
123 int ret;
124 pk = EVP_PKEY_new();
125 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
126 return 0;
127 ret = EVP_PKEY_print_private(bp, pk, off, NULL);
128 EVP_PKEY_free(pk);
129 return ret;
130 }
131
132int ECParameters_print(BIO *bp, const EC_KEY *x)
133 {
134 EVP_PKEY *pk;
135 int ret;
136 pk = EVP_PKEY_new();
137 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
138 return 0;
139 ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
140 EVP_PKEY_free(pk);
141 return ret;
142 }
143
144static int print_bin(BIO *fp, const char *str, const unsigned char *num,
145 size_t len, int off);
146
147int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
148 {
149 unsigned char *buffer=NULL;
150 size_t buf_len=0, i;
151 int ret=0, reason=ERR_R_BIO_LIB;
152 BN_CTX *ctx=NULL;
153 const EC_POINT *point=NULL;
154 BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
155 *order=NULL, *cofactor=NULL;
156 const unsigned char *seed;
157 size_t seed_len=0;
158
159 static const char *gen_compressed = "Generator (compressed):";
160 static const char *gen_uncompressed = "Generator (uncompressed):";
161 static const char *gen_hybrid = "Generator (hybrid):";
162
163 if (!x)
164 {
165 reason = ERR_R_PASSED_NULL_PARAMETER;
166 goto err;
167 }
168
169 ctx = BN_CTX_new();
170 if (ctx == NULL)
171 {
172 reason = ERR_R_MALLOC_FAILURE;
173 goto err;
174 }
175
176 if (EC_GROUP_get_asn1_flag(x))
177 {
178 /* the curve parameter are given by an asn1 OID */
179 int nid;
180
181 if (!BIO_indent(bp, off, 128))
182 goto err;
183
184 nid = EC_GROUP_get_curve_name(x);
185 if (nid == 0)
186 goto err;
187
188 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
189 goto err;
190 if (BIO_printf(bp, "\n") <= 0)
191 goto err;
192 }
193 else
194 {
195 /* explicit parameters */
196 int is_char_two = 0;
197 point_conversion_form_t form;
198 int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
199
200 if (tmp_nid == NID_X9_62_characteristic_two_field)
201 is_char_two = 1;
202
203 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
204 (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
205 (cofactor = BN_new()) == NULL)
206 {
207 reason = ERR_R_MALLOC_FAILURE;
208 goto err;
209 }
210
211 if (is_char_two)
212 {
213 if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
214 {
215 reason = ERR_R_EC_LIB;
216 goto err;
217 }
218 }
219 else /* prime field */
220 {
221 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
222 {
223 reason = ERR_R_EC_LIB;
224 goto err;
225 }
226 }
227
228 if ((point = EC_GROUP_get0_generator(x)) == NULL)
229 {
230 reason = ERR_R_EC_LIB;
231 goto err;
232 }
233 if (!EC_GROUP_get_order(x, order, NULL) ||
234 !EC_GROUP_get_cofactor(x, cofactor, NULL))
235 {
236 reason = ERR_R_EC_LIB;
237 goto err;
238 }
239
240 form = EC_GROUP_get_point_conversion_form(x);
241
242 if ((gen = EC_POINT_point2bn(x, point,
243 form, NULL, ctx)) == NULL)
244 {
245 reason = ERR_R_EC_LIB;
246 goto err;
247 }
248
249 buf_len = (size_t)BN_num_bytes(p);
250 if (buf_len < (i = (size_t)BN_num_bytes(a)))
251 buf_len = i;
252 if (buf_len < (i = (size_t)BN_num_bytes(b)))
253 buf_len = i;
254 if (buf_len < (i = (size_t)BN_num_bytes(gen)))
255 buf_len = i;
256 if (buf_len < (i = (size_t)BN_num_bytes(order)))
257 buf_len = i;
258 if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
259 buf_len = i;
260
261 if ((seed = EC_GROUP_get0_seed(x)) != NULL)
262 seed_len = EC_GROUP_get_seed_len(x);
263
264 buf_len += 10;
265 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
266 {
267 reason = ERR_R_MALLOC_FAILURE;
268 goto err;
269 }
270
271 if (!BIO_indent(bp, off, 128))
272 goto err;
273
274 /* print the 'short name' of the field type */
275 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
276 <= 0)
277 goto err;
278
279 if (is_char_two)
280 {
281 /* print the 'short name' of the base type OID */
282 int basis_type = EC_GROUP_get_basis_type(x);
283 if (basis_type == 0)
284 goto err;
285
286 if (!BIO_indent(bp, off, 128))
287 goto err;
288
289 if (BIO_printf(bp, "Basis Type: %s\n",
290 OBJ_nid2sn(basis_type)) <= 0)
291 goto err;
292
293 /* print the polynomial */
294 if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
295 off))
296 goto err;
297 }
298 else
299 {
300 if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off))
301 goto err;
302 }
303 if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
304 goto err;
305 if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
306 goto err;
307 if (form == POINT_CONVERSION_COMPRESSED)
308 {
309 if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
310 buffer, off))
311 goto err;
312 }
313 else if (form == POINT_CONVERSION_UNCOMPRESSED)
314 {
315 if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
316 buffer, off))
317 goto err;
318 }
319 else /* form == POINT_CONVERSION_HYBRID */
320 {
321 if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
322 buffer, off))
323 goto err;
324 }
325 if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
326 buffer, off)) goto err;
327 if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
328 buffer, off)) goto err;
329 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
330 goto err;
331 }
332 ret=1;
333err:
334 if (!ret)
335 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
336 if (p)
337 BN_free(p);
338 if (a)
339 BN_free(a);
340 if (b)
341 BN_free(b);
342 if (gen)
343 BN_free(gen);
344 if (order)
345 BN_free(order);
346 if (cofactor)
347 BN_free(cofactor);
348 if (ctx)
349 BN_CTX_free(ctx);
350 if (buffer != NULL)
351 OPENSSL_free(buffer);
352 return(ret);
353 }
354
355static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
356 size_t len, int off)
357 {
358 size_t i;
359 char str[128];
360
361 if (buf == NULL)
362 return 1;
363 if (off)
364 {
365 if (off > 128)
366 off=128;
367 memset(str,' ',off);
368 if (BIO_write(fp, str, off) <= 0)
369 return 0;
370 }
371
372 if (BIO_printf(fp,"%s", name) <= 0)
373 return 0;
374
375 for (i=0; i<len; i++)
376 {
377 if ((i%15) == 0)
378 {
379 str[0]='\n';
380 memset(&(str[1]),' ',off+4);
381 if (BIO_write(fp, str, off+1+4) <= 0)
382 return 0;
383 }
384 if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
385 return 0;
386 }
387 if (BIO_write(fp,"\n",1) <= 0)
388 return 0;
389
390 return 1;
391 }
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
deleted file mode 100644
index 9fc4a466a5..0000000000
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ /dev/null
@@ -1,315 +0,0 @@
1/* crypto/ec/ecp_mont.c */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2001 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 of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <openssl/err.h>
65
66#include "ec_lcl.h"
67
68
69const EC_METHOD *EC_GFp_mont_method(void)
70 {
71 static const EC_METHOD ret = {
72 NID_X9_62_prime_field,
73 ec_GFp_mont_group_init,
74 ec_GFp_mont_group_finish,
75 ec_GFp_mont_group_clear_finish,
76 ec_GFp_mont_group_copy,
77 ec_GFp_mont_group_set_curve,
78 ec_GFp_simple_group_get_curve,
79 ec_GFp_simple_group_get_degree,
80 ec_GFp_simple_group_check_discriminant,
81 ec_GFp_simple_point_init,
82 ec_GFp_simple_point_finish,
83 ec_GFp_simple_point_clear_finish,
84 ec_GFp_simple_point_copy,
85 ec_GFp_simple_point_set_to_infinity,
86 ec_GFp_simple_set_Jprojective_coordinates_GFp,
87 ec_GFp_simple_get_Jprojective_coordinates_GFp,
88 ec_GFp_simple_point_set_affine_coordinates,
89 ec_GFp_simple_point_get_affine_coordinates,
90 ec_GFp_simple_set_compressed_coordinates,
91 ec_GFp_simple_point2oct,
92 ec_GFp_simple_oct2point,
93 ec_GFp_simple_add,
94 ec_GFp_simple_dbl,
95 ec_GFp_simple_invert,
96 ec_GFp_simple_is_at_infinity,
97 ec_GFp_simple_is_on_curve,
98 ec_GFp_simple_cmp,
99 ec_GFp_simple_make_affine,
100 ec_GFp_simple_points_make_affine,
101 0 /* mul */,
102 0 /* precompute_mult */,
103 0 /* have_precompute_mult */,
104 ec_GFp_mont_field_mul,
105 ec_GFp_mont_field_sqr,
106 0 /* field_div */,
107 ec_GFp_mont_field_encode,
108 ec_GFp_mont_field_decode,
109 ec_GFp_mont_field_set_to_one };
110
111 return &ret;
112 }
113
114
115int ec_GFp_mont_group_init(EC_GROUP *group)
116 {
117 int ok;
118
119 ok = ec_GFp_simple_group_init(group);
120 group->field_data1 = NULL;
121 group->field_data2 = NULL;
122 return ok;
123 }
124
125
126void ec_GFp_mont_group_finish(EC_GROUP *group)
127 {
128 if (group->field_data1 != NULL)
129 {
130 BN_MONT_CTX_free(group->field_data1);
131 group->field_data1 = NULL;
132 }
133 if (group->field_data2 != NULL)
134 {
135 BN_free(group->field_data2);
136 group->field_data2 = NULL;
137 }
138 ec_GFp_simple_group_finish(group);
139 }
140
141
142void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
143 {
144 if (group->field_data1 != NULL)
145 {
146 BN_MONT_CTX_free(group->field_data1);
147 group->field_data1 = NULL;
148 }
149 if (group->field_data2 != NULL)
150 {
151 BN_clear_free(group->field_data2);
152 group->field_data2 = NULL;
153 }
154 ec_GFp_simple_group_clear_finish(group);
155 }
156
157
158int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
159 {
160 if (dest->field_data1 != NULL)
161 {
162 BN_MONT_CTX_free(dest->field_data1);
163 dest->field_data1 = NULL;
164 }
165 if (dest->field_data2 != NULL)
166 {
167 BN_clear_free(dest->field_data2);
168 dest->field_data2 = NULL;
169 }
170
171 if (!ec_GFp_simple_group_copy(dest, src)) return 0;
172
173 if (src->field_data1 != NULL)
174 {
175 dest->field_data1 = BN_MONT_CTX_new();
176 if (dest->field_data1 == NULL) return 0;
177 if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
178 }
179 if (src->field_data2 != NULL)
180 {
181 dest->field_data2 = BN_dup(src->field_data2);
182 if (dest->field_data2 == NULL) goto err;
183 }
184
185 return 1;
186
187 err:
188 if (dest->field_data1 != NULL)
189 {
190 BN_MONT_CTX_free(dest->field_data1);
191 dest->field_data1 = NULL;
192 }
193 return 0;
194 }
195
196
197int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
198 {
199 BN_CTX *new_ctx = NULL;
200 BN_MONT_CTX *mont = NULL;
201 BIGNUM *one = NULL;
202 int ret = 0;
203
204 if (group->field_data1 != NULL)
205 {
206 BN_MONT_CTX_free(group->field_data1);
207 group->field_data1 = NULL;
208 }
209 if (group->field_data2 != NULL)
210 {
211 BN_free(group->field_data2);
212 group->field_data2 = NULL;
213 }
214
215 if (ctx == NULL)
216 {
217 ctx = new_ctx = BN_CTX_new();
218 if (ctx == NULL)
219 return 0;
220 }
221
222 mont = BN_MONT_CTX_new();
223 if (mont == NULL) goto err;
224 if (!BN_MONT_CTX_set(mont, p, ctx))
225 {
226 ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
227 goto err;
228 }
229 one = BN_new();
230 if (one == NULL) goto err;
231 if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
232
233 group->field_data1 = mont;
234 mont = NULL;
235 group->field_data2 = one;
236 one = NULL;
237
238 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
239
240 if (!ret)
241 {
242 BN_MONT_CTX_free(group->field_data1);
243 group->field_data1 = NULL;
244 BN_free(group->field_data2);
245 group->field_data2 = NULL;
246 }
247
248 err:
249 if (new_ctx != NULL)
250 BN_CTX_free(new_ctx);
251 if (mont != NULL)
252 BN_MONT_CTX_free(mont);
253 return ret;
254 }
255
256
257int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
258 {
259 if (group->field_data1 == NULL)
260 {
261 ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
262 return 0;
263 }
264
265 return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
266 }
267
268
269int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
270 {
271 if (group->field_data1 == NULL)
272 {
273 ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
274 return 0;
275 }
276
277 return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
278 }
279
280
281int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
282 {
283 if (group->field_data1 == NULL)
284 {
285 ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
286 return 0;
287 }
288
289 return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
290 }
291
292
293int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
294 {
295 if (group->field_data1 == NULL)
296 {
297 ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
298 return 0;
299 }
300
301 return BN_from_montgomery(r, a, group->field_data1, ctx);
302 }
303
304
305int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
306 {
307 if (group->field_data2 == NULL)
308 {
309 ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
310 return 0;
311 }
312
313 if (!BN_copy(r, group->field_data2)) return 0;
314 return 1;
315 }
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
deleted file mode 100644
index 2a5682ea41..0000000000
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ /dev/null
@@ -1,210 +0,0 @@
1/* crypto/ec/ecp_nist.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-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 * 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 of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <limits.h>
65
66#include <openssl/err.h>
67#include <openssl/obj_mac.h>
68#include "ec_lcl.h"
69
70const EC_METHOD *EC_GFp_nist_method(void)
71 {
72 static const EC_METHOD ret = {
73 NID_X9_62_prime_field,
74 ec_GFp_simple_group_init,
75 ec_GFp_simple_group_finish,
76 ec_GFp_simple_group_clear_finish,
77 ec_GFp_nist_group_copy,
78 ec_GFp_nist_group_set_curve,
79 ec_GFp_simple_group_get_curve,
80 ec_GFp_simple_group_get_degree,
81 ec_GFp_simple_group_check_discriminant,
82 ec_GFp_simple_point_init,
83 ec_GFp_simple_point_finish,
84 ec_GFp_simple_point_clear_finish,
85 ec_GFp_simple_point_copy,
86 ec_GFp_simple_point_set_to_infinity,
87 ec_GFp_simple_set_Jprojective_coordinates_GFp,
88 ec_GFp_simple_get_Jprojective_coordinates_GFp,
89 ec_GFp_simple_point_set_affine_coordinates,
90 ec_GFp_simple_point_get_affine_coordinates,
91 ec_GFp_simple_set_compressed_coordinates,
92 ec_GFp_simple_point2oct,
93 ec_GFp_simple_oct2point,
94 ec_GFp_simple_add,
95 ec_GFp_simple_dbl,
96 ec_GFp_simple_invert,
97 ec_GFp_simple_is_at_infinity,
98 ec_GFp_simple_is_on_curve,
99 ec_GFp_simple_cmp,
100 ec_GFp_simple_make_affine,
101 ec_GFp_simple_points_make_affine,
102 0 /* mul */,
103 0 /* precompute_mult */,
104 0 /* have_precompute_mult */,
105 ec_GFp_nist_field_mul,
106 ec_GFp_nist_field_sqr,
107 0 /* field_div */,
108 0 /* field_encode */,
109 0 /* field_decode */,
110 0 /* field_set_to_one */ };
111
112 return &ret;
113 }
114
115int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
116 {
117 dest->field_mod_func = src->field_mod_func;
118
119 return ec_GFp_simple_group_copy(dest, src);
120 }
121
122int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
123 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
124 {
125 int ret = 0;
126 BN_CTX *new_ctx = NULL;
127 BIGNUM *tmp_bn;
128
129 if (ctx == NULL)
130 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
131
132 BN_CTX_start(ctx);
133 if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
134
135 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
136 group->field_mod_func = BN_nist_mod_192;
137 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
138 group->field_mod_func = BN_nist_mod_224;
139 else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
140 group->field_mod_func = BN_nist_mod_256;
141 else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
142 group->field_mod_func = BN_nist_mod_384;
143 else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
144 group->field_mod_func = BN_nist_mod_521;
145 else
146 {
147 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
148 goto err;
149 }
150
151 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
152
153 err:
154 BN_CTX_end(ctx);
155 if (new_ctx != NULL)
156 BN_CTX_free(new_ctx);
157 return ret;
158 }
159
160
161int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
162 const BIGNUM *b, BN_CTX *ctx)
163 {
164 int ret=0;
165 BN_CTX *ctx_new=NULL;
166
167 if (!group || !r || !a || !b)
168 {
169 ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
170 goto err;
171 }
172 if (!ctx)
173 if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
174
175 if (!BN_mul(r, a, b, ctx)) goto err;
176 if (!group->field_mod_func(r, r, &group->field, ctx))
177 goto err;
178
179 ret=1;
180err:
181 if (ctx_new)
182 BN_CTX_free(ctx_new);
183 return ret;
184 }
185
186
187int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
188 BN_CTX *ctx)
189 {
190 int ret=0;
191 BN_CTX *ctx_new=NULL;
192
193 if (!group || !r || !a)
194 {
195 ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
196 goto err;
197 }
198 if (!ctx)
199 if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
200
201 if (!BN_sqr(r, a, ctx)) goto err;
202 if (!group->field_mod_func(r, r, &group->field, ctx))
203 goto err;
204
205 ret=1;
206err:
207 if (ctx_new)
208 BN_CTX_free(ctx_new);
209 return ret;
210 }
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c
deleted file mode 100644
index 66a92e2a90..0000000000
--- a/src/lib/libcrypto/ec/ecp_smpl.c
+++ /dev/null
@@ -1,1719 +0,0 @@
1/* crypto/ec/ecp_smpl.c */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project.
5*/
6/* ====================================================================
7 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* ====================================================================
60 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
61 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
62 * and contributed to the OpenSSL project.
63 */
64
65#include <openssl/err.h>
66#include <openssl/symhacks.h>
67
68#include "ec_lcl.h"
69
70const EC_METHOD *EC_GFp_simple_method(void)
71 {
72 static const EC_METHOD ret = {
73 NID_X9_62_prime_field,
74 ec_GFp_simple_group_init,
75 ec_GFp_simple_group_finish,
76 ec_GFp_simple_group_clear_finish,
77 ec_GFp_simple_group_copy,
78 ec_GFp_simple_group_set_curve,
79 ec_GFp_simple_group_get_curve,
80 ec_GFp_simple_group_get_degree,
81 ec_GFp_simple_group_check_discriminant,
82 ec_GFp_simple_point_init,
83 ec_GFp_simple_point_finish,
84 ec_GFp_simple_point_clear_finish,
85 ec_GFp_simple_point_copy,
86 ec_GFp_simple_point_set_to_infinity,
87 ec_GFp_simple_set_Jprojective_coordinates_GFp,
88 ec_GFp_simple_get_Jprojective_coordinates_GFp,
89 ec_GFp_simple_point_set_affine_coordinates,
90 ec_GFp_simple_point_get_affine_coordinates,
91 ec_GFp_simple_set_compressed_coordinates,
92 ec_GFp_simple_point2oct,
93 ec_GFp_simple_oct2point,
94 ec_GFp_simple_add,
95 ec_GFp_simple_dbl,
96 ec_GFp_simple_invert,
97 ec_GFp_simple_is_at_infinity,
98 ec_GFp_simple_is_on_curve,
99 ec_GFp_simple_cmp,
100 ec_GFp_simple_make_affine,
101 ec_GFp_simple_points_make_affine,
102 0 /* mul */,
103 0 /* precompute_mult */,
104 0 /* have_precompute_mult */,
105 ec_GFp_simple_field_mul,
106 ec_GFp_simple_field_sqr,
107 0 /* field_div */,
108 0 /* field_encode */,
109 0 /* field_decode */,
110 0 /* field_set_to_one */ };
111
112 return &ret;
113 }
114
115
116/* Most method functions in this file are designed to work with
117 * non-trivial representations of field elements if necessary
118 * (see ecp_mont.c): while standard modular addition and subtraction
119 * are used, the field_mul and field_sqr methods will be used for
120 * multiplication, and field_encode and field_decode (if defined)
121 * will be used for converting between representations.
122
123 * Functions ec_GFp_simple_points_make_affine() and
124 * ec_GFp_simple_point_get_affine_coordinates() specifically assume
125 * that if a non-trivial representation is used, it is a Montgomery
126 * representation (i.e. 'encoding' means multiplying by some factor R).
127 */
128
129
130int ec_GFp_simple_group_init(EC_GROUP *group)
131 {
132 BN_init(&group->field);
133 BN_init(&group->a);
134 BN_init(&group->b);
135 group->a_is_minus3 = 0;
136 return 1;
137 }
138
139
140void ec_GFp_simple_group_finish(EC_GROUP *group)
141 {
142 BN_free(&group->field);
143 BN_free(&group->a);
144 BN_free(&group->b);
145 }
146
147
148void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
149 {
150 BN_clear_free(&group->field);
151 BN_clear_free(&group->a);
152 BN_clear_free(&group->b);
153 }
154
155
156int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
157 {
158 if (!BN_copy(&dest->field, &src->field)) return 0;
159 if (!BN_copy(&dest->a, &src->a)) return 0;
160 if (!BN_copy(&dest->b, &src->b)) return 0;
161
162 dest->a_is_minus3 = src->a_is_minus3;
163
164 return 1;
165 }
166
167
168int ec_GFp_simple_group_set_curve(EC_GROUP *group,
169 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
170 {
171 int ret = 0;
172 BN_CTX *new_ctx = NULL;
173 BIGNUM *tmp_a;
174
175 /* p must be a prime > 3 */
176 if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
177 {
178 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
179 return 0;
180 }
181
182 if (ctx == NULL)
183 {
184 ctx = new_ctx = BN_CTX_new();
185 if (ctx == NULL)
186 return 0;
187 }
188
189 BN_CTX_start(ctx);
190 tmp_a = BN_CTX_get(ctx);
191 if (tmp_a == NULL) goto err;
192
193 /* group->field */
194 if (!BN_copy(&group->field, p)) goto err;
195 BN_set_negative(&group->field, 0);
196
197 /* group->a */
198 if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
199 if (group->meth->field_encode)
200 { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; }
201 else
202 if (!BN_copy(&group->a, tmp_a)) goto err;
203
204 /* group->b */
205 if (!BN_nnmod(&group->b, b, p, ctx)) goto err;
206 if (group->meth->field_encode)
207 if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err;
208
209 /* group->a_is_minus3 */
210 if (!BN_add_word(tmp_a, 3)) goto err;
211 group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
212
213 ret = 1;
214
215 err:
216 BN_CTX_end(ctx);
217 if (new_ctx != NULL)
218 BN_CTX_free(new_ctx);
219 return ret;
220 }
221
222
223int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
224 {
225 int ret = 0;
226 BN_CTX *new_ctx = NULL;
227
228 if (p != NULL)
229 {
230 if (!BN_copy(p, &group->field)) return 0;
231 }
232
233 if (a != NULL || b != NULL)
234 {
235 if (group->meth->field_decode)
236 {
237 if (ctx == NULL)
238 {
239 ctx = new_ctx = BN_CTX_new();
240 if (ctx == NULL)
241 return 0;
242 }
243 if (a != NULL)
244 {
245 if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
246 }
247 if (b != NULL)
248 {
249 if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
250 }
251 }
252 else
253 {
254 if (a != NULL)
255 {
256 if (!BN_copy(a, &group->a)) goto err;
257 }
258 if (b != NULL)
259 {
260 if (!BN_copy(b, &group->b)) goto err;
261 }
262 }
263 }
264
265 ret = 1;
266
267 err:
268 if (new_ctx)
269 BN_CTX_free(new_ctx);
270 return ret;
271 }
272
273
274int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
275 {
276 return BN_num_bits(&group->field);
277 }
278
279
280int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
281 {
282 int ret = 0;
283 BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
284 const BIGNUM *p = &group->field;
285 BN_CTX *new_ctx = NULL;
286
287 if (ctx == NULL)
288 {
289 ctx = new_ctx = BN_CTX_new();
290 if (ctx == NULL)
291 {
292 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
293 goto err;
294 }
295 }
296 BN_CTX_start(ctx);
297 a = BN_CTX_get(ctx);
298 b = BN_CTX_get(ctx);
299 tmp_1 = BN_CTX_get(ctx);
300 tmp_2 = BN_CTX_get(ctx);
301 order = BN_CTX_get(ctx);
302 if (order == NULL) goto err;
303
304 if (group->meth->field_decode)
305 {
306 if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
307 if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
308 }
309 else
310 {
311 if (!BN_copy(a, &group->a)) goto err;
312 if (!BN_copy(b, &group->b)) goto err;
313 }
314
315 /* check the discriminant:
316 * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
317 * 0 =< a, b < p */
318 if (BN_is_zero(a))
319 {
320 if (BN_is_zero(b)) goto err;
321 }
322 else if (!BN_is_zero(b))
323 {
324 if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
325 if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
326 if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
327 /* tmp_1 = 4*a^3 */
328
329 if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
330 if (!BN_mul_word(tmp_2, 27)) goto err;
331 /* tmp_2 = 27*b^2 */
332
333 if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
334 if (BN_is_zero(a)) goto err;
335 }
336 ret = 1;
337
338err:
339 if (ctx != NULL)
340 BN_CTX_end(ctx);
341 if (new_ctx != NULL)
342 BN_CTX_free(new_ctx);
343 return ret;
344 }
345
346
347int ec_GFp_simple_point_init(EC_POINT *point)
348 {
349 BN_init(&point->X);
350 BN_init(&point->Y);
351 BN_init(&point->Z);
352 point->Z_is_one = 0;
353
354 return 1;
355 }
356
357
358void ec_GFp_simple_point_finish(EC_POINT *point)
359 {
360 BN_free(&point->X);
361 BN_free(&point->Y);
362 BN_free(&point->Z);
363 }
364
365
366void ec_GFp_simple_point_clear_finish(EC_POINT *point)
367 {
368 BN_clear_free(&point->X);
369 BN_clear_free(&point->Y);
370 BN_clear_free(&point->Z);
371 point->Z_is_one = 0;
372 }
373
374
375int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
376 {
377 if (!BN_copy(&dest->X, &src->X)) return 0;
378 if (!BN_copy(&dest->Y, &src->Y)) return 0;
379 if (!BN_copy(&dest->Z, &src->Z)) return 0;
380 dest->Z_is_one = src->Z_is_one;
381
382 return 1;
383 }
384
385
386int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
387 {
388 point->Z_is_one = 0;
389 BN_zero(&point->Z);
390 return 1;
391 }
392
393
394int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
395 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
396 {
397 BN_CTX *new_ctx = NULL;
398 int ret = 0;
399
400 if (ctx == NULL)
401 {
402 ctx = new_ctx = BN_CTX_new();
403 if (ctx == NULL)
404 return 0;
405 }
406
407 if (x != NULL)
408 {
409 if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err;
410 if (group->meth->field_encode)
411 {
412 if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err;
413 }
414 }
415
416 if (y != NULL)
417 {
418 if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err;
419 if (group->meth->field_encode)
420 {
421 if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err;
422 }
423 }
424
425 if (z != NULL)
426 {
427 int Z_is_one;
428
429 if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err;
430 Z_is_one = BN_is_one(&point->Z);
431 if (group->meth->field_encode)
432 {
433 if (Z_is_one && (group->meth->field_set_to_one != 0))
434 {
435 if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err;
436 }
437 else
438 {
439 if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err;
440 }
441 }
442 point->Z_is_one = Z_is_one;
443 }
444
445 ret = 1;
446
447 err:
448 if (new_ctx != NULL)
449 BN_CTX_free(new_ctx);
450 return ret;
451 }
452
453
454int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
455 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
456 {
457 BN_CTX *new_ctx = NULL;
458 int ret = 0;
459
460 if (group->meth->field_decode != 0)
461 {
462 if (ctx == NULL)
463 {
464 ctx = new_ctx = BN_CTX_new();
465 if (ctx == NULL)
466 return 0;
467 }
468
469 if (x != NULL)
470 {
471 if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
472 }
473 if (y != NULL)
474 {
475 if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
476 }
477 if (z != NULL)
478 {
479 if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err;
480 }
481 }
482 else
483 {
484 if (x != NULL)
485 {
486 if (!BN_copy(x, &point->X)) goto err;
487 }
488 if (y != NULL)
489 {
490 if (!BN_copy(y, &point->Y)) goto err;
491 }
492 if (z != NULL)
493 {
494 if (!BN_copy(z, &point->Z)) goto err;
495 }
496 }
497
498 ret = 1;
499
500 err:
501 if (new_ctx != NULL)
502 BN_CTX_free(new_ctx);
503 return ret;
504 }
505
506
507int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
508 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
509 {
510 if (x == NULL || y == NULL)
511 {
512 /* unlike for projective coordinates, we do not tolerate this */
513 ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
514 return 0;
515 }
516
517 return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
518 }
519
520
521int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
522 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
523 {
524 BN_CTX *new_ctx = NULL;
525 BIGNUM *Z, *Z_1, *Z_2, *Z_3;
526 const BIGNUM *Z_;
527 int ret = 0;
528
529 if (EC_POINT_is_at_infinity(group, point))
530 {
531 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
532 return 0;
533 }
534
535 if (ctx == NULL)
536 {
537 ctx = new_ctx = BN_CTX_new();
538 if (ctx == NULL)
539 return 0;
540 }
541
542 BN_CTX_start(ctx);
543 Z = BN_CTX_get(ctx);
544 Z_1 = BN_CTX_get(ctx);
545 Z_2 = BN_CTX_get(ctx);
546 Z_3 = BN_CTX_get(ctx);
547 if (Z_3 == NULL) goto err;
548
549 /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
550
551 if (group->meth->field_decode)
552 {
553 if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
554 Z_ = Z;
555 }
556 else
557 {
558 Z_ = &point->Z;
559 }
560
561 if (BN_is_one(Z_))
562 {
563 if (group->meth->field_decode)
564 {
565 if (x != NULL)
566 {
567 if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
568 }
569 if (y != NULL)
570 {
571 if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
572 }
573 }
574 else
575 {
576 if (x != NULL)
577 {
578 if (!BN_copy(x, &point->X)) goto err;
579 }
580 if (y != NULL)
581 {
582 if (!BN_copy(y, &point->Y)) goto err;
583 }
584 }
585 }
586 else
587 {
588 if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
589 {
590 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
591 goto err;
592 }
593
594 if (group->meth->field_encode == 0)
595 {
596 /* field_sqr works on standard representation */
597 if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;
598 }
599 else
600 {
601 if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;
602 }
603
604 if (x != NULL)
605 {
606 /* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */
607 if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;
608 }
609
610 if (y != NULL)
611 {
612 if (group->meth->field_encode == 0)
613 {
614 /* field_mul works on standard representation */
615 if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
616 }
617 else
618 {
619 if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
620 }
621
622 /* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
623 if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
624 }
625 }
626
627 ret = 1;
628
629 err:
630 BN_CTX_end(ctx);
631 if (new_ctx != NULL)
632 BN_CTX_free(new_ctx);
633 return ret;
634 }
635
636
637int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
638 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
639 {
640 BN_CTX *new_ctx = NULL;
641 BIGNUM *tmp1, *tmp2, *x, *y;
642 int ret = 0;
643
644 /* clear error queue*/
645 ERR_clear_error();
646
647 if (ctx == NULL)
648 {
649 ctx = new_ctx = BN_CTX_new();
650 if (ctx == NULL)
651 return 0;
652 }
653
654 y_bit = (y_bit != 0);
655
656 BN_CTX_start(ctx);
657 tmp1 = BN_CTX_get(ctx);
658 tmp2 = BN_CTX_get(ctx);
659 x = BN_CTX_get(ctx);
660 y = BN_CTX_get(ctx);
661 if (y == NULL) goto err;
662
663 /* Recover y. We have a Weierstrass equation
664 * y^2 = x^3 + a*x + b,
665 * so y is one of the square roots of x^3 + a*x + b.
666 */
667
668 /* tmp1 := x^3 */
669 if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
670 if (group->meth->field_decode == 0)
671 {
672 /* field_{sqr,mul} work on standard representation */
673 if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
674 if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
675 }
676 else
677 {
678 if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
679 if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
680 }
681
682 /* tmp1 := tmp1 + a*x */
683 if (group->a_is_minus3)
684 {
685 if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
686 if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
687 if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
688 }
689 else
690 {
691 if (group->meth->field_decode)
692 {
693 if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
694 if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
695 }
696 else
697 {
698 /* field_mul works on standard representation */
699 if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
700 }
701
702 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
703 }
704
705 /* tmp1 := tmp1 + b */
706 if (group->meth->field_decode)
707 {
708 if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
709 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
710 }
711 else
712 {
713 if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
714 }
715
716 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
717 {
718 unsigned long err = ERR_peek_last_error();
719
720 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
721 {
722 ERR_clear_error();
723 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
724 }
725 else
726 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
727 goto err;
728 }
729
730 if (y_bit != BN_is_odd(y))
731 {
732 if (BN_is_zero(y))
733 {
734 int kron;
735
736 kron = BN_kronecker(x, &group->field, ctx);
737 if (kron == -2) goto err;
738
739 if (kron == 1)
740 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
741 else
742 /* BN_mod_sqrt() should have cought this error (not a square) */
743 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
744 goto err;
745 }
746 if (!BN_usub(y, &group->field, y)) goto err;
747 }
748 if (y_bit != BN_is_odd(y))
749 {
750 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
751 goto err;
752 }
753
754 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
755
756 ret = 1;
757
758 err:
759 BN_CTX_end(ctx);
760 if (new_ctx != NULL)
761 BN_CTX_free(new_ctx);
762 return ret;
763 }
764
765
766size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
767 unsigned char *buf, size_t len, BN_CTX *ctx)
768 {
769 size_t ret;
770 BN_CTX *new_ctx = NULL;
771 int used_ctx = 0;
772 BIGNUM *x, *y;
773 size_t field_len, i, skip;
774
775 if ((form != POINT_CONVERSION_COMPRESSED)
776 && (form != POINT_CONVERSION_UNCOMPRESSED)
777 && (form != POINT_CONVERSION_HYBRID))
778 {
779 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
780 goto err;
781 }
782
783 if (EC_POINT_is_at_infinity(group, point))
784 {
785 /* encodes to a single 0 octet */
786 if (buf != NULL)
787 {
788 if (len < 1)
789 {
790 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
791 return 0;
792 }
793 buf[0] = 0;
794 }
795 return 1;
796 }
797
798
799 /* ret := required output buffer length */
800 field_len = BN_num_bytes(&group->field);
801 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
802
803 /* if 'buf' is NULL, just return required length */
804 if (buf != NULL)
805 {
806 if (len < ret)
807 {
808 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
809 goto err;
810 }
811
812 if (ctx == NULL)
813 {
814 ctx = new_ctx = BN_CTX_new();
815 if (ctx == NULL)
816 return 0;
817 }
818
819 BN_CTX_start(ctx);
820 used_ctx = 1;
821 x = BN_CTX_get(ctx);
822 y = BN_CTX_get(ctx);
823 if (y == NULL) goto err;
824
825 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
826
827 if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
828 buf[0] = form + 1;
829 else
830 buf[0] = form;
831
832 i = 1;
833
834 skip = field_len - BN_num_bytes(x);
835 if (skip > field_len)
836 {
837 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
838 goto err;
839 }
840 while (skip > 0)
841 {
842 buf[i++] = 0;
843 skip--;
844 }
845 skip = BN_bn2bin(x, buf + i);
846 i += skip;
847 if (i != 1 + field_len)
848 {
849 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
850 goto err;
851 }
852
853 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
854 {
855 skip = field_len - BN_num_bytes(y);
856 if (skip > field_len)
857 {
858 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
859 goto err;
860 }
861 while (skip > 0)
862 {
863 buf[i++] = 0;
864 skip--;
865 }
866 skip = BN_bn2bin(y, buf + i);
867 i += skip;
868 }
869
870 if (i != ret)
871 {
872 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
873 goto err;
874 }
875 }
876
877 if (used_ctx)
878 BN_CTX_end(ctx);
879 if (new_ctx != NULL)
880 BN_CTX_free(new_ctx);
881 return ret;
882
883 err:
884 if (used_ctx)
885 BN_CTX_end(ctx);
886 if (new_ctx != NULL)
887 BN_CTX_free(new_ctx);
888 return 0;
889 }
890
891
892int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
893 const unsigned char *buf, size_t len, BN_CTX *ctx)
894 {
895 point_conversion_form_t form;
896 int y_bit;
897 BN_CTX *new_ctx = NULL;
898 BIGNUM *x, *y;
899 size_t field_len, enc_len;
900 int ret = 0;
901
902 if (len == 0)
903 {
904 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
905 return 0;
906 }
907 form = buf[0];
908 y_bit = form & 1;
909 form = form & ~1U;
910 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
911 && (form != POINT_CONVERSION_UNCOMPRESSED)
912 && (form != POINT_CONVERSION_HYBRID))
913 {
914 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
915 return 0;
916 }
917 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
918 {
919 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
920 return 0;
921 }
922
923 if (form == 0)
924 {
925 if (len != 1)
926 {
927 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
928 return 0;
929 }
930
931 return EC_POINT_set_to_infinity(group, point);
932 }
933
934 field_len = BN_num_bytes(&group->field);
935 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
936
937 if (len != enc_len)
938 {
939 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
940 return 0;
941 }
942
943 if (ctx == NULL)
944 {
945 ctx = new_ctx = BN_CTX_new();
946 if (ctx == NULL)
947 return 0;
948 }
949
950 BN_CTX_start(ctx);
951 x = BN_CTX_get(ctx);
952 y = BN_CTX_get(ctx);
953 if (y == NULL) goto err;
954
955 if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
956 if (BN_ucmp(x, &group->field) >= 0)
957 {
958 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
959 goto err;
960 }
961
962 if (form == POINT_CONVERSION_COMPRESSED)
963 {
964 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
965 }
966 else
967 {
968 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
969 if (BN_ucmp(y, &group->field) >= 0)
970 {
971 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
972 goto err;
973 }
974 if (form == POINT_CONVERSION_HYBRID)
975 {
976 if (y_bit != BN_is_odd(y))
977 {
978 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
979 goto err;
980 }
981 }
982
983 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
984 }
985
986 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
987 {
988 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
989 goto err;
990 }
991
992 ret = 1;
993
994 err:
995 BN_CTX_end(ctx);
996 if (new_ctx != NULL)
997 BN_CTX_free(new_ctx);
998 return ret;
999 }
1000
1001
1002int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
1003 {
1004 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1005 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1006 const BIGNUM *p;
1007 BN_CTX *new_ctx = NULL;
1008 BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
1009 int ret = 0;
1010
1011 if (a == b)
1012 return EC_POINT_dbl(group, r, a, ctx);
1013 if (EC_POINT_is_at_infinity(group, a))
1014 return EC_POINT_copy(r, b);
1015 if (EC_POINT_is_at_infinity(group, b))
1016 return EC_POINT_copy(r, a);
1017
1018 field_mul = group->meth->field_mul;
1019 field_sqr = group->meth->field_sqr;
1020 p = &group->field;
1021
1022 if (ctx == NULL)
1023 {
1024 ctx = new_ctx = BN_CTX_new();
1025 if (ctx == NULL)
1026 return 0;
1027 }
1028
1029 BN_CTX_start(ctx);
1030 n0 = BN_CTX_get(ctx);
1031 n1 = BN_CTX_get(ctx);
1032 n2 = BN_CTX_get(ctx);
1033 n3 = BN_CTX_get(ctx);
1034 n4 = BN_CTX_get(ctx);
1035 n5 = BN_CTX_get(ctx);
1036 n6 = BN_CTX_get(ctx);
1037 if (n6 == NULL) goto end;
1038
1039 /* Note that in this function we must not read components of 'a' or 'b'
1040 * once we have written the corresponding components of 'r'.
1041 * ('r' might be one of 'a' or 'b'.)
1042 */
1043
1044 /* n1, n2 */
1045 if (b->Z_is_one)
1046 {
1047 if (!BN_copy(n1, &a->X)) goto end;
1048 if (!BN_copy(n2, &a->Y)) goto end;
1049 /* n1 = X_a */
1050 /* n2 = Y_a */
1051 }
1052 else
1053 {
1054 if (!field_sqr(group, n0, &b->Z, ctx)) goto end;
1055 if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;
1056 /* n1 = X_a * Z_b^2 */
1057
1058 if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;
1059 if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;
1060 /* n2 = Y_a * Z_b^3 */
1061 }
1062
1063 /* n3, n4 */
1064 if (a->Z_is_one)
1065 {
1066 if (!BN_copy(n3, &b->X)) goto end;
1067 if (!BN_copy(n4, &b->Y)) goto end;
1068 /* n3 = X_b */
1069 /* n4 = Y_b */
1070 }
1071 else
1072 {
1073 if (!field_sqr(group, n0, &a->Z, ctx)) goto end;
1074 if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;
1075 /* n3 = X_b * Z_a^2 */
1076
1077 if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;
1078 if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;
1079 /* n4 = Y_b * Z_a^3 */
1080 }
1081
1082 /* n5, n6 */
1083 if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;
1084 if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;
1085 /* n5 = n1 - n3 */
1086 /* n6 = n2 - n4 */
1087
1088 if (BN_is_zero(n5))
1089 {
1090 if (BN_is_zero(n6))
1091 {
1092 /* a is the same point as b */
1093 BN_CTX_end(ctx);
1094 ret = EC_POINT_dbl(group, r, a, ctx);
1095 ctx = NULL;
1096 goto end;
1097 }
1098 else
1099 {
1100 /* a is the inverse of b */
1101 BN_zero(&r->Z);
1102 r->Z_is_one = 0;
1103 ret = 1;
1104 goto end;
1105 }
1106 }
1107
1108 /* 'n7', 'n8' */
1109 if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;
1110 if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;
1111 /* 'n7' = n1 + n3 */
1112 /* 'n8' = n2 + n4 */
1113
1114 /* Z_r */
1115 if (a->Z_is_one && b->Z_is_one)
1116 {
1117 if (!BN_copy(&r->Z, n5)) goto end;
1118 }
1119 else
1120 {
1121 if (a->Z_is_one)
1122 { if (!BN_copy(n0, &b->Z)) goto end; }
1123 else if (b->Z_is_one)
1124 { if (!BN_copy(n0, &a->Z)) goto end; }
1125 else
1126 { if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }
1127 if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;
1128 }
1129 r->Z_is_one = 0;
1130 /* Z_r = Z_a * Z_b * n5 */
1131
1132 /* X_r */
1133 if (!field_sqr(group, n0, n6, ctx)) goto end;
1134 if (!field_sqr(group, n4, n5, ctx)) goto end;
1135 if (!field_mul(group, n3, n1, n4, ctx)) goto end;
1136 if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;
1137 /* X_r = n6^2 - n5^2 * 'n7' */
1138
1139 /* 'n9' */
1140 if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;
1141 if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;
1142 /* n9 = n5^2 * 'n7' - 2 * X_r */
1143
1144 /* Y_r */
1145 if (!field_mul(group, n0, n0, n6, ctx)) goto end;
1146 if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */
1147 if (!field_mul(group, n1, n2, n5, ctx)) goto end;
1148 if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;
1149 if (BN_is_odd(n0))
1150 if (!BN_add(n0, n0, p)) goto end;
1151 /* now 0 <= n0 < 2*p, and n0 is even */
1152 if (!BN_rshift1(&r->Y, n0)) goto end;
1153 /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
1154
1155 ret = 1;
1156
1157 end:
1158 if (ctx) /* otherwise we already called BN_CTX_end */
1159 BN_CTX_end(ctx);
1160 if (new_ctx != NULL)
1161 BN_CTX_free(new_ctx);
1162 return ret;
1163 }
1164
1165
1166int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
1167 {
1168 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1169 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1170 const BIGNUM *p;
1171 BN_CTX *new_ctx = NULL;
1172 BIGNUM *n0, *n1, *n2, *n3;
1173 int ret = 0;
1174
1175 if (EC_POINT_is_at_infinity(group, a))
1176 {
1177 BN_zero(&r->Z);
1178 r->Z_is_one = 0;
1179 return 1;
1180 }
1181
1182 field_mul = group->meth->field_mul;
1183 field_sqr = group->meth->field_sqr;
1184 p = &group->field;
1185
1186 if (ctx == NULL)
1187 {
1188 ctx = new_ctx = BN_CTX_new();
1189 if (ctx == NULL)
1190 return 0;
1191 }
1192
1193 BN_CTX_start(ctx);
1194 n0 = BN_CTX_get(ctx);
1195 n1 = BN_CTX_get(ctx);
1196 n2 = BN_CTX_get(ctx);
1197 n3 = BN_CTX_get(ctx);
1198 if (n3 == NULL) goto err;
1199
1200 /* Note that in this function we must not read components of 'a'
1201 * once we have written the corresponding components of 'r'.
1202 * ('r' might the same as 'a'.)
1203 */
1204
1205 /* n1 */
1206 if (a->Z_is_one)
1207 {
1208 if (!field_sqr(group, n0, &a->X, ctx)) goto err;
1209 if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
1210 if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
1211 if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;
1212 /* n1 = 3 * X_a^2 + a_curve */
1213 }
1214 else if (group->a_is_minus3)
1215 {
1216 if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
1217 if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;
1218 if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;
1219 if (!field_mul(group, n1, n0, n2, ctx)) goto err;
1220 if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;
1221 if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;
1222 /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
1223 * = 3 * X_a^2 - 3 * Z_a^4 */
1224 }
1225 else
1226 {
1227 if (!field_sqr(group, n0, &a->X, ctx)) goto err;
1228 if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
1229 if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
1230 if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
1231 if (!field_sqr(group, n1, n1, ctx)) goto err;
1232 if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;
1233 if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;
1234 /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
1235 }
1236
1237 /* Z_r */
1238 if (a->Z_is_one)
1239 {
1240 if (!BN_copy(n0, &a->Y)) goto err;
1241 }
1242 else
1243 {
1244 if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;
1245 }
1246 if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;
1247 r->Z_is_one = 0;
1248 /* Z_r = 2 * Y_a * Z_a */
1249
1250 /* n2 */
1251 if (!field_sqr(group, n3, &a->Y, ctx)) goto err;
1252 if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;
1253 if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;
1254 /* n2 = 4 * X_a * Y_a^2 */
1255
1256 /* X_r */
1257 if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;
1258 if (!field_sqr(group, &r->X, n1, ctx)) goto err;
1259 if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;
1260 /* X_r = n1^2 - 2 * n2 */
1261
1262 /* n3 */
1263 if (!field_sqr(group, n0, n3, ctx)) goto err;
1264 if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;
1265 /* n3 = 8 * Y_a^4 */
1266
1267 /* Y_r */
1268 if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;
1269 if (!field_mul(group, n0, n1, n0, ctx)) goto err;
1270 if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;
1271 /* Y_r = n1 * (n2 - X_r) - n3 */
1272
1273 ret = 1;
1274
1275 err:
1276 BN_CTX_end(ctx);
1277 if (new_ctx != NULL)
1278 BN_CTX_free(new_ctx);
1279 return ret;
1280 }
1281
1282
1283int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1284 {
1285 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
1286 /* point is its own inverse */
1287 return 1;
1288
1289 return BN_usub(&point->Y, &group->field, &point->Y);
1290 }
1291
1292
1293int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1294 {
1295 return BN_is_zero(&point->Z);
1296 }
1297
1298
1299int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
1300 {
1301 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1302 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1303 const BIGNUM *p;
1304 BN_CTX *new_ctx = NULL;
1305 BIGNUM *rh, *tmp, *Z4, *Z6;
1306 int ret = -1;
1307
1308 if (EC_POINT_is_at_infinity(group, point))
1309 return 1;
1310
1311 field_mul = group->meth->field_mul;
1312 field_sqr = group->meth->field_sqr;
1313 p = &group->field;
1314
1315 if (ctx == NULL)
1316 {
1317 ctx = new_ctx = BN_CTX_new();
1318 if (ctx == NULL)
1319 return -1;
1320 }
1321
1322 BN_CTX_start(ctx);
1323 rh = BN_CTX_get(ctx);
1324 tmp = BN_CTX_get(ctx);
1325 Z4 = BN_CTX_get(ctx);
1326 Z6 = BN_CTX_get(ctx);
1327 if (Z6 == NULL) goto err;
1328
1329 /* We have a curve defined by a Weierstrass equation
1330 * y^2 = x^3 + a*x + b.
1331 * The point to consider is given in Jacobian projective coordinates
1332 * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
1333 * Substituting this and multiplying by Z^6 transforms the above equation into
1334 * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
1335 * To test this, we add up the right-hand side in 'rh'.
1336 */
1337
1338 /* rh := X^2 */
1339 if (!field_sqr(group, rh, &point->X, ctx)) goto err;
1340
1341 if (!point->Z_is_one)
1342 {
1343 if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
1344 if (!field_sqr(group, Z4, tmp, ctx)) goto err;
1345 if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
1346
1347 /* rh := (rh + a*Z^4)*X */
1348 if (group->a_is_minus3)
1349 {
1350 if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
1351 if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
1352 if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
1353 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1354 }
1355 else
1356 {
1357 if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
1358 if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
1359 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1360 }
1361
1362 /* rh := rh + b*Z^6 */
1363 if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
1364 if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
1365 }
1366 else
1367 {
1368 /* point->Z_is_one */
1369
1370 /* rh := (rh + a)*X */
1371 if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
1372 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1373 /* rh := rh + b */
1374 if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
1375 }
1376
1377 /* 'lh' := Y^2 */
1378 if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
1379
1380 ret = (0 == BN_ucmp(tmp, rh));
1381
1382 err:
1383 BN_CTX_end(ctx);
1384 if (new_ctx != NULL)
1385 BN_CTX_free(new_ctx);
1386 return ret;
1387 }
1388
1389
1390int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
1391 {
1392 /* return values:
1393 * -1 error
1394 * 0 equal (in affine coordinates)
1395 * 1 not equal
1396 */
1397
1398 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1399 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1400 BN_CTX *new_ctx = NULL;
1401 BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
1402 const BIGNUM *tmp1_, *tmp2_;
1403 int ret = -1;
1404
1405 if (EC_POINT_is_at_infinity(group, a))
1406 {
1407 return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
1408 }
1409
1410 if (EC_POINT_is_at_infinity(group, b))
1411 return 1;
1412
1413 if (a->Z_is_one && b->Z_is_one)
1414 {
1415 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
1416 }
1417
1418 field_mul = group->meth->field_mul;
1419 field_sqr = group->meth->field_sqr;
1420
1421 if (ctx == NULL)
1422 {
1423 ctx = new_ctx = BN_CTX_new();
1424 if (ctx == NULL)
1425 return -1;
1426 }
1427
1428 BN_CTX_start(ctx);
1429 tmp1 = BN_CTX_get(ctx);
1430 tmp2 = BN_CTX_get(ctx);
1431 Za23 = BN_CTX_get(ctx);
1432 Zb23 = BN_CTX_get(ctx);
1433 if (Zb23 == NULL) goto end;
1434
1435 /* We have to decide whether
1436 * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
1437 * or equivalently, whether
1438 * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
1439 */
1440
1441 if (!b->Z_is_one)
1442 {
1443 if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;
1444 if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;
1445 tmp1_ = tmp1;
1446 }
1447 else
1448 tmp1_ = &a->X;
1449 if (!a->Z_is_one)
1450 {
1451 if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;
1452 if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;
1453 tmp2_ = tmp2;
1454 }
1455 else
1456 tmp2_ = &b->X;
1457
1458 /* compare X_a*Z_b^2 with X_b*Z_a^2 */
1459 if (BN_cmp(tmp1_, tmp2_) != 0)
1460 {
1461 ret = 1; /* points differ */
1462 goto end;
1463 }
1464
1465
1466 if (!b->Z_is_one)
1467 {
1468 if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;
1469 if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;
1470 /* tmp1_ = tmp1 */
1471 }
1472 else
1473 tmp1_ = &a->Y;
1474 if (!a->Z_is_one)
1475 {
1476 if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;
1477 if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;
1478 /* tmp2_ = tmp2 */
1479 }
1480 else
1481 tmp2_ = &b->Y;
1482
1483 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
1484 if (BN_cmp(tmp1_, tmp2_) != 0)
1485 {
1486 ret = 1; /* points differ */
1487 goto end;
1488 }
1489
1490 /* points are equal */
1491 ret = 0;
1492
1493 end:
1494 BN_CTX_end(ctx);
1495 if (new_ctx != NULL)
1496 BN_CTX_free(new_ctx);
1497 return ret;
1498 }
1499
1500
1501int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1502 {
1503 BN_CTX *new_ctx = NULL;
1504 BIGNUM *x, *y;
1505 int ret = 0;
1506
1507 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
1508 return 1;
1509
1510 if (ctx == NULL)
1511 {
1512 ctx = new_ctx = BN_CTX_new();
1513 if (ctx == NULL)
1514 return 0;
1515 }
1516
1517 BN_CTX_start(ctx);
1518 x = BN_CTX_get(ctx);
1519 y = BN_CTX_get(ctx);
1520 if (y == NULL) goto err;
1521
1522 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
1523 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
1524 if (!point->Z_is_one)
1525 {
1526 ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
1527 goto err;
1528 }
1529
1530 ret = 1;
1531
1532 err:
1533 BN_CTX_end(ctx);
1534 if (new_ctx != NULL)
1535 BN_CTX_free(new_ctx);
1536 return ret;
1537 }
1538
1539
1540int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1541 {
1542 BN_CTX *new_ctx = NULL;
1543 BIGNUM *tmp0, *tmp1;
1544 size_t pow2 = 0;
1545 BIGNUM **heap = NULL;
1546 size_t i;
1547 int ret = 0;
1548
1549 if (num == 0)
1550 return 1;
1551
1552 if (ctx == NULL)
1553 {
1554 ctx = new_ctx = BN_CTX_new();
1555 if (ctx == NULL)
1556 return 0;
1557 }
1558
1559 BN_CTX_start(ctx);
1560 tmp0 = BN_CTX_get(ctx);
1561 tmp1 = BN_CTX_get(ctx);
1562 if (tmp0 == NULL || tmp1 == NULL) goto err;
1563
1564 /* Before converting the individual points, compute inverses of all Z values.
1565 * Modular inversion is rather slow, but luckily we can do with a single
1566 * explicit inversion, plus about 3 multiplications per input value.
1567 */
1568
1569 pow2 = 1;
1570 while (num > pow2)
1571 pow2 <<= 1;
1572 /* Now pow2 is the smallest power of 2 satifsying pow2 >= num.
1573 * We need twice that. */
1574 pow2 <<= 1;
1575
1576 heap = OPENSSL_malloc(pow2 * sizeof heap[0]);
1577 if (heap == NULL) goto err;
1578
1579 /* The array is used as a binary tree, exactly as in heapsort:
1580 *
1581 * heap[1]
1582 * heap[2] heap[3]
1583 * heap[4] heap[5] heap[6] heap[7]
1584 * heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]
1585 *
1586 * We put the Z's in the last line;
1587 * then we set each other node to the product of its two child-nodes (where
1588 * empty or 0 entries are treated as ones);
1589 * then we invert heap[1];
1590 * then we invert each other node by replacing it by the product of its
1591 * parent (after inversion) and its sibling (before inversion).
1592 */
1593 heap[0] = NULL;
1594 for (i = pow2/2 - 1; i > 0; i--)
1595 heap[i] = NULL;
1596 for (i = 0; i < num; i++)
1597 heap[pow2/2 + i] = &points[i]->Z;
1598 for (i = pow2/2 + num; i < pow2; i++)
1599 heap[i] = NULL;
1600
1601 /* set each node to the product of its children */
1602 for (i = pow2/2 - 1; i > 0; i--)
1603 {
1604 heap[i] = BN_new();
1605 if (heap[i] == NULL) goto err;
1606
1607 if (heap[2*i] != NULL)
1608 {
1609 if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))
1610 {
1611 if (!BN_copy(heap[i], heap[2*i])) goto err;
1612 }
1613 else
1614 {
1615 if (BN_is_zero(heap[2*i]))
1616 {
1617 if (!BN_copy(heap[i], heap[2*i + 1])) goto err;
1618 }
1619 else
1620 {
1621 if (!group->meth->field_mul(group, heap[i],
1622 heap[2*i], heap[2*i + 1], ctx)) goto err;
1623 }
1624 }
1625 }
1626 }
1627
1628 /* invert heap[1] */
1629 if (!BN_is_zero(heap[1]))
1630 {
1631 if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))
1632 {
1633 ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
1634 goto err;
1635 }
1636 }
1637 if (group->meth->field_encode != 0)
1638 {
1639 /* in the Montgomery case, we just turned R*H (representing H)
1640 * into 1/(R*H), but we need R*(1/H) (representing 1/H);
1641 * i.e. we have need to multiply by the Montgomery factor twice */
1642 if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
1643 if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
1644 }
1645
1646 /* set other heap[i]'s to their inverses */
1647 for (i = 2; i < pow2/2 + num; i += 2)
1648 {
1649 /* i is even */
1650 if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))
1651 {
1652 if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;
1653 if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;
1654 if (!BN_copy(heap[i], tmp0)) goto err;
1655 if (!BN_copy(heap[i + 1], tmp1)) goto err;
1656 }
1657 else
1658 {
1659 if (!BN_copy(heap[i], heap[i/2])) goto err;
1660 }
1661 }
1662
1663 /* we have replaced all non-zero Z's by their inverses, now fix up all the points */
1664 for (i = 0; i < num; i++)
1665 {
1666 EC_POINT *p = points[i];
1667
1668 if (!BN_is_zero(&p->Z))
1669 {
1670 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
1671
1672 if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;
1673 if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;
1674
1675 if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;
1676 if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;
1677
1678 if (group->meth->field_set_to_one != 0)
1679 {
1680 if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;
1681 }
1682 else
1683 {
1684 if (!BN_one(&p->Z)) goto err;
1685 }
1686 p->Z_is_one = 1;
1687 }
1688 }
1689
1690 ret = 1;
1691
1692 err:
1693 BN_CTX_end(ctx);
1694 if (new_ctx != NULL)
1695 BN_CTX_free(new_ctx);
1696 if (heap != NULL)
1697 {
1698 /* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
1699 for (i = pow2/2 - 1; i > 0; i--)
1700 {
1701 if (heap[i] != NULL)
1702 BN_clear_free(heap[i]);
1703 }
1704 OPENSSL_free(heap);
1705 }
1706 return ret;
1707 }
1708
1709
1710int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1711 {
1712 return BN_mod_mul(r, a, b, &group->field, ctx);
1713 }
1714
1715
1716int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
1717 {
1718 return BN_mod_sqr(r, a, &group->field, ctx);
1719 }