summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/ec/ec.h1159
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c390
-rw-r--r--src/lib/libcrypto/ec/ec2_oct.c407
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c719
-rw-r--r--src/lib/libcrypto/ec/ec_ameth.c660
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c1443
-rw-r--r--src/lib/libcrypto/ec/ec_check.c123
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c2100
-rw-r--r--src/lib/libcrypto/ec/ec_cvt.c170
-rw-r--r--src/lib/libcrypto/ec/ec_err.c276
-rw-r--r--src/lib/libcrypto/ec/ec_key.c563
-rw-r--r--src/lib/libcrypto/ec/ec_lcl.h446
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c1096
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c940
-rw-r--r--src/lib/libcrypto/ec/ec_oct.c199
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c341
-rw-r--r--src/lib/libcrypto/ec/ec_print.c195
-rw-r--r--src/lib/libcrypto/ec/eck_prn.c392
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c323
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c217
-rw-r--r--src/lib/libcrypto/ec/ecp_nistp224.c1658
-rw-r--r--src/lib/libcrypto/ec/ecp_nistp256.c2171
-rw-r--r--src/lib/libcrypto/ec/ecp_nistp521.c2025
-rw-r--r--src/lib/libcrypto/ec/ecp_nistputil.c197
-rw-r--r--src/lib/libcrypto/ec/ecp_oct.c433
-rw-r--r--src/lib/libcrypto/ec/ecp_smpl.c1360
-rw-r--r--src/lib/libcrypto/ecdh/ecdh.h125
-rw-r--r--src/lib/libcrypto/ecdh/ech_err.c100
-rw-r--r--src/lib/libcrypto/ecdh/ech_key.c83
-rw-r--r--src/lib/libcrypto/ecdh/ech_lib.c266
-rw-r--r--src/lib/libcrypto/ecdh/ech_locl.h102
-rw-r--r--src/lib/libcrypto/ecdsa/ecdsa.h260
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_asn1.c67
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_err.c106
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_lib.c278
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_locl.h115
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c483
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_sign.c106
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_vrf.c96
39 files changed, 0 insertions, 22190 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
deleted file mode 100644
index 9d01325af3..0000000000
--- a/src/lib/libcrypto/ec/ec.h
+++ /dev/null
@@ -1,1159 +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#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
155/** Returns 64-bit optimized methods for nistp224
156 * \return EC_METHOD object
157 */
158const EC_METHOD *EC_GFp_nistp224_method(void);
159
160/** Returns 64-bit optimized methods for nistp256
161 * \return EC_METHOD object
162 */
163const EC_METHOD *EC_GFp_nistp256_method(void);
164
165/** Returns 64-bit optimized methods for nistp521
166 * \return EC_METHOD object
167 */
168const EC_METHOD *EC_GFp_nistp521_method(void);
169#endif
170
171#ifndef OPENSSL_NO_EC2M
172/********************************************************************/
173/* EC_METHOD for curves over GF(2^m) */
174/********************************************************************/
175
176/** Returns the basic GF2m ec method
177 * \return EC_METHOD object
178 */
179const EC_METHOD *EC_GF2m_simple_method(void);
180
181#endif
182
183
184/********************************************************************/
185/* EC_GROUP functions */
186/********************************************************************/
187
188/** Creates a new EC_GROUP object
189 * \param meth EC_METHOD to use
190 * \return newly created EC_GROUP object or NULL in case of an error.
191 */
192EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
193
194/** Frees a EC_GROUP object
195 * \param group EC_GROUP object to be freed.
196 */
197void EC_GROUP_free(EC_GROUP *group);
198
199/** Clears and frees a EC_GROUP object
200 * \param group EC_GROUP object to be cleared and freed.
201 */
202void EC_GROUP_clear_free(EC_GROUP *group);
203
204/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
205 * \param dst destination EC_GROUP object
206 * \param src source EC_GROUP object
207 * \return 1 on success and 0 if an error occurred.
208 */
209int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
210
211/** Creates a new EC_GROUP object and copies the copies the content
212 * form src to the newly created EC_KEY object
213 * \param src source EC_GROUP object
214 * \return newly created EC_GROUP object or NULL in case of an error.
215 */
216EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
217
218/** Returns the EC_METHOD of the EC_GROUP object.
219 * \param group EC_GROUP object
220 * \return EC_METHOD used in this EC_GROUP object.
221 */
222const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
223
224/** Returns the field type of the EC_METHOD.
225 * \param meth EC_METHOD object
226 * \return NID of the underlying field type OID.
227 */
228int EC_METHOD_get_field_type(const EC_METHOD *meth);
229
230/** Sets the generator and it's order/cofactor of a EC_GROUP object.
231 * \param group EC_GROUP object
232 * \param generator EC_POINT object with the generator.
233 * \param order the order of the group generated by the generator.
234 * \param cofactor the index of the sub-group generated by the generator
235 * in the group of all points on the elliptic curve.
236 * \return 1 on success and 0 if an error occured
237 */
238int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
239
240/** Returns the generator of a EC_GROUP object.
241 * \param group EC_GROUP object
242 * \return the currently used generator (possibly NULL).
243 */
244const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
245
246/** Gets the order of a EC_GROUP
247 * \param group EC_GROUP object
248 * \param order BIGNUM to which the order is copied
249 * \param ctx BN_CTX object (optional)
250 * \return 1 on success and 0 if an error occured
251 */
252int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
253
254/** Gets the cofactor of a EC_GROUP
255 * \param group EC_GROUP object
256 * \param cofactor BIGNUM to which the cofactor is copied
257 * \param ctx BN_CTX object (optional)
258 * \return 1 on success and 0 if an error occured
259 */
260int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
261
262/** Sets the name of a EC_GROUP object
263 * \param group EC_GROUP object
264 * \param nid NID of the curve name OID
265 */
266void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
267
268/** Returns the curve name of a EC_GROUP object
269 * \param group EC_GROUP object
270 * \return NID of the curve name OID or 0 if not set.
271 */
272int EC_GROUP_get_curve_name(const EC_GROUP *group);
273
274void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
275int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
276
277void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
278point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
279
280unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
281size_t EC_GROUP_get_seed_len(const EC_GROUP *);
282size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
283
284/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
285 * \param group EC_GROUP object
286 * \param p BIGNUM with the prime number
287 * \param a BIGNUM with parameter a of the equation
288 * \param b BIGNUM with parameter b of the equation
289 * \param ctx BN_CTX object (optional)
290 * \return 1 on success and 0 if an error occured
291 */
292int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
293
294/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
295 * \param group EC_GROUP object
296 * \param p BIGNUM for the prime number
297 * \param a BIGNUM for parameter a of the equation
298 * \param b BIGNUM for parameter b of the equation
299 * \param ctx BN_CTX object (optional)
300 * \return 1 on success and 0 if an error occured
301 */
302int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
303
304#ifndef OPENSSL_NO_EC2M
305/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
306 * \param group EC_GROUP object
307 * \param p BIGNUM with the polynomial defining the underlying field
308 * \param a BIGNUM with parameter a of the equation
309 * \param b BIGNUM with parameter b of the equation
310 * \param ctx BN_CTX object (optional)
311 * \return 1 on success and 0 if an error occured
312 */
313int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
314
315/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
316 * \param group EC_GROUP object
317 * \param p BIGNUM for the polynomial defining the underlying field
318 * \param a BIGNUM for parameter a of the equation
319 * \param b BIGNUM for parameter b of the equation
320 * \param ctx BN_CTX object (optional)
321 * \return 1 on success and 0 if an error occured
322 */
323int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
324#endif
325/** Returns the number of bits needed to represent a field element
326 * \param group EC_GROUP object
327 * \return number of bits needed to represent a field element
328 */
329int EC_GROUP_get_degree(const EC_GROUP *group);
330
331/** Checks whether the parameter in the EC_GROUP define a valid ec group
332 * \param group EC_GROUP object
333 * \param ctx BN_CTX object (optional)
334 * \return 1 if group is a valid ec group and 0 otherwise
335 */
336int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
337
338/** Checks whether the discriminant of the elliptic curve is zero or not
339 * \param group EC_GROUP object
340 * \param ctx BN_CTX object (optional)
341 * \return 1 if the discriminant is not zero and 0 otherwise
342 */
343int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
344
345/** Compares two EC_GROUP objects
346 * \param a first EC_GROUP object
347 * \param b second EC_GROUP object
348 * \param ctx BN_CTX object (optional)
349 * \return 0 if both groups are equal and 1 otherwise
350 */
351int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
352
353/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
354 * after choosing an appropriate EC_METHOD */
355
356/** Creates a new EC_GROUP object with the specified parameters defined
357 * over GFp (defined by the equation y^2 = x^3 + a*x + b)
358 * \param p BIGNUM with the prime number
359 * \param a BIGNUM with the parameter a of the equation
360 * \param b BIGNUM with the parameter b of the equation
361 * \param ctx BN_CTX object (optional)
362 * \return newly created EC_GROUP object with the specified parameters
363 */
364EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
365#ifndef OPENSSL_NO_EC2M
366/** Creates a new EC_GROUP object with the specified parameters defined
367 * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
368 * \param p BIGNUM with the polynomial defining the underlying field
369 * \param a BIGNUM with the parameter a of the equation
370 * \param b BIGNUM with the parameter b of the equation
371 * \param ctx BN_CTX object (optional)
372 * \return newly created EC_GROUP object with the specified parameters
373 */
374EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
375#endif
376/** Creates a EC_GROUP object with a curve specified by a NID
377 * \param nid NID of the OID of the curve name
378 * \return newly created EC_GROUP object with specified curve or NULL
379 * if an error occurred
380 */
381EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
382
383
384/********************************************************************/
385/* handling of internal curves */
386/********************************************************************/
387
388typedef struct {
389 int nid;
390 const char *comment;
391 } EC_builtin_curve;
392
393/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number
394 * of all available curves or zero if a error occurred.
395 * In case r ist not zero nitems EC_builtin_curve structures
396 * are filled with the data of the first nitems internal groups */
397size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
398
399
400/********************************************************************/
401/* EC_POINT functions */
402/********************************************************************/
403
404/** Creates a new EC_POINT object for the specified EC_GROUP
405 * \param group EC_GROUP the underlying EC_GROUP object
406 * \return newly created EC_POINT object or NULL if an error occurred
407 */
408EC_POINT *EC_POINT_new(const EC_GROUP *group);
409
410/** Frees a EC_POINT object
411 * \param point EC_POINT object to be freed
412 */
413void EC_POINT_free(EC_POINT *point);
414
415/** Clears and frees a EC_POINT object
416 * \param point EC_POINT object to be cleared and freed
417 */
418void EC_POINT_clear_free(EC_POINT *point);
419
420/** Copies EC_POINT object
421 * \param dst destination EC_POINT object
422 * \param src source EC_POINT object
423 * \return 1 on success and 0 if an error occured
424 */
425int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
426
427/** Creates a new EC_POINT object and copies the content of the supplied
428 * EC_POINT
429 * \param src source EC_POINT object
430 * \param group underlying the EC_GROUP object
431 * \return newly created EC_POINT object or NULL if an error occurred
432 */
433EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
434
435/** Returns the EC_METHOD used in EC_POINT object
436 * \param point EC_POINT object
437 * \return the EC_METHOD used
438 */
439const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
440
441/** Sets a point to infinity (neutral element)
442 * \param group underlying EC_GROUP object
443 * \param point EC_POINT to set to infinity
444 * \return 1 on success and 0 if an error occured
445 */
446int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
447
448/** Sets the jacobian projective coordinates of a EC_POINT over GFp
449 * \param group underlying EC_GROUP object
450 * \param p EC_POINT object
451 * \param x BIGNUM with the x-coordinate
452 * \param y BIGNUM with the y-coordinate
453 * \param z BIGNUM with the z-coordinate
454 * \param ctx BN_CTX object (optional)
455 * \return 1 on success and 0 if an error occured
456 */
457int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
458 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
459
460/** Gets the jacobian projective coordinates of a EC_POINT over GFp
461 * \param group underlying EC_GROUP object
462 * \param p EC_POINT object
463 * \param x BIGNUM for the x-coordinate
464 * \param y BIGNUM for the y-coordinate
465 * \param z BIGNUM for the z-coordinate
466 * \param ctx BN_CTX object (optional)
467 * \return 1 on success and 0 if an error occured
468 */
469int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
470 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
471
472/** Sets the affine coordinates of a EC_POINT over GFp
473 * \param group underlying EC_GROUP object
474 * \param p EC_POINT object
475 * \param x BIGNUM with the x-coordinate
476 * \param y BIGNUM with the y-coordinate
477 * \param ctx BN_CTX object (optional)
478 * \return 1 on success and 0 if an error occured
479 */
480int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
481 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
482
483/** Gets the affine coordinates of a EC_POINT over GFp
484 * \param group underlying EC_GROUP object
485 * \param p EC_POINT object
486 * \param x BIGNUM for the x-coordinate
487 * \param y BIGNUM for the y-coordinate
488 * \param ctx BN_CTX object (optional)
489 * \return 1 on success and 0 if an error occured
490 */
491int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
492 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
493
494/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
495 * \param group underlying EC_GROUP object
496 * \param p EC_POINT object
497 * \param x BIGNUM with x-coordinate
498 * \param y_bit integer with the y-Bit (either 0 or 1)
499 * \param ctx BN_CTX object (optional)
500 * \return 1 on success and 0 if an error occured
501 */
502int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
503 const BIGNUM *x, int y_bit, BN_CTX *ctx);
504#ifndef OPENSSL_NO_EC2M
505/** Sets the affine coordinates of a EC_POINT over GF2m
506 * \param group underlying EC_GROUP object
507 * \param p EC_POINT object
508 * \param x BIGNUM with the x-coordinate
509 * \param y BIGNUM with the y-coordinate
510 * \param ctx BN_CTX object (optional)
511 * \return 1 on success and 0 if an error occured
512 */
513int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
514 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
515
516/** Gets the affine coordinates of a EC_POINT over GF2m
517 * \param group underlying EC_GROUP object
518 * \param p EC_POINT object
519 * \param x BIGNUM for the x-coordinate
520 * \param y BIGNUM for the y-coordinate
521 * \param ctx BN_CTX object (optional)
522 * \return 1 on success and 0 if an error occured
523 */
524int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
525 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
526
527/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
528 * \param group underlying EC_GROUP object
529 * \param p EC_POINT object
530 * \param x BIGNUM with x-coordinate
531 * \param y_bit integer with the y-Bit (either 0 or 1)
532 * \param ctx BN_CTX object (optional)
533 * \return 1 on success and 0 if an error occured
534 */
535int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
536 const BIGNUM *x, int y_bit, BN_CTX *ctx);
537#endif
538/** Encodes a EC_POINT object to a octet string
539 * \param group underlying EC_GROUP object
540 * \param p EC_POINT object
541 * \param form point conversion form
542 * \param buf memory buffer for the result. If NULL the function returns
543 * required buffer size.
544 * \param len length of the memory buffer
545 * \param ctx BN_CTX object (optional)
546 * \return the length of the encoded octet string or 0 if an error occurred
547 */
548size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
549 point_conversion_form_t form,
550 unsigned char *buf, size_t len, BN_CTX *ctx);
551
552/** Decodes a EC_POINT from a octet string
553 * \param group underlying EC_GROUP object
554 * \param p EC_POINT object
555 * \param buf memory buffer with the encoded ec point
556 * \param len length of the encoded ec point
557 * \param ctx BN_CTX object (optional)
558 * \return 1 on success and 0 if an error occured
559 */
560int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
561 const unsigned char *buf, size_t len, BN_CTX *ctx);
562
563/* other interfaces to point2oct/oct2point: */
564BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
565 point_conversion_form_t form, BIGNUM *, BN_CTX *);
566EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
567 EC_POINT *, BN_CTX *);
568char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
569 point_conversion_form_t form, BN_CTX *);
570EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
571 EC_POINT *, BN_CTX *);
572
573
574/********************************************************************/
575/* functions for doing EC_POINT arithmetic */
576/********************************************************************/
577
578/** Computes the sum of two EC_POINT
579 * \param group underlying EC_GROUP object
580 * \param r EC_POINT object for the result (r = a + b)
581 * \param a EC_POINT object with the first summand
582 * \param b EC_POINT object with the second summand
583 * \param ctx BN_CTX object (optional)
584 * \return 1 on success and 0 if an error occured
585 */
586int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
587
588/** Computes the double of a EC_POINT
589 * \param group underlying EC_GROUP object
590 * \param r EC_POINT object for the result (r = 2 * a)
591 * \param a EC_POINT object
592 * \param ctx BN_CTX object (optional)
593 * \return 1 on success and 0 if an error occured
594 */
595int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
596
597/** Computes the inverse of a EC_POINT
598 * \param group underlying EC_GROUP object
599 * \param a EC_POINT object to be inverted (it's used for the result as well)
600 * \param ctx BN_CTX object (optional)
601 * \return 1 on success and 0 if an error occured
602 */
603int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
604
605/** Checks whether the point is the neutral element of the group
606 * \param group the underlying EC_GROUP object
607 * \param p EC_POINT object
608 * \return 1 if the point is the neutral element and 0 otherwise
609 */
610int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
611
612/** Checks whether the point is on the curve
613 * \param group underlying EC_GROUP object
614 * \param point EC_POINT object to check
615 * \param ctx BN_CTX object (optional)
616 * \return 1 if point if on the curve and 0 otherwise
617 */
618int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
619
620/** Compares two EC_POINTs
621 * \param group underlying EC_GROUP object
622 * \param a first EC_POINT object
623 * \param b second EC_POINT object
624 * \param ctx BN_CTX object (optional)
625 * \return 0 if both points are equal and a value != 0 otherwise
626 */
627int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
628
629int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
630int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
631
632/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
633 * \param group underlying EC_GROUP object
634 * \param r EC_POINT object for the result
635 * \param n BIGNUM with the multiplier for the group generator (optional)
636 * \param num number futher summands
637 * \param p array of size num of EC_POINT objects
638 * \param m array of size num of BIGNUM objects
639 * \param ctx BN_CTX object (optional)
640 * \return 1 on success and 0 if an error occured
641 */
642int 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);
643
644/** Computes r = generator * n + q * m
645 * \param group underlying EC_GROUP object
646 * \param r EC_POINT object for the result
647 * \param n BIGNUM with the multiplier for the group generator (optional)
648 * \param q EC_POINT object with the first factor of the second summand
649 * \param m BIGNUM with the second factor of the second summand
650 * \param ctx BN_CTX object (optional)
651 * \return 1 on success and 0 if an error occured
652 */
653int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
654
655/** Stores multiples of generator for faster point multiplication
656 * \param group EC_GROUP object
657 * \param ctx BN_CTX object (optional)
658 * \return 1 on success and 0 if an error occured
659 */
660int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
661
662/** Reports whether a precomputation has been done
663 * \param group EC_GROUP object
664 * \return 1 if a pre-computation has been done and 0 otherwise
665 */
666int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
667
668
669/********************************************************************/
670/* ASN1 stuff */
671/********************************************************************/
672
673/* EC_GROUP_get_basis_type() returns the NID of the basis type
674 * used to represent the field elements */
675int EC_GROUP_get_basis_type(const EC_GROUP *);
676#ifndef OPENSSL_NO_EC2M
677int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
678int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
679 unsigned int *k2, unsigned int *k3);
680#endif
681
682#define OPENSSL_EC_NAMED_CURVE 0x001
683
684typedef struct ecpk_parameters_st ECPKPARAMETERS;
685
686EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
687int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
688
689#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
690#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
691#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
692 (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
693#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
694 (unsigned char *)(x))
695
696#ifndef OPENSSL_NO_BIO
697int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
698#endif
699#ifndef OPENSSL_NO_FP_API
700int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
701#endif
702
703
704/********************************************************************/
705/* EC_KEY functions */
706/********************************************************************/
707
708typedef struct ec_key_st EC_KEY;
709
710/* some values for the encoding_flag */
711#define EC_PKEY_NO_PARAMETERS 0x001
712#define EC_PKEY_NO_PUBKEY 0x002
713
714/* some values for the flags field */
715#define EC_FLAG_NON_FIPS_ALLOW 0x1
716#define EC_FLAG_FIPS_CHECKED 0x2
717
718/** Creates a new EC_KEY object.
719 * \return EC_KEY object or NULL if an error occurred.
720 */
721EC_KEY *EC_KEY_new(void);
722
723int EC_KEY_get_flags(const EC_KEY *key);
724
725void EC_KEY_set_flags(EC_KEY *key, int flags);
726
727void EC_KEY_clear_flags(EC_KEY *key, int flags);
728
729/** Creates a new EC_KEY object using a named curve as underlying
730 * EC_GROUP object.
731 * \param nid NID of the named curve.
732 * \return EC_KEY object or NULL if an error occurred.
733 */
734EC_KEY *EC_KEY_new_by_curve_name(int nid);
735
736/** Frees a EC_KEY object.
737 * \param key EC_KEY object to be freed.
738 */
739void EC_KEY_free(EC_KEY *key);
740
741/** Copies a EC_KEY object.
742 * \param dst destination EC_KEY object
743 * \param src src EC_KEY object
744 * \return dst or NULL if an error occurred.
745 */
746EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
747
748/** Creates a new EC_KEY object and copies the content from src to it.
749 * \param src the source EC_KEY object
750 * \return newly created EC_KEY object or NULL if an error occurred.
751 */
752EC_KEY *EC_KEY_dup(const EC_KEY *src);
753
754/** Increases the internal reference count of a EC_KEY object.
755 * \param key EC_KEY object
756 * \return 1 on success and 0 if an error occurred.
757 */
758int EC_KEY_up_ref(EC_KEY *key);
759
760/** Returns the EC_GROUP object of a EC_KEY object
761 * \param key EC_KEY object
762 * \return the EC_GROUP object (possibly NULL).
763 */
764const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
765
766/** Sets the EC_GROUP of a EC_KEY object.
767 * \param key EC_KEY object
768 * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY
769 * object will use an own copy of the EC_GROUP).
770 * \return 1 on success and 0 if an error occurred.
771 */
772int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
773
774/** Returns the private key of a EC_KEY object.
775 * \param key EC_KEY object
776 * \return a BIGNUM with the private key (possibly NULL).
777 */
778const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
779
780/** Sets the private key of a EC_KEY object.
781 * \param key EC_KEY object
782 * \param prv BIGNUM with the private key (note: the EC_KEY object
783 * will use an own copy of the BIGNUM).
784 * \return 1 on success and 0 if an error occurred.
785 */
786int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
787
788/** Returns the public key of a EC_KEY object.
789 * \param key the EC_KEY object
790 * \return a EC_POINT object with the public key (possibly NULL)
791 */
792const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
793
794/** Sets the public key of a EC_KEY object.
795 * \param key EC_KEY object
796 * \param pub EC_POINT object with the public key (note: the EC_KEY object
797 * will use an own copy of the EC_POINT object).
798 * \return 1 on success and 0 if an error occurred.
799 */
800int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
801
802unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
803void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
804point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
805void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
806/* functions to set/get method specific data */
807void *EC_KEY_get_key_method_data(EC_KEY *,
808 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
809void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
810 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
811/* wrapper functions for the underlying EC_GROUP object */
812void EC_KEY_set_asn1_flag(EC_KEY *, int);
813
814/** Creates a table of pre-computed multiples of the generator to
815 * accelerate further EC_KEY operations.
816 * \param key EC_KEY object
817 * \param ctx BN_CTX object (optional)
818 * \return 1 on success and 0 if an error occurred.
819 */
820int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
821
822/** Creates a new ec private (and optional a new public) key.
823 * \param key EC_KEY object
824 * \return 1 on success and 0 if an error occurred.
825 */
826int EC_KEY_generate_key(EC_KEY *key);
827
828/** Verifies that a private and/or public key is valid.
829 * \param key the EC_KEY object
830 * \return 1 on success and 0 otherwise.
831 */
832int EC_KEY_check_key(const EC_KEY *key);
833
834/** Sets a public key from affine coordindates performing
835 * neccessary NIST PKV tests.
836 * \param key the EC_KEY object
837 * \param x public key x coordinate
838 * \param y public key y coordinate
839 * \return 1 on success and 0 otherwise.
840 */
841int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
842
843
844/********************************************************************/
845/* de- and encoding functions for SEC1 ECPrivateKey */
846/********************************************************************/
847
848/** Decodes a private key from a memory buffer.
849 * \param key a pointer to a EC_KEY object which should be used (or NULL)
850 * \param in pointer to memory with the DER encoded private key
851 * \param len length of the DER encoded private key
852 * \return the decoded private key or NULL if an error occurred.
853 */
854EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
855
856/** Encodes a private key object and stores the result in a buffer.
857 * \param key the EC_KEY object to encode
858 * \param out the buffer for the result (if NULL the function returns number
859 * of bytes needed).
860 * \return 1 on success and 0 if an error occurred.
861 */
862int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
863
864
865/********************************************************************/
866/* de- and encoding functions for EC parameters */
867/********************************************************************/
868
869/** Decodes ec parameter from a memory buffer.
870 * \param key a pointer to a EC_KEY object which should be used (or NULL)
871 * \param in pointer to memory with the DER encoded ec parameters
872 * \param len length of the DER encoded ec parameters
873 * \return a EC_KEY object with the decoded parameters or NULL if an error
874 * occurred.
875 */
876EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
877
878/** Encodes ec parameter and stores the result in a buffer.
879 * \param key the EC_KEY object with ec paramters to encode
880 * \param out the buffer for the result (if NULL the function returns number
881 * of bytes needed).
882 * \return 1 on success and 0 if an error occurred.
883 */
884int i2d_ECParameters(EC_KEY *key, unsigned char **out);
885
886
887/********************************************************************/
888/* de- and encoding functions for EC public key */
889/* (octet string, not DER -- hence 'o2i' and 'i2o') */
890/********************************************************************/
891
892/** Decodes a ec public key from a octet string.
893 * \param key a pointer to a EC_KEY object which should be used
894 * \param in memory buffer with the encoded public key
895 * \param len length of the encoded public key
896 * \return EC_KEY object with decoded public key or NULL if an error
897 * occurred.
898 */
899EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
900
901/** Encodes a ec public key in an octet string.
902 * \param key the EC_KEY object with the public key
903 * \param out the buffer for the result (if NULL the function returns number
904 * of bytes needed).
905 * \return 1 on success and 0 if an error occurred
906 */
907int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
908
909#ifndef OPENSSL_NO_BIO
910/** Prints out the ec parameters on human readable form.
911 * \param bp BIO object to which the information is printed
912 * \param key EC_KEY object
913 * \return 1 on success and 0 if an error occurred
914 */
915int ECParameters_print(BIO *bp, const EC_KEY *key);
916
917/** Prints out the contents of a EC_KEY object
918 * \param bp BIO object to which the information is printed
919 * \param key EC_KEY object
920 * \param off line offset
921 * \return 1 on success and 0 if an error occurred
922 */
923int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
924
925#endif
926#ifndef OPENSSL_NO_FP_API
927/** Prints out the ec parameters on human readable form.
928 * \param fp file descriptor to which the information is printed
929 * \param key EC_KEY object
930 * \return 1 on success and 0 if an error occurred
931 */
932int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
933
934/** Prints out the contents of a EC_KEY object
935 * \param fp file descriptor to which the information is printed
936 * \param key EC_KEY object
937 * \param off line offset
938 * \return 1 on success and 0 if an error occurred
939 */
940int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
941
942#endif
943
944#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
945
946#ifndef __cplusplus
947#if defined(__SUNPRO_C)
948# if __SUNPRO_C >= 0x520
949# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
950# endif
951# endif
952#endif
953
954#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
955 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
956 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
957
958
959#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
960
961/* BEGIN ERROR CODES */
962/* The following lines are auto generated by the script mkerr.pl. Any changes
963 * made after this point may be overwritten when the script is next run.
964 */
965void ERR_load_EC_strings(void);
966
967/* Error codes for the EC functions. */
968
969/* Function codes. */
970#define EC_F_BN_TO_FELEM 224
971#define EC_F_COMPUTE_WNAF 143
972#define EC_F_D2I_ECPARAMETERS 144
973#define EC_F_D2I_ECPKPARAMETERS 145
974#define EC_F_D2I_ECPRIVATEKEY 146
975#define EC_F_DO_EC_KEY_PRINT 221
976#define EC_F_ECKEY_PARAM2TYPE 223
977#define EC_F_ECKEY_PARAM_DECODE 212
978#define EC_F_ECKEY_PRIV_DECODE 213
979#define EC_F_ECKEY_PRIV_ENCODE 214
980#define EC_F_ECKEY_PUB_DECODE 215
981#define EC_F_ECKEY_PUB_ENCODE 216
982#define EC_F_ECKEY_TYPE2PARAM 220
983#define EC_F_ECPARAMETERS_PRINT 147
984#define EC_F_ECPARAMETERS_PRINT_FP 148
985#define EC_F_ECPKPARAMETERS_PRINT 149
986#define EC_F_ECPKPARAMETERS_PRINT_FP 150
987#define EC_F_ECP_NIST_MOD_192 203
988#define EC_F_ECP_NIST_MOD_224 204
989#define EC_F_ECP_NIST_MOD_256 205
990#define EC_F_ECP_NIST_MOD_521 206
991#define EC_F_EC_ASN1_GROUP2CURVE 153
992#define EC_F_EC_ASN1_GROUP2FIELDID 154
993#define EC_F_EC_ASN1_GROUP2PARAMETERS 155
994#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156
995#define EC_F_EC_ASN1_PARAMETERS2GROUP 157
996#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158
997#define EC_F_EC_EX_DATA_SET_DATA 211
998#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208
999#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159
1000#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195
1001#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160
1002#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161
1003#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
1004#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
1005#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164
1006#define EC_F_EC_GFP_MONT_FIELD_DECODE 133
1007#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
1008#define EC_F_EC_GFP_MONT_FIELD_MUL 131
1009#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209
1010#define EC_F_EC_GFP_MONT_FIELD_SQR 132
1011#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
1012#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
1013#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225
1014#define EC_F_EC_GFP_NISTP224_POINTS_MUL 228
1015#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
1016#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230
1017#define EC_F_EC_GFP_NISTP256_POINTS_MUL 231
1018#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
1019#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233
1020#define EC_F_EC_GFP_NISTP521_POINTS_MUL 234
1021#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
1022#define EC_F_EC_GFP_NIST_FIELD_MUL 200
1023#define EC_F_EC_GFP_NIST_FIELD_SQR 201
1024#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
1025#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
1026#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
1027#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
1028#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
1029#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
1030#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
1031#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
1032#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
1033#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167
1034#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
1035#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168
1036#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
1037#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169
1038#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
1039#define EC_F_EC_GROUP_CHECK 170
1040#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171
1041#define EC_F_EC_GROUP_COPY 106
1042#define EC_F_EC_GROUP_GET0_GENERATOR 139
1043#define EC_F_EC_GROUP_GET_COFACTOR 140
1044#define EC_F_EC_GROUP_GET_CURVE_GF2M 172
1045#define EC_F_EC_GROUP_GET_CURVE_GFP 130
1046#define EC_F_EC_GROUP_GET_DEGREE 173
1047#define EC_F_EC_GROUP_GET_ORDER 141
1048#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193
1049#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194
1050#define EC_F_EC_GROUP_NEW 108
1051#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174
1052#define EC_F_EC_GROUP_NEW_FROM_DATA 175
1053#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142
1054#define EC_F_EC_GROUP_SET_CURVE_GF2M 176
1055#define EC_F_EC_GROUP_SET_CURVE_GFP 109
1056#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
1057#define EC_F_EC_GROUP_SET_GENERATOR 111
1058#define EC_F_EC_KEY_CHECK_KEY 177
1059#define EC_F_EC_KEY_COPY 178
1060#define EC_F_EC_KEY_GENERATE_KEY 179
1061#define EC_F_EC_KEY_NEW 182
1062#define EC_F_EC_KEY_PRINT 180
1063#define EC_F_EC_KEY_PRINT_FP 181
1064#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229
1065#define EC_F_EC_POINTS_MAKE_AFFINE 136
1066#define EC_F_EC_POINT_ADD 112
1067#define EC_F_EC_POINT_CMP 113
1068#define EC_F_EC_POINT_COPY 114
1069#define EC_F_EC_POINT_DBL 115
1070#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183
1071#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116
1072#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117
1073#define EC_F_EC_POINT_INVERT 210
1074#define EC_F_EC_POINT_IS_AT_INFINITY 118
1075#define EC_F_EC_POINT_IS_ON_CURVE 119
1076#define EC_F_EC_POINT_MAKE_AFFINE 120
1077#define EC_F_EC_POINT_MUL 184
1078#define EC_F_EC_POINT_NEW 121
1079#define EC_F_EC_POINT_OCT2POINT 122
1080#define EC_F_EC_POINT_POINT2OCT 123
1081#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185
1082#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124
1083#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186
1084#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125
1085#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126
1086#define EC_F_EC_POINT_SET_TO_INFINITY 127
1087#define EC_F_EC_PRE_COMP_DUP 207
1088#define EC_F_EC_PRE_COMP_NEW 196
1089#define EC_F_EC_WNAF_MUL 187
1090#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
1091#define EC_F_I2D_ECPARAMETERS 190
1092#define EC_F_I2D_ECPKPARAMETERS 191
1093#define EC_F_I2D_ECPRIVATEKEY 192
1094#define EC_F_I2O_ECPUBLICKEY 151
1095#define EC_F_NISTP224_PRE_COMP_NEW 227
1096#define EC_F_NISTP256_PRE_COMP_NEW 236
1097#define EC_F_NISTP521_PRE_COMP_NEW 237
1098#define EC_F_O2I_ECPUBLICKEY 152
1099#define EC_F_OLD_EC_PRIV_DECODE 222
1100#define EC_F_PKEY_EC_CTRL 197
1101#define EC_F_PKEY_EC_CTRL_STR 198
1102#define EC_F_PKEY_EC_DERIVE 217
1103#define EC_F_PKEY_EC_KEYGEN 199
1104#define EC_F_PKEY_EC_PARAMGEN 219
1105#define EC_F_PKEY_EC_SIGN 218
1106
1107/* Reason codes. */
1108#define EC_R_ASN1_ERROR 115
1109#define EC_R_ASN1_UNKNOWN_FIELD 116
1110#define EC_R_BIGNUM_OUT_OF_RANGE 144
1111#define EC_R_BUFFER_TOO_SMALL 100
1112#define EC_R_COORDINATES_OUT_OF_RANGE 146
1113#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
1114#define EC_R_DECODE_ERROR 142
1115#define EC_R_DISCRIMINANT_IS_ZERO 118
1116#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
1117#define EC_R_FIELD_TOO_LARGE 143
1118#define EC_R_GF2M_NOT_SUPPORTED 147
1119#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
1120#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
1121#define EC_R_INCOMPATIBLE_OBJECTS 101
1122#define EC_R_INVALID_ARGUMENT 112
1123#define EC_R_INVALID_COMPRESSED_POINT 110
1124#define EC_R_INVALID_COMPRESSION_BIT 109
1125#define EC_R_INVALID_CURVE 141
1126#define EC_R_INVALID_DIGEST_TYPE 138
1127#define EC_R_INVALID_ENCODING 102
1128#define EC_R_INVALID_FIELD 103
1129#define EC_R_INVALID_FORM 104
1130#define EC_R_INVALID_GROUP_ORDER 122
1131#define EC_R_INVALID_PENTANOMIAL_BASIS 132
1132#define EC_R_INVALID_PRIVATE_KEY 123
1133#define EC_R_INVALID_TRINOMIAL_BASIS 137
1134#define EC_R_KEYS_NOT_SET 140
1135#define EC_R_MISSING_PARAMETERS 124
1136#define EC_R_MISSING_PRIVATE_KEY 125
1137#define EC_R_NOT_A_NIST_PRIME 135
1138#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136
1139#define EC_R_NOT_IMPLEMENTED 126
1140#define EC_R_NOT_INITIALIZED 111
1141#define EC_R_NO_FIELD_MOD 133
1142#define EC_R_NO_PARAMETERS_SET 139
1143#define EC_R_PASSED_NULL_PARAMETER 134
1144#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
1145#define EC_R_POINT_AT_INFINITY 106
1146#define EC_R_POINT_IS_NOT_ON_CURVE 107
1147#define EC_R_SLOT_FULL 108
1148#define EC_R_UNDEFINED_GENERATOR 113
1149#define EC_R_UNDEFINED_ORDER 128
1150#define EC_R_UNKNOWN_GROUP 129
1151#define EC_R_UNKNOWN_ORDER 114
1152#define EC_R_UNSUPPORTED_FIELD 131
1153#define EC_R_WRONG_CURVE_PARAMETERS 145
1154#define EC_R_WRONG_ORDER 130
1155
1156#ifdef __cplusplus
1157}
1158#endif
1159#endif
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
deleted file mode 100644
index 26f4a783fc..0000000000
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ /dev/null
@@ -1,390 +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#ifndef OPENSSL_NO_EC2M
75
76
77/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
78 * coordinates.
79 * Uses algorithm Mdouble in appendix of
80 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
81 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
82 * modified to not require precomputation of c=b^{2^{m-1}}.
83 */
84static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
85 {
86 BIGNUM *t1;
87 int ret = 0;
88
89 /* Since Mdouble is static we can guarantee that ctx != NULL. */
90 BN_CTX_start(ctx);
91 t1 = BN_CTX_get(ctx);
92 if (t1 == NULL) goto err;
93
94 if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
95 if (!group->meth->field_sqr(group, t1, z, ctx)) goto err;
96 if (!group->meth->field_mul(group, z, x, t1, ctx)) goto err;
97 if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
98 if (!group->meth->field_sqr(group, t1, t1, ctx)) goto err;
99 if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) goto err;
100 if (!BN_GF2m_add(x, x, t1)) goto err;
101
102 ret = 1;
103
104 err:
105 BN_CTX_end(ctx);
106 return ret;
107 }
108
109/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
110 * projective coordinates.
111 * Uses algorithm Madd in appendix of
112 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
113 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
114 */
115static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1,
116 const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
117 {
118 BIGNUM *t1, *t2;
119 int ret = 0;
120
121 /* Since Madd is static we can guarantee that ctx != NULL. */
122 BN_CTX_start(ctx);
123 t1 = BN_CTX_get(ctx);
124 t2 = BN_CTX_get(ctx);
125 if (t2 == NULL) goto err;
126
127 if (!BN_copy(t1, x)) goto err;
128 if (!group->meth->field_mul(group, x1, x1, z2, ctx)) goto err;
129 if (!group->meth->field_mul(group, z1, z1, x2, ctx)) goto err;
130 if (!group->meth->field_mul(group, t2, x1, z1, ctx)) goto err;
131 if (!BN_GF2m_add(z1, z1, x1)) goto err;
132 if (!group->meth->field_sqr(group, z1, z1, ctx)) goto err;
133 if (!group->meth->field_mul(group, x1, z1, t1, ctx)) goto err;
134 if (!BN_GF2m_add(x1, x1, t2)) goto err;
135
136 ret = 1;
137
138 err:
139 BN_CTX_end(ctx);
140 return ret;
141 }
142
143/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
144 * using Montgomery point multiplication algorithm Mxy() in appendix of
145 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
146 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
147 * Returns:
148 * 0 on error
149 * 1 if return value should be the point at infinity
150 * 2 otherwise
151 */
152static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1,
153 BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
154 {
155 BIGNUM *t3, *t4, *t5;
156 int ret = 0;
157
158 if (BN_is_zero(z1))
159 {
160 BN_zero(x2);
161 BN_zero(z2);
162 return 1;
163 }
164
165 if (BN_is_zero(z2))
166 {
167 if (!BN_copy(x2, x)) return 0;
168 if (!BN_GF2m_add(z2, x, y)) return 0;
169 return 2;
170 }
171
172 /* Since Mxy is static we can guarantee that ctx != NULL. */
173 BN_CTX_start(ctx);
174 t3 = BN_CTX_get(ctx);
175 t4 = BN_CTX_get(ctx);
176 t5 = BN_CTX_get(ctx);
177 if (t5 == NULL) goto err;
178
179 if (!BN_one(t5)) goto err;
180
181 if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err;
182
183 if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err;
184 if (!BN_GF2m_add(z1, z1, x1)) goto err;
185 if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err;
186 if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err;
187 if (!BN_GF2m_add(z2, z2, x2)) goto err;
188
189 if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err;
190 if (!group->meth->field_sqr(group, t4, x, ctx)) goto err;
191 if (!BN_GF2m_add(t4, t4, y)) goto err;
192 if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err;
193 if (!BN_GF2m_add(t4, t4, z2)) goto err;
194
195 if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err;
196 if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err;
197 if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err;
198 if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err;
199 if (!BN_GF2m_add(z2, x2, x)) goto err;
200
201 if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err;
202 if (!BN_GF2m_add(z2, z2, y)) goto err;
203
204 ret = 2;
205
206 err:
207 BN_CTX_end(ctx);
208 return ret;
209 }
210
211/* Computes scalar*point and stores the result in r.
212 * point can not equal r.
213 * Uses algorithm 2P of
214 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
215 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
216 */
217static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
218 const EC_POINT *point, BN_CTX *ctx)
219 {
220 BIGNUM *x1, *x2, *z1, *z2;
221 int ret = 0, i;
222 BN_ULONG mask,word;
223
224 if (r == point)
225 {
226 ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
227 return 0;
228 }
229
230 /* if result should be point at infinity */
231 if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
232 EC_POINT_is_at_infinity(group, point))
233 {
234 return EC_POINT_set_to_infinity(group, r);
235 }
236
237 /* only support affine coordinates */
238 if (!point->Z_is_one) return 0;
239
240 /* Since point_multiply is static we can guarantee that ctx != NULL. */
241 BN_CTX_start(ctx);
242 x1 = BN_CTX_get(ctx);
243 z1 = BN_CTX_get(ctx);
244 if (z1 == NULL) goto err;
245
246 x2 = &r->X;
247 z2 = &r->Y;
248
249 if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
250 if (!BN_one(z1)) goto err; /* z1 = 1 */
251 if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
252 if (!group->meth->field_sqr(group, x2, z2, ctx)) goto err;
253 if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */
254
255 /* find top most bit and go one past it */
256 i = scalar->top - 1;
257 mask = BN_TBIT;
258 word = scalar->d[i];
259 while (!(word & mask)) mask >>= 1;
260 mask >>= 1;
261 /* if top most bit was at word break, go to next word */
262 if (!mask)
263 {
264 i--;
265 mask = BN_TBIT;
266 }
267
268 for (; i >= 0; i--)
269 {
270 word = scalar->d[i];
271 while (mask)
272 {
273 if (word & mask)
274 {
275 if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
276 if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
277 }
278 else
279 {
280 if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
281 if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
282 }
283 mask >>= 1;
284 }
285 mask = BN_TBIT;
286 }
287
288 /* convert out of "projective" coordinates */
289 i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
290 if (i == 0) goto err;
291 else if (i == 1)
292 {
293 if (!EC_POINT_set_to_infinity(group, r)) goto err;
294 }
295 else
296 {
297 if (!BN_one(&r->Z)) goto err;
298 r->Z_is_one = 1;
299 }
300
301 /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
302 BN_set_negative(&r->X, 0);
303 BN_set_negative(&r->Y, 0);
304
305 ret = 1;
306
307 err:
308 BN_CTX_end(ctx);
309 return ret;
310 }
311
312
313/* Computes the sum
314 * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
315 * gracefully ignoring NULL scalar values.
316 */
317int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
318 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
319 {
320 BN_CTX *new_ctx = NULL;
321 int ret = 0;
322 size_t i;
323 EC_POINT *p=NULL;
324 EC_POINT *acc = NULL;
325
326 if (ctx == NULL)
327 {
328 ctx = new_ctx = BN_CTX_new();
329 if (ctx == NULL)
330 return 0;
331 }
332
333 /* This implementation is more efficient than the wNAF implementation for 2
334 * or fewer points. Use the ec_wNAF_mul implementation for 3 or more points,
335 * or if we can perform a fast multiplication based on precomputation.
336 */
337 if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group)))
338 {
339 ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
340 goto err;
341 }
342
343 if ((p = EC_POINT_new(group)) == NULL) goto err;
344 if ((acc = EC_POINT_new(group)) == NULL) goto err;
345
346 if (!EC_POINT_set_to_infinity(group, acc)) goto err;
347
348 if (scalar)
349 {
350 if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
351 if (BN_is_negative(scalar))
352 if (!group->meth->invert(group, p, ctx)) goto err;
353 if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
354 }
355
356 for (i = 0; i < num; i++)
357 {
358 if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
359 if (BN_is_negative(scalars[i]))
360 if (!group->meth->invert(group, p, ctx)) goto err;
361 if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
362 }
363
364 if (!EC_POINT_copy(r, acc)) goto err;
365
366 ret = 1;
367
368 err:
369 if (p) EC_POINT_free(p);
370 if (acc) EC_POINT_free(acc);
371 if (new_ctx != NULL)
372 BN_CTX_free(new_ctx);
373 return ret;
374 }
375
376
377/* Precomputation for point multiplication: fall back to wNAF methods
378 * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
379
380int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
381 {
382 return ec_wNAF_precompute_mult(group, ctx);
383 }
384
385int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
386 {
387 return ec_wNAF_have_precompute_mult(group);
388 }
389
390#endif
diff --git a/src/lib/libcrypto/ec/ec2_oct.c b/src/lib/libcrypto/ec/ec2_oct.c
deleted file mode 100644
index f1d75e5ddf..0000000000
--- a/src/lib/libcrypto/ec/ec2_oct.c
+++ /dev/null
@@ -1,407 +0,0 @@
1/* crypto/ec/ec2_oct.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#ifndef OPENSSL_NO_EC2M
75
76/* Calculates and sets the affine coordinates of an EC_POINT from the given
77 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
78 * Note that the simple implementation only uses affine coordinates.
79 *
80 * The method is from the following publication:
81 *
82 * Harper, Menezes, Vanstone:
83 * "Public-Key Cryptosystems with Very Small Key Lengths",
84 * EUROCRYPT '92, Springer-Verlag LNCS 658,
85 * published February 1993
86 *
87 * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
88 * the same method, but claim no priority date earlier than July 29, 1994
89 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
90 */
91int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
92 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
93 {
94 BN_CTX *new_ctx = NULL;
95 BIGNUM *tmp, *x, *y, *z;
96 int ret = 0, z0;
97
98 /* clear error queue */
99 ERR_clear_error();
100
101 if (ctx == NULL)
102 {
103 ctx = new_ctx = BN_CTX_new();
104 if (ctx == NULL)
105 return 0;
106 }
107
108 y_bit = (y_bit != 0) ? 1 : 0;
109
110 BN_CTX_start(ctx);
111 tmp = BN_CTX_get(ctx);
112 x = BN_CTX_get(ctx);
113 y = BN_CTX_get(ctx);
114 z = BN_CTX_get(ctx);
115 if (z == NULL) goto err;
116
117 if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
118 if (BN_is_zero(x))
119 {
120 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
121 }
122 else
123 {
124 if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
125 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
126 if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
127 if (!BN_GF2m_add(tmp, x, tmp)) goto err;
128 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
129 {
130 unsigned long err = ERR_peek_last_error();
131
132 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
133 {
134 ERR_clear_error();
135 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
136 }
137 else
138 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
139 goto err;
140 }
141 z0 = (BN_is_odd(z)) ? 1 : 0;
142 if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
143 if (z0 != y_bit)
144 {
145 if (!BN_GF2m_add(y, y, x)) goto err;
146 }
147 }
148
149 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
150
151 ret = 1;
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
161/* Converts an EC_POINT to an octet string.
162 * If buf is NULL, the encoded length will be returned.
163 * If the length len of buf is smaller than required an error will be returned.
164 */
165size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
166 unsigned char *buf, size_t len, BN_CTX *ctx)
167 {
168 size_t ret;
169 BN_CTX *new_ctx = NULL;
170 int used_ctx = 0;
171 BIGNUM *x, *y, *yxi;
172 size_t field_len, i, skip;
173
174 if ((form != POINT_CONVERSION_COMPRESSED)
175 && (form != POINT_CONVERSION_UNCOMPRESSED)
176 && (form != POINT_CONVERSION_HYBRID))
177 {
178 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
179 goto err;
180 }
181
182 if (EC_POINT_is_at_infinity(group, point))
183 {
184 /* encodes to a single 0 octet */
185 if (buf != NULL)
186 {
187 if (len < 1)
188 {
189 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
190 return 0;
191 }
192 buf[0] = 0;
193 }
194 return 1;
195 }
196
197
198 /* ret := required output buffer length */
199 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
200 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
201
202 /* if 'buf' is NULL, just return required length */
203 if (buf != NULL)
204 {
205 if (len < ret)
206 {
207 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
208 goto err;
209 }
210
211 if (ctx == NULL)
212 {
213 ctx = new_ctx = BN_CTX_new();
214 if (ctx == NULL)
215 return 0;
216 }
217
218 BN_CTX_start(ctx);
219 used_ctx = 1;
220 x = BN_CTX_get(ctx);
221 y = BN_CTX_get(ctx);
222 yxi = BN_CTX_get(ctx);
223 if (yxi == NULL) goto err;
224
225 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
226
227 buf[0] = form;
228 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
229 {
230 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
231 if (BN_is_odd(yxi)) buf[0]++;
232 }
233
234 i = 1;
235
236 skip = field_len - BN_num_bytes(x);
237 if (skip > field_len)
238 {
239 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
240 goto err;
241 }
242 while (skip > 0)
243 {
244 buf[i++] = 0;
245 skip--;
246 }
247 skip = BN_bn2bin(x, buf + i);
248 i += skip;
249 if (i != 1 + field_len)
250 {
251 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
252 goto err;
253 }
254
255 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
256 {
257 skip = field_len - BN_num_bytes(y);
258 if (skip > field_len)
259 {
260 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
261 goto err;
262 }
263 while (skip > 0)
264 {
265 buf[i++] = 0;
266 skip--;
267 }
268 skip = BN_bn2bin(y, buf + i);
269 i += skip;
270 }
271
272 if (i != ret)
273 {
274 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
275 goto err;
276 }
277 }
278
279 if (used_ctx)
280 BN_CTX_end(ctx);
281 if (new_ctx != NULL)
282 BN_CTX_free(new_ctx);
283 return ret;
284
285 err:
286 if (used_ctx)
287 BN_CTX_end(ctx);
288 if (new_ctx != NULL)
289 BN_CTX_free(new_ctx);
290 return 0;
291 }
292
293
294/* Converts an octet string representation to an EC_POINT.
295 * Note that the simple implementation only uses affine coordinates.
296 */
297int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
298 const unsigned char *buf, size_t len, BN_CTX *ctx)
299 {
300 point_conversion_form_t form;
301 int y_bit;
302 BN_CTX *new_ctx = NULL;
303 BIGNUM *x, *y, *yxi;
304 size_t field_len, enc_len;
305 int ret = 0;
306
307 if (len == 0)
308 {
309 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
310 return 0;
311 }
312 form = buf[0];
313 y_bit = form & 1;
314 form = form & ~1U;
315 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
316 && (form != POINT_CONVERSION_UNCOMPRESSED)
317 && (form != POINT_CONVERSION_HYBRID))
318 {
319 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
320 return 0;
321 }
322 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
323 {
324 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
325 return 0;
326 }
327
328 if (form == 0)
329 {
330 if (len != 1)
331 {
332 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
333 return 0;
334 }
335
336 return EC_POINT_set_to_infinity(group, point);
337 }
338
339 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
340 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
341
342 if (len != enc_len)
343 {
344 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
345 return 0;
346 }
347
348 if (ctx == NULL)
349 {
350 ctx = new_ctx = BN_CTX_new();
351 if (ctx == NULL)
352 return 0;
353 }
354
355 BN_CTX_start(ctx);
356 x = BN_CTX_get(ctx);
357 y = BN_CTX_get(ctx);
358 yxi = BN_CTX_get(ctx);
359 if (yxi == NULL) goto err;
360
361 if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
362 if (BN_ucmp(x, &group->field) >= 0)
363 {
364 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
365 goto err;
366 }
367
368 if (form == POINT_CONVERSION_COMPRESSED)
369 {
370 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
371 }
372 else
373 {
374 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
375 if (BN_ucmp(y, &group->field) >= 0)
376 {
377 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
378 goto err;
379 }
380 if (form == POINT_CONVERSION_HYBRID)
381 {
382 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
383 if (y_bit != BN_is_odd(yxi))
384 {
385 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
386 goto err;
387 }
388 }
389
390 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
391 }
392
393 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
394 {
395 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
396 goto err;
397 }
398
399 ret = 1;
400
401 err:
402 BN_CTX_end(ctx);
403 if (new_ctx != NULL)
404 BN_CTX_free(new_ctx);
405 return ret;
406 }
407#endif
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
deleted file mode 100644
index e0e59c7d82..0000000000
--- a/src/lib/libcrypto/ec/ec2_smpl.c
+++ /dev/null
@@ -1,719 +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#ifndef OPENSSL_NO_EC2M
75
76#ifdef OPENSSL_FIPS
77#include <openssl/fips.h>
78#endif
79
80
81const EC_METHOD *EC_GF2m_simple_method(void)
82 {
83#ifdef OPENSSL_FIPS
84 return fips_ec_gf2m_simple_method();
85#else
86 static const EC_METHOD ret = {
87 EC_FLAGS_DEFAULT_OCT,
88 NID_X9_62_characteristic_two_field,
89 ec_GF2m_simple_group_init,
90 ec_GF2m_simple_group_finish,
91 ec_GF2m_simple_group_clear_finish,
92 ec_GF2m_simple_group_copy,
93 ec_GF2m_simple_group_set_curve,
94 ec_GF2m_simple_group_get_curve,
95 ec_GF2m_simple_group_get_degree,
96 ec_GF2m_simple_group_check_discriminant,
97 ec_GF2m_simple_point_init,
98 ec_GF2m_simple_point_finish,
99 ec_GF2m_simple_point_clear_finish,
100 ec_GF2m_simple_point_copy,
101 ec_GF2m_simple_point_set_to_infinity,
102 0 /* set_Jprojective_coordinates_GFp */,
103 0 /* get_Jprojective_coordinates_GFp */,
104 ec_GF2m_simple_point_set_affine_coordinates,
105 ec_GF2m_simple_point_get_affine_coordinates,
106 0,0,0,
107 ec_GF2m_simple_add,
108 ec_GF2m_simple_dbl,
109 ec_GF2m_simple_invert,
110 ec_GF2m_simple_is_at_infinity,
111 ec_GF2m_simple_is_on_curve,
112 ec_GF2m_simple_cmp,
113 ec_GF2m_simple_make_affine,
114 ec_GF2m_simple_points_make_affine,
115
116 /* the following three method functions are defined in ec2_mult.c */
117 ec_GF2m_simple_mul,
118 ec_GF2m_precompute_mult,
119 ec_GF2m_have_precompute_mult,
120
121 ec_GF2m_simple_field_mul,
122 ec_GF2m_simple_field_sqr,
123 ec_GF2m_simple_field_div,
124 0 /* field_encode */,
125 0 /* field_decode */,
126 0 /* field_set_to_one */ };
127
128 return &ret;
129#endif
130 }
131
132
133/* Initialize a GF(2^m)-based EC_GROUP structure.
134 * Note that all other members are handled by EC_GROUP_new.
135 */
136int ec_GF2m_simple_group_init(EC_GROUP *group)
137 {
138 BN_init(&group->field);
139 BN_init(&group->a);
140 BN_init(&group->b);
141 return 1;
142 }
143
144
145/* Free a GF(2^m)-based EC_GROUP structure.
146 * Note that all other members are handled by EC_GROUP_free.
147 */
148void ec_GF2m_simple_group_finish(EC_GROUP *group)
149 {
150 BN_free(&group->field);
151 BN_free(&group->a);
152 BN_free(&group->b);
153 }
154
155
156/* Clear and free a GF(2^m)-based EC_GROUP structure.
157 * Note that all other members are handled by EC_GROUP_clear_free.
158 */
159void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
160 {
161 BN_clear_free(&group->field);
162 BN_clear_free(&group->a);
163 BN_clear_free(&group->b);
164 group->poly[0] = 0;
165 group->poly[1] = 0;
166 group->poly[2] = 0;
167 group->poly[3] = 0;
168 group->poly[4] = 0;
169 group->poly[5] = -1;
170 }
171
172
173/* Copy a GF(2^m)-based EC_GROUP structure.
174 * Note that all other members are handled by EC_GROUP_copy.
175 */
176int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
177 {
178 int i;
179 if (!BN_copy(&dest->field, &src->field)) return 0;
180 if (!BN_copy(&dest->a, &src->a)) return 0;
181 if (!BN_copy(&dest->b, &src->b)) return 0;
182 dest->poly[0] = src->poly[0];
183 dest->poly[1] = src->poly[1];
184 dest->poly[2] = src->poly[2];
185 dest->poly[3] = src->poly[3];
186 dest->poly[4] = src->poly[4];
187 dest->poly[5] = src->poly[5];
188 if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
189 if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
190 for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
191 for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
192 return 1;
193 }
194
195
196/* Set the curve parameters of an EC_GROUP structure. */
197int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
198 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
199 {
200 int ret = 0, i;
201
202 /* group->field */
203 if (!BN_copy(&group->field, p)) goto err;
204 i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
205 if ((i != 5) && (i != 3))
206 {
207 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
208 goto err;
209 }
210
211 /* group->a */
212 if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
213 if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
214 for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
215
216 /* group->b */
217 if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
218 if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
219 for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
220
221 ret = 1;
222 err:
223 return ret;
224 }
225
226
227/* Get the curve parameters of an EC_GROUP structure.
228 * If p, a, or b are NULL then there values will not be set but the method will return with success.
229 */
230int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
231 {
232 int ret = 0;
233
234 if (p != NULL)
235 {
236 if (!BN_copy(p, &group->field)) return 0;
237 }
238
239 if (a != NULL)
240 {
241 if (!BN_copy(a, &group->a)) goto err;
242 }
243
244 if (b != NULL)
245 {
246 if (!BN_copy(b, &group->b)) goto err;
247 }
248
249 ret = 1;
250
251 err:
252 return ret;
253 }
254
255
256/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */
257int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
258 {
259 return BN_num_bits(&group->field)-1;
260 }
261
262
263/* Checks the discriminant of the curve.
264 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
265 */
266int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
267 {
268 int ret = 0;
269 BIGNUM *b;
270 BN_CTX *new_ctx = NULL;
271
272 if (ctx == NULL)
273 {
274 ctx = new_ctx = BN_CTX_new();
275 if (ctx == NULL)
276 {
277 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
278 goto err;
279 }
280 }
281 BN_CTX_start(ctx);
282 b = BN_CTX_get(ctx);
283 if (b == NULL) goto err;
284
285 if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
286
287 /* check the discriminant:
288 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
289 */
290 if (BN_is_zero(b)) goto err;
291
292 ret = 1;
293
294err:
295 if (ctx != NULL)
296 BN_CTX_end(ctx);
297 if (new_ctx != NULL)
298 BN_CTX_free(new_ctx);
299 return ret;
300 }
301
302
303/* Initializes an EC_POINT. */
304int ec_GF2m_simple_point_init(EC_POINT *point)
305 {
306 BN_init(&point->X);
307 BN_init(&point->Y);
308 BN_init(&point->Z);
309 return 1;
310 }
311
312
313/* Frees an EC_POINT. */
314void ec_GF2m_simple_point_finish(EC_POINT *point)
315 {
316 BN_free(&point->X);
317 BN_free(&point->Y);
318 BN_free(&point->Z);
319 }
320
321
322/* Clears and frees an EC_POINT. */
323void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
324 {
325 BN_clear_free(&point->X);
326 BN_clear_free(&point->Y);
327 BN_clear_free(&point->Z);
328 point->Z_is_one = 0;
329 }
330
331
332/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */
333int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
334 {
335 if (!BN_copy(&dest->X, &src->X)) return 0;
336 if (!BN_copy(&dest->Y, &src->Y)) return 0;
337 if (!BN_copy(&dest->Z, &src->Z)) return 0;
338 dest->Z_is_one = src->Z_is_one;
339
340 return 1;
341 }
342
343
344/* Set an EC_POINT to the point at infinity.
345 * A point at infinity is represented by having Z=0.
346 */
347int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
348 {
349 point->Z_is_one = 0;
350 BN_zero(&point->Z);
351 return 1;
352 }
353
354
355/* Set the coordinates of an EC_POINT using affine coordinates.
356 * Note that the simple implementation only uses affine coordinates.
357 */
358int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
359 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
360 {
361 int ret = 0;
362 if (x == NULL || y == NULL)
363 {
364 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
365 return 0;
366 }
367
368 if (!BN_copy(&point->X, x)) goto err;
369 BN_set_negative(&point->X, 0);
370 if (!BN_copy(&point->Y, y)) goto err;
371 BN_set_negative(&point->Y, 0);
372 if (!BN_copy(&point->Z, BN_value_one())) goto err;
373 BN_set_negative(&point->Z, 0);
374 point->Z_is_one = 1;
375 ret = 1;
376
377 err:
378 return ret;
379 }
380
381
382/* Gets the affine coordinates of an EC_POINT.
383 * Note that the simple implementation only uses affine coordinates.
384 */
385int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
386 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
387 {
388 int ret = 0;
389
390 if (EC_POINT_is_at_infinity(group, point))
391 {
392 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
393 return 0;
394 }
395
396 if (BN_cmp(&point->Z, BN_value_one()))
397 {
398 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
399 return 0;
400 }
401 if (x != NULL)
402 {
403 if (!BN_copy(x, &point->X)) goto err;
404 BN_set_negative(x, 0);
405 }
406 if (y != NULL)
407 {
408 if (!BN_copy(y, &point->Y)) goto err;
409 BN_set_negative(y, 0);
410 }
411 ret = 1;
412
413 err:
414 return ret;
415 }
416
417/* Computes a + b and stores the result in r. r could be a or b, a could be b.
418 * Uses algorithm A.10.2 of IEEE P1363.
419 */
420int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
421 {
422 BN_CTX *new_ctx = NULL;
423 BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
424 int ret = 0;
425
426 if (EC_POINT_is_at_infinity(group, a))
427 {
428 if (!EC_POINT_copy(r, b)) return 0;
429 return 1;
430 }
431
432 if (EC_POINT_is_at_infinity(group, b))
433 {
434 if (!EC_POINT_copy(r, a)) return 0;
435 return 1;
436 }
437
438 if (ctx == NULL)
439 {
440 ctx = new_ctx = BN_CTX_new();
441 if (ctx == NULL)
442 return 0;
443 }
444
445 BN_CTX_start(ctx);
446 x0 = BN_CTX_get(ctx);
447 y0 = BN_CTX_get(ctx);
448 x1 = BN_CTX_get(ctx);
449 y1 = BN_CTX_get(ctx);
450 x2 = BN_CTX_get(ctx);
451 y2 = BN_CTX_get(ctx);
452 s = BN_CTX_get(ctx);
453 t = BN_CTX_get(ctx);
454 if (t == NULL) goto err;
455
456 if (a->Z_is_one)
457 {
458 if (!BN_copy(x0, &a->X)) goto err;
459 if (!BN_copy(y0, &a->Y)) goto err;
460 }
461 else
462 {
463 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
464 }
465 if (b->Z_is_one)
466 {
467 if (!BN_copy(x1, &b->X)) goto err;
468 if (!BN_copy(y1, &b->Y)) goto err;
469 }
470 else
471 {
472 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
473 }
474
475
476 if (BN_GF2m_cmp(x0, x1))
477 {
478 if (!BN_GF2m_add(t, x0, x1)) goto err;
479 if (!BN_GF2m_add(s, y0, y1)) goto err;
480 if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
481 if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
482 if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
483 if (!BN_GF2m_add(x2, x2, s)) goto err;
484 if (!BN_GF2m_add(x2, x2, t)) goto err;
485 }
486 else
487 {
488 if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
489 {
490 if (!EC_POINT_set_to_infinity(group, r)) goto err;
491 ret = 1;
492 goto err;
493 }
494 if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
495 if (!BN_GF2m_add(s, s, x1)) goto err;
496
497 if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
498 if (!BN_GF2m_add(x2, x2, s)) goto err;
499 if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
500 }
501
502 if (!BN_GF2m_add(y2, x1, x2)) goto err;
503 if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
504 if (!BN_GF2m_add(y2, y2, x2)) goto err;
505 if (!BN_GF2m_add(y2, y2, y1)) goto err;
506
507 if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
508
509 ret = 1;
510
511 err:
512 BN_CTX_end(ctx);
513 if (new_ctx != NULL)
514 BN_CTX_free(new_ctx);
515 return ret;
516 }
517
518
519/* Computes 2 * a and stores the result in r. r could be a.
520 * Uses algorithm A.10.2 of IEEE P1363.
521 */
522int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
523 {
524 return ec_GF2m_simple_add(group, r, a, a, ctx);
525 }
526
527
528int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
529 {
530 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
531 /* point is its own inverse */
532 return 1;
533
534 if (!EC_POINT_make_affine(group, point, ctx)) return 0;
535 return BN_GF2m_add(&point->Y, &point->X, &point->Y);
536 }
537
538
539/* Indicates whether the given point is the point at infinity. */
540int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
541 {
542 return BN_is_zero(&point->Z);
543 }
544
545
546/* Determines whether the given EC_POINT is an actual point on the curve defined
547 * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
548 * y^2 + x*y = x^3 + a*x^2 + b.
549 */
550int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
551 {
552 int ret = -1;
553 BN_CTX *new_ctx = NULL;
554 BIGNUM *lh, *y2;
555 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
556 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
557
558 if (EC_POINT_is_at_infinity(group, point))
559 return 1;
560
561 field_mul = group->meth->field_mul;
562 field_sqr = group->meth->field_sqr;
563
564 /* only support affine coordinates */
565 if (!point->Z_is_one) return -1;
566
567 if (ctx == NULL)
568 {
569 ctx = new_ctx = BN_CTX_new();
570 if (ctx == NULL)
571 return -1;
572 }
573
574 BN_CTX_start(ctx);
575 y2 = BN_CTX_get(ctx);
576 lh = BN_CTX_get(ctx);
577 if (lh == NULL) goto err;
578
579 /* We have a curve defined by a Weierstrass equation
580 * y^2 + x*y = x^3 + a*x^2 + b.
581 * <=> x^3 + a*x^2 + x*y + b + y^2 = 0
582 * <=> ((x + a) * x + y ) * x + b + y^2 = 0
583 */
584 if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
585 if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
586 if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
587 if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
588 if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
589 if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
590 if (!BN_GF2m_add(lh, lh, y2)) goto err;
591 ret = BN_is_zero(lh);
592 err:
593 if (ctx) BN_CTX_end(ctx);
594 if (new_ctx) BN_CTX_free(new_ctx);
595 return ret;
596 }
597
598
599/* Indicates whether two points are equal.
600 * Return values:
601 * -1 error
602 * 0 equal (in affine coordinates)
603 * 1 not equal
604 */
605int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
606 {
607 BIGNUM *aX, *aY, *bX, *bY;
608 BN_CTX *new_ctx = NULL;
609 int ret = -1;
610
611 if (EC_POINT_is_at_infinity(group, a))
612 {
613 return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
614 }
615
616 if (EC_POINT_is_at_infinity(group, b))
617 return 1;
618
619 if (a->Z_is_one && b->Z_is_one)
620 {
621 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
622 }
623
624 if (ctx == NULL)
625 {
626 ctx = new_ctx = BN_CTX_new();
627 if (ctx == NULL)
628 return -1;
629 }
630
631 BN_CTX_start(ctx);
632 aX = BN_CTX_get(ctx);
633 aY = BN_CTX_get(ctx);
634 bX = BN_CTX_get(ctx);
635 bY = BN_CTX_get(ctx);
636 if (bY == NULL) goto err;
637
638 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
639 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
640 ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
641
642 err:
643 if (ctx) BN_CTX_end(ctx);
644 if (new_ctx) BN_CTX_free(new_ctx);
645 return ret;
646 }
647
648
649/* Forces the given EC_POINT to internally use affine coordinates. */
650int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
651 {
652 BN_CTX *new_ctx = NULL;
653 BIGNUM *x, *y;
654 int ret = 0;
655
656 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
657 return 1;
658
659 if (ctx == NULL)
660 {
661 ctx = new_ctx = BN_CTX_new();
662 if (ctx == NULL)
663 return 0;
664 }
665
666 BN_CTX_start(ctx);
667 x = BN_CTX_get(ctx);
668 y = BN_CTX_get(ctx);
669 if (y == NULL) goto err;
670
671 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
672 if (!BN_copy(&point->X, x)) goto err;
673 if (!BN_copy(&point->Y, y)) goto err;
674 if (!BN_one(&point->Z)) goto err;
675
676 ret = 1;
677
678 err:
679 if (ctx) BN_CTX_end(ctx);
680 if (new_ctx) BN_CTX_free(new_ctx);
681 return ret;
682 }
683
684
685/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
686int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
687 {
688 size_t i;
689
690 for (i = 0; i < num; i++)
691 {
692 if (!group->meth->make_affine(group, points[i], ctx)) return 0;
693 }
694
695 return 1;
696 }
697
698
699/* Wrapper to simple binary polynomial field multiplication implementation. */
700int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
701 {
702 return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
703 }
704
705
706/* Wrapper to simple binary polynomial field squaring implementation. */
707int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
708 {
709 return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
710 }
711
712
713/* Wrapper to simple binary polynomial field division implementation. */
714int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
715 {
716 return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
717 }
718
719#endif
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
deleted file mode 100644
index 83909c1853..0000000000
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ /dev/null
@@ -1,660 +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 0,
655
656 int_ec_free,
657 ec_pkey_ctrl,
658 old_ec_priv_decode,
659 old_ec_priv_encode
660 };
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
deleted file mode 100644
index 175eec5342..0000000000
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ /dev/null
@@ -1,1443 +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#ifndef OPENSSL_NO_EC2M
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 }
104int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
105 unsigned int *k2, unsigned int *k3)
106 {
107 if (group == NULL)
108 return 0;
109
110 if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
111 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
112 {
113 ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
114 return 0;
115 }
116
117 if (k1)
118 *k1 = group->poly[3];
119 if (k2)
120 *k2 = group->poly[2];
121 if (k3)
122 *k3 = group->poly[1];
123
124 return 1;
125 }
126#endif
127
128
129/* some structures needed for the asn1 encoding */
130typedef struct x9_62_pentanomial_st {
131 long k1;
132 long k2;
133 long k3;
134 } X9_62_PENTANOMIAL;
135
136typedef struct x9_62_characteristic_two_st {
137 long m;
138 ASN1_OBJECT *type;
139 union {
140 char *ptr;
141 /* NID_X9_62_onBasis */
142 ASN1_NULL *onBasis;
143 /* NID_X9_62_tpBasis */
144 ASN1_INTEGER *tpBasis;
145 /* NID_X9_62_ppBasis */
146 X9_62_PENTANOMIAL *ppBasis;
147 /* anything else */
148 ASN1_TYPE *other;
149 } p;
150 } X9_62_CHARACTERISTIC_TWO;
151
152typedef struct x9_62_fieldid_st {
153 ASN1_OBJECT *fieldType;
154 union {
155 char *ptr;
156 /* NID_X9_62_prime_field */
157 ASN1_INTEGER *prime;
158 /* NID_X9_62_characteristic_two_field */
159 X9_62_CHARACTERISTIC_TWO *char_two;
160 /* anything else */
161 ASN1_TYPE *other;
162 } p;
163 } X9_62_FIELDID;
164
165typedef struct x9_62_curve_st {
166 ASN1_OCTET_STRING *a;
167 ASN1_OCTET_STRING *b;
168 ASN1_BIT_STRING *seed;
169 } X9_62_CURVE;
170
171typedef struct ec_parameters_st {
172 long version;
173 X9_62_FIELDID *fieldID;
174 X9_62_CURVE *curve;
175 ASN1_OCTET_STRING *base;
176 ASN1_INTEGER *order;
177 ASN1_INTEGER *cofactor;
178 } ECPARAMETERS;
179
180struct ecpk_parameters_st {
181 int type;
182 union {
183 ASN1_OBJECT *named_curve;
184 ECPARAMETERS *parameters;
185 ASN1_NULL *implicitlyCA;
186 } value;
187 }/* ECPKPARAMETERS */;
188
189/* SEC1 ECPrivateKey */
190typedef struct ec_privatekey_st {
191 long version;
192 ASN1_OCTET_STRING *privateKey;
193 ECPKPARAMETERS *parameters;
194 ASN1_BIT_STRING *publicKey;
195 } EC_PRIVATEKEY;
196
197/* the OpenSSL ASN.1 definitions */
198ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
199 ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
200 ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
201 ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
202} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
203
204DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
205IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
206
207ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
208
209ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
210 ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
211 ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
212 ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
213} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
214
215ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
216 ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
217 ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
218 ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
219} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
220
221DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
222IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
223
224ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
225
226ASN1_ADB(X9_62_FIELDID) = {
227 ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
228 ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
229} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
230
231ASN1_SEQUENCE(X9_62_FIELDID) = {
232 ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
233 ASN1_ADB_OBJECT(X9_62_FIELDID)
234} ASN1_SEQUENCE_END(X9_62_FIELDID)
235
236ASN1_SEQUENCE(X9_62_CURVE) = {
237 ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
238 ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
239 ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
240} ASN1_SEQUENCE_END(X9_62_CURVE)
241
242ASN1_SEQUENCE(ECPARAMETERS) = {
243 ASN1_SIMPLE(ECPARAMETERS, version, LONG),
244 ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
245 ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
246 ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
247 ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
248 ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
249} ASN1_SEQUENCE_END(ECPARAMETERS)
250
251DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
252IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
253
254ASN1_CHOICE(ECPKPARAMETERS) = {
255 ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
256 ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
257 ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
258} ASN1_CHOICE_END(ECPKPARAMETERS)
259
260DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
261DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
262IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
263
264ASN1_SEQUENCE(EC_PRIVATEKEY) = {
265 ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
266 ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
267 ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
268 ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
269} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
270
271DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
272DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
273IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
274
275/* some declarations of internal function */
276
277/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
278static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
279/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
280static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
281/* ec_asn1_parameters2group() creates a EC_GROUP object from a
282 * ECPARAMETERS object */
283static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
284/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
285 * EC_GROUP object */
286static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
287/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
288 * ECPKPARAMETERS object */
289static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
290/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
291 * EC_GROUP object */
292static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
293 ECPKPARAMETERS *);
294
295
296/* the function definitions */
297
298static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
299 {
300 int ok=0, nid;
301 BIGNUM *tmp = NULL;
302
303 if (group == NULL || field == NULL)
304 return 0;
305
306 /* clear the old values (if necessary) */
307 if (field->fieldType != NULL)
308 ASN1_OBJECT_free(field->fieldType);
309 if (field->p.other != NULL)
310 ASN1_TYPE_free(field->p.other);
311
312 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
313 /* set OID for the field */
314 if ((field->fieldType = OBJ_nid2obj(nid)) == NULL)
315 {
316 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
317 goto err;
318 }
319
320 if (nid == NID_X9_62_prime_field)
321 {
322 if ((tmp = BN_new()) == NULL)
323 {
324 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
325 goto err;
326 }
327 /* the parameters are specified by the prime number p */
328 if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL))
329 {
330 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
331 goto err;
332 }
333 /* set the prime number */
334 field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL);
335 if (field->p.prime == NULL)
336 {
337 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
338 goto err;
339 }
340 }
341 else /* nid == NID_X9_62_characteristic_two_field */
342#ifdef OPENSSL_NO_EC2M
343 {
344 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
345 goto err;
346 }
347#else
348 {
349 int field_type;
350 X9_62_CHARACTERISTIC_TWO *char_two;
351
352 field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
353 char_two = field->p.char_two;
354
355 if (char_two == NULL)
356 {
357 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
358 goto err;
359 }
360
361 char_two->m = (long)EC_GROUP_get_degree(group);
362
363 field_type = EC_GROUP_get_basis_type(group);
364
365 if (field_type == 0)
366 {
367 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
368 goto err;
369 }
370 /* set base type OID */
371 if ((char_two->type = OBJ_nid2obj(field_type)) == NULL)
372 {
373 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
374 goto err;
375 }
376
377 if (field_type == NID_X9_62_tpBasis)
378 {
379 unsigned int k;
380
381 if (!EC_GROUP_get_trinomial_basis(group, &k))
382 goto err;
383
384 char_two->p.tpBasis = ASN1_INTEGER_new();
385 if (!char_two->p.tpBasis)
386 {
387 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
388 goto err;
389 }
390 if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k))
391 {
392 ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
393 ERR_R_ASN1_LIB);
394 goto err;
395 }
396 }
397 else if (field_type == NID_X9_62_ppBasis)
398 {
399 unsigned int k1, k2, k3;
400
401 if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
402 goto err;
403
404 char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
405 if (!char_two->p.ppBasis)
406 {
407 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
408 goto err;
409 }
410
411 /* set k? values */
412 char_two->p.ppBasis->k1 = (long)k1;
413 char_two->p.ppBasis->k2 = (long)k2;
414 char_two->p.ppBasis->k3 = (long)k3;
415 }
416 else /* field_type == NID_X9_62_onBasis */
417 {
418 /* for ONB the parameters are (asn1) NULL */
419 char_two->p.onBasis = ASN1_NULL_new();
420 if (!char_two->p.onBasis)
421 {
422 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
423 goto err;
424 }
425 }
426 }
427#endif
428
429 ok = 1;
430
431err : if (tmp)
432 BN_free(tmp);
433 return(ok);
434}
435
436static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
437 {
438 int ok=0, nid;
439 BIGNUM *tmp_1=NULL, *tmp_2=NULL;
440 unsigned char *buffer_1=NULL, *buffer_2=NULL,
441 *a_buf=NULL, *b_buf=NULL;
442 size_t len_1, len_2;
443 unsigned char char_zero = 0;
444
445 if (!group || !curve || !curve->a || !curve->b)
446 return 0;
447
448 if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL)
449 {
450 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
451 goto err;
452 }
453
454 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
455
456 /* get a and b */
457 if (nid == NID_X9_62_prime_field)
458 {
459 if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL))
460 {
461 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
462 goto err;
463 }
464 }
465#ifndef OPENSSL_NO_EC2M
466 else /* nid == NID_X9_62_characteristic_two_field */
467 {
468 if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
469 {
470 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
471 goto err;
472 }
473 }
474#endif
475 len_1 = (size_t)BN_num_bytes(tmp_1);
476 len_2 = (size_t)BN_num_bytes(tmp_2);
477
478 if (len_1 == 0)
479 {
480 /* len_1 == 0 => a == 0 */
481 a_buf = &char_zero;
482 len_1 = 1;
483 }
484 else
485 {
486 if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL)
487 {
488 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
489 ERR_R_MALLOC_FAILURE);
490 goto err;
491 }
492 if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0)
493 {
494 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
495 goto err;
496 }
497 a_buf = buffer_1;
498 }
499
500 if (len_2 == 0)
501 {
502 /* len_2 == 0 => b == 0 */
503 b_buf = &char_zero;
504 len_2 = 1;
505 }
506 else
507 {
508 if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL)
509 {
510 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
511 ERR_R_MALLOC_FAILURE);
512 goto err;
513 }
514 if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0)
515 {
516 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
517 goto err;
518 }
519 b_buf = buffer_2;
520 }
521
522 /* set a and b */
523 if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
524 !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2))
525 {
526 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
527 goto err;
528 }
529
530 /* set the seed (optional) */
531 if (group->seed)
532 {
533 if (!curve->seed)
534 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL)
535 {
536 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
537 goto err;
538 }
539 curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
540 curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
541 if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
542 (int)group->seed_len))
543 {
544 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
545 goto err;
546 }
547 }
548 else
549 {
550 if (curve->seed)
551 {
552 ASN1_BIT_STRING_free(curve->seed);
553 curve->seed = NULL;
554 }
555 }
556
557 ok = 1;
558
559err: if (buffer_1)
560 OPENSSL_free(buffer_1);
561 if (buffer_2)
562 OPENSSL_free(buffer_2);
563 if (tmp_1)
564 BN_free(tmp_1);
565 if (tmp_2)
566 BN_free(tmp_2);
567 return(ok);
568 }
569
570static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
571 ECPARAMETERS *param)
572 {
573 int ok=0;
574 size_t len=0;
575 ECPARAMETERS *ret=NULL;
576 BIGNUM *tmp=NULL;
577 unsigned char *buffer=NULL;
578 const EC_POINT *point=NULL;
579 point_conversion_form_t form;
580
581 if ((tmp = BN_new()) == NULL)
582 {
583 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
584 goto err;
585 }
586
587 if (param == NULL)
588 {
589 if ((ret = ECPARAMETERS_new()) == NULL)
590 {
591 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS,
592 ERR_R_MALLOC_FAILURE);
593 goto err;
594 }
595 }
596 else
597 ret = param;
598
599 /* set the version (always one) */
600 ret->version = (long)0x1;
601
602 /* set the fieldID */
603 if (!ec_asn1_group2fieldid(group, ret->fieldID))
604 {
605 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
606 goto err;
607 }
608
609 /* set the curve */
610 if (!ec_asn1_group2curve(group, ret->curve))
611 {
612 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
613 goto err;
614 }
615
616 /* set the base point */
617 if ((point = EC_GROUP_get0_generator(group)) == NULL)
618 {
619 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
620 goto err;
621 }
622
623 form = EC_GROUP_get_point_conversion_form(group);
624
625 len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
626 if (len == 0)
627 {
628 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
629 goto err;
630 }
631 if ((buffer = OPENSSL_malloc(len)) == NULL)
632 {
633 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
634 goto err;
635 }
636 if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
637 {
638 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
639 goto err;
640 }
641 if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
642 {
643 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
644 goto err;
645 }
646 if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
647 {
648 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
649 goto err;
650 }
651
652 /* set the order */
653 if (!EC_GROUP_get_order(group, tmp, NULL))
654 {
655 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
656 goto err;
657 }
658 ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
659 if (ret->order == NULL)
660 {
661 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
662 goto err;
663 }
664
665 /* set the cofactor (optional) */
666 if (EC_GROUP_get_cofactor(group, tmp, NULL))
667 {
668 ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
669 if (ret->cofactor == NULL)
670 {
671 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
672 goto err;
673 }
674 }
675
676 ok = 1;
677
678err : if(!ok)
679 {
680 if (ret && !param)
681 ECPARAMETERS_free(ret);
682 ret = NULL;
683 }
684 if (tmp)
685 BN_free(tmp);
686 if (buffer)
687 OPENSSL_free(buffer);
688 return(ret);
689 }
690
691ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
692 ECPKPARAMETERS *params)
693 {
694 int ok = 1, tmp;
695 ECPKPARAMETERS *ret = params;
696
697 if (ret == NULL)
698 {
699 if ((ret = ECPKPARAMETERS_new()) == NULL)
700 {
701 ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS,
702 ERR_R_MALLOC_FAILURE);
703 return NULL;
704 }
705 }
706 else
707 {
708 if (ret->type == 0 && ret->value.named_curve)
709 ASN1_OBJECT_free(ret->value.named_curve);
710 else if (ret->type == 1 && ret->value.parameters)
711 ECPARAMETERS_free(ret->value.parameters);
712 }
713
714 if (EC_GROUP_get_asn1_flag(group))
715 {
716 /* use the asn1 OID to describe the
717 * the elliptic curve parameters
718 */
719 tmp = EC_GROUP_get_curve_name(group);
720 if (tmp)
721 {
722 ret->type = 0;
723 if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
724 ok = 0;
725 }
726 else
727 /* we don't kmow the nid => ERROR */
728 ok = 0;
729 }
730 else
731 {
732 /* use the ECPARAMETERS structure */
733 ret->type = 1;
734 if ((ret->value.parameters = ec_asn1_group2parameters(
735 group, NULL)) == NULL)
736 ok = 0;
737 }
738
739 if (!ok)
740 {
741 ECPKPARAMETERS_free(ret);
742 return NULL;
743 }
744 return ret;
745 }
746
747static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
748 {
749 int ok = 0, tmp;
750 EC_GROUP *ret = NULL;
751 BIGNUM *p = NULL, *a = NULL, *b = NULL;
752 EC_POINT *point=NULL;
753 long field_bits;
754
755 if (!params->fieldID || !params->fieldID->fieldType ||
756 !params->fieldID->p.ptr)
757 {
758 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
759 goto err;
760 }
761
762 /* now extract the curve parameters a and b */
763 if (!params->curve || !params->curve->a ||
764 !params->curve->a->data || !params->curve->b ||
765 !params->curve->b->data)
766 {
767 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
768 goto err;
769 }
770 a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
771 if (a == NULL)
772 {
773 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
774 goto err;
775 }
776 b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
777 if (b == NULL)
778 {
779 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
780 goto err;
781 }
782
783 /* get the field parameters */
784 tmp = OBJ_obj2nid(params->fieldID->fieldType);
785 if (tmp == NID_X9_62_characteristic_two_field)
786#ifdef OPENSSL_NO_EC2M
787 {
788 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
789 goto err;
790 }
791#else
792 {
793 X9_62_CHARACTERISTIC_TWO *char_two;
794
795 char_two = params->fieldID->p.char_two;
796
797 field_bits = char_two->m;
798 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
799 {
800 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
801 goto err;
802 }
803
804 if ((p = BN_new()) == NULL)
805 {
806 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
807 goto err;
808 }
809
810 /* get the base type */
811 tmp = OBJ_obj2nid(char_two->type);
812
813 if (tmp == NID_X9_62_tpBasis)
814 {
815 long tmp_long;
816
817 if (!char_two->p.tpBasis)
818 {
819 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
820 goto err;
821 }
822
823 tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
824
825 if (!(char_two->m > tmp_long && tmp_long > 0))
826 {
827 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
828 goto err;
829 }
830
831 /* create the polynomial */
832 if (!BN_set_bit(p, (int)char_two->m))
833 goto err;
834 if (!BN_set_bit(p, (int)tmp_long))
835 goto err;
836 if (!BN_set_bit(p, 0))
837 goto err;
838 }
839 else if (tmp == NID_X9_62_ppBasis)
840 {
841 X9_62_PENTANOMIAL *penta;
842
843 penta = char_two->p.ppBasis;
844 if (!penta)
845 {
846 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
847 goto err;
848 }
849
850 if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
851 {
852 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
853 goto err;
854 }
855
856 /* create the polynomial */
857 if (!BN_set_bit(p, (int)char_two->m)) goto err;
858 if (!BN_set_bit(p, (int)penta->k1)) goto err;
859 if (!BN_set_bit(p, (int)penta->k2)) goto err;
860 if (!BN_set_bit(p, (int)penta->k3)) goto err;
861 if (!BN_set_bit(p, 0)) goto err;
862 }
863 else if (tmp == NID_X9_62_onBasis)
864 {
865 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
866 goto err;
867 }
868 else /* error */
869 {
870 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
871 goto err;
872 }
873
874 /* create the EC_GROUP structure */
875 ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
876 }
877#endif
878 else if (tmp == NID_X9_62_prime_field)
879 {
880 /* we have a curve over a prime field */
881 /* extract the prime number */
882 if (!params->fieldID->p.prime)
883 {
884 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
885 goto err;
886 }
887 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
888 if (p == NULL)
889 {
890 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
891 goto err;
892 }
893
894 if (BN_is_negative(p) || BN_is_zero(p))
895 {
896 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
897 goto err;
898 }
899
900 field_bits = BN_num_bits(p);
901 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
902 {
903 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
904 goto err;
905 }
906
907 /* create the EC_GROUP structure */
908 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
909 }
910 else
911 {
912 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
913 goto err;
914 }
915
916 if (ret == NULL)
917 {
918 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
919 goto err;
920 }
921
922 /* extract seed (optional) */
923 if (params->curve->seed != NULL)
924 {
925 if (ret->seed != NULL)
926 OPENSSL_free(ret->seed);
927 if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
928 {
929 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
930 ERR_R_MALLOC_FAILURE);
931 goto err;
932 }
933 memcpy(ret->seed, params->curve->seed->data,
934 params->curve->seed->length);
935 ret->seed_len = params->curve->seed->length;
936 }
937
938 if (!params->order || !params->base || !params->base->data)
939 {
940 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
941 goto err;
942 }
943
944 if ((point = EC_POINT_new(ret)) == NULL) goto err;
945
946 /* set the point conversion form */
947 EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
948 (params->base->data[0] & ~0x01));
949
950 /* extract the ec point */
951 if (!EC_POINT_oct2point(ret, point, params->base->data,
952 params->base->length, NULL))
953 {
954 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
955 goto err;
956 }
957
958 /* extract the order */
959 if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
960 {
961 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
962 goto err;
963 }
964 if (BN_is_negative(a) || BN_is_zero(a))
965 {
966 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
967 goto err;
968 }
969 if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
970 {
971 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
972 goto err;
973 }
974
975 /* extract the cofactor (optional) */
976 if (params->cofactor == NULL)
977 {
978 if (b)
979 {
980 BN_free(b);
981 b = NULL;
982 }
983 }
984 else
985 if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
986 {
987 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
988 goto err;
989 }
990 /* set the generator, order and cofactor (if present) */
991 if (!EC_GROUP_set_generator(ret, point, a, b))
992 {
993 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
994 goto err;
995 }
996
997 ok = 1;
998
999err: if (!ok)
1000 {
1001 if (ret)
1002 EC_GROUP_clear_free(ret);
1003 ret = NULL;
1004 }
1005
1006 if (p)
1007 BN_free(p);
1008 if (a)
1009 BN_free(a);
1010 if (b)
1011 BN_free(b);
1012 if (point)
1013 EC_POINT_free(point);
1014 return(ret);
1015}
1016
1017EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1018 {
1019 EC_GROUP *ret=NULL;
1020 int tmp=0;
1021
1022 if (params == NULL)
1023 {
1024 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1025 EC_R_MISSING_PARAMETERS);
1026 return NULL;
1027 }
1028
1029 if (params->type == 0)
1030 { /* the curve is given by an OID */
1031 tmp = OBJ_obj2nid(params->value.named_curve);
1032 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
1033 {
1034 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1035 EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1036 return NULL;
1037 }
1038 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1039 }
1040 else if (params->type == 1)
1041 { /* the parameters are given by a ECPARAMETERS
1042 * structure */
1043 ret = ec_asn1_parameters2group(params->value.parameters);
1044 if (!ret)
1045 {
1046 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1047 return NULL;
1048 }
1049 EC_GROUP_set_asn1_flag(ret, 0x0);
1050 }
1051 else if (params->type == 2)
1052 { /* implicitlyCA */
1053 return NULL;
1054 }
1055 else
1056 {
1057 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
1058 return NULL;
1059 }
1060
1061 return ret;
1062 }
1063
1064/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1065
1066EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1067 {
1068 EC_GROUP *group = NULL;
1069 ECPKPARAMETERS *params = NULL;
1070
1071 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
1072 {
1073 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1074 ECPKPARAMETERS_free(params);
1075 return NULL;
1076 }
1077
1078 if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1079 {
1080 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1081 ECPKPARAMETERS_free(params);
1082 return NULL;
1083 }
1084
1085
1086 if (a && *a)
1087 EC_GROUP_clear_free(*a);
1088 if (a)
1089 *a = group;
1090
1091 ECPKPARAMETERS_free(params);
1092 return(group);
1093 }
1094
1095int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1096 {
1097 int ret=0;
1098 ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
1099 if (tmp == NULL)
1100 {
1101 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1102 return 0;
1103 }
1104 if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
1105 {
1106 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1107 ECPKPARAMETERS_free(tmp);
1108 return 0;
1109 }
1110 ECPKPARAMETERS_free(tmp);
1111 return(ret);
1112 }
1113
1114/* some EC_KEY functions */
1115
1116EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1117 {
1118 int ok=0;
1119 EC_KEY *ret=NULL;
1120 EC_PRIVATEKEY *priv_key=NULL;
1121
1122 if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1123 {
1124 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1125 return NULL;
1126 }
1127
1128 if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
1129 {
1130 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1131 EC_PRIVATEKEY_free(priv_key);
1132 return NULL;
1133 }
1134
1135 if (a == NULL || *a == NULL)
1136 {
1137 if ((ret = EC_KEY_new()) == NULL)
1138 {
1139 ECerr(EC_F_D2I_ECPRIVATEKEY,
1140 ERR_R_MALLOC_FAILURE);
1141 goto err;
1142 }
1143 if (a)
1144 *a = ret;
1145 }
1146 else
1147 ret = *a;
1148
1149 if (priv_key->parameters)
1150 {
1151 if (ret->group)
1152 EC_GROUP_clear_free(ret->group);
1153 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1154 }
1155
1156 if (ret->group == NULL)
1157 {
1158 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1159 goto err;
1160 }
1161
1162 ret->version = priv_key->version;
1163
1164 if (priv_key->privateKey)
1165 {
1166 ret->priv_key = BN_bin2bn(
1167 M_ASN1_STRING_data(priv_key->privateKey),
1168 M_ASN1_STRING_length(priv_key->privateKey),
1169 ret->priv_key);
1170 if (ret->priv_key == NULL)
1171 {
1172 ECerr(EC_F_D2I_ECPRIVATEKEY,
1173 ERR_R_BN_LIB);
1174 goto err;
1175 }
1176 }
1177 else
1178 {
1179 ECerr(EC_F_D2I_ECPRIVATEKEY,
1180 EC_R_MISSING_PRIVATE_KEY);
1181 goto err;
1182 }
1183
1184 if (priv_key->publicKey)
1185 {
1186 const unsigned char *pub_oct;
1187 size_t pub_oct_len;
1188
1189 if (ret->pub_key)
1190 EC_POINT_clear_free(ret->pub_key);
1191 ret->pub_key = EC_POINT_new(ret->group);
1192 if (ret->pub_key == NULL)
1193 {
1194 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1195 goto err;
1196 }
1197 pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
1198 pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1199 /* save the point conversion form */
1200 ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
1201 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1202 pub_oct, pub_oct_len, NULL))
1203 {
1204 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1205 goto err;
1206 }
1207 }
1208
1209 ok = 1;
1210err:
1211 if (!ok)
1212 {
1213 if (ret)
1214 EC_KEY_free(ret);
1215 ret = NULL;
1216 }
1217
1218 if (priv_key)
1219 EC_PRIVATEKEY_free(priv_key);
1220
1221 return(ret);
1222 }
1223
1224int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1225 {
1226 int ret=0, ok=0;
1227 unsigned char *buffer=NULL;
1228 size_t buf_len=0, tmp_len;
1229 EC_PRIVATEKEY *priv_key=NULL;
1230
1231 if (a == NULL || a->group == NULL || a->priv_key == NULL)
1232 {
1233 ECerr(EC_F_I2D_ECPRIVATEKEY,
1234 ERR_R_PASSED_NULL_PARAMETER);
1235 goto err;
1236 }
1237
1238 if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1239 {
1240 ECerr(EC_F_I2D_ECPRIVATEKEY,
1241 ERR_R_MALLOC_FAILURE);
1242 goto err;
1243 }
1244
1245 priv_key->version = a->version;
1246
1247 buf_len = (size_t)BN_num_bytes(a->priv_key);
1248 buffer = OPENSSL_malloc(buf_len);
1249 if (buffer == NULL)
1250 {
1251 ECerr(EC_F_I2D_ECPRIVATEKEY,
1252 ERR_R_MALLOC_FAILURE);
1253 goto err;
1254 }
1255
1256 if (!BN_bn2bin(a->priv_key, buffer))
1257 {
1258 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1259 goto err;
1260 }
1261
1262 if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
1263 {
1264 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1265 goto err;
1266 }
1267
1268 if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
1269 {
1270 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1271 a->group, priv_key->parameters)) == NULL)
1272 {
1273 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1274 goto err;
1275 }
1276 }
1277
1278 if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
1279 {
1280 priv_key->publicKey = M_ASN1_BIT_STRING_new();
1281 if (priv_key->publicKey == NULL)
1282 {
1283 ECerr(EC_F_I2D_ECPRIVATEKEY,
1284 ERR_R_MALLOC_FAILURE);
1285 goto err;
1286 }
1287
1288 tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1289 a->conv_form, NULL, 0, NULL);
1290
1291 if (tmp_len > buf_len)
1292 {
1293 unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1294 if (!tmp_buffer)
1295 {
1296 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1297 goto err;
1298 }
1299 buffer = tmp_buffer;
1300 buf_len = tmp_len;
1301 }
1302
1303 if (!EC_POINT_point2oct(a->group, a->pub_key,
1304 a->conv_form, buffer, buf_len, NULL))
1305 {
1306 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1307 goto err;
1308 }
1309
1310 priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
1311 priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1312 if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer,
1313 buf_len))
1314 {
1315 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1316 goto err;
1317 }
1318 }
1319
1320 if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
1321 {
1322 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1323 goto err;
1324 }
1325 ok=1;
1326err:
1327 if (buffer)
1328 OPENSSL_free(buffer);
1329 if (priv_key)
1330 EC_PRIVATEKEY_free(priv_key);
1331 return(ok?ret:0);
1332 }
1333
1334int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1335 {
1336 if (a == NULL)
1337 {
1338 ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1339 return 0;
1340 }
1341 return i2d_ECPKParameters(a->group, out);
1342 }
1343
1344EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1345 {
1346 EC_KEY *ret;
1347
1348 if (in == NULL || *in == NULL)
1349 {
1350 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1351 return NULL;
1352 }
1353
1354 if (a == NULL || *a == NULL)
1355 {
1356 if ((ret = EC_KEY_new()) == NULL)
1357 {
1358 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1359 return NULL;
1360 }
1361 if (a)
1362 *a = ret;
1363 }
1364 else
1365 ret = *a;
1366
1367 if (!d2i_ECPKParameters(&ret->group, in, len))
1368 {
1369 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1370 return NULL;
1371 }
1372
1373 return ret;
1374 }
1375
1376EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1377 {
1378 EC_KEY *ret=NULL;
1379
1380 if (a == NULL || (*a) == NULL || (*a)->group == NULL)
1381 {
1382 /* sorry, but a EC_GROUP-structur is necessary
1383 * to set the public key */
1384 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1385 return 0;
1386 }
1387 ret = *a;
1388 if (ret->pub_key == NULL &&
1389 (ret->pub_key = EC_POINT_new(ret->group)) == NULL)
1390 {
1391 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1392 return 0;
1393 }
1394 if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
1395 {
1396 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1397 return 0;
1398 }
1399 /* save the point conversion form */
1400 ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
1401 *in += len;
1402 return ret;
1403 }
1404
1405int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1406 {
1407 size_t buf_len=0;
1408 int new_buffer = 0;
1409
1410 if (a == NULL)
1411 {
1412 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1413 return 0;
1414 }
1415
1416 buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1417 a->conv_form, NULL, 0, NULL);
1418
1419 if (out == NULL || buf_len == 0)
1420 /* out == NULL => just return the length of the octet string */
1421 return buf_len;
1422
1423 if (*out == NULL)
1424 {
1425 if ((*out = OPENSSL_malloc(buf_len)) == NULL)
1426 {
1427 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1428 return 0;
1429 }
1430 new_buffer = 1;
1431 }
1432 if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1433 *out, buf_len, NULL))
1434 {
1435 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1436 OPENSSL_free(*out);
1437 *out = NULL;
1438 return 0;
1439 }
1440 if (!new_buffer)
1441 *out += buf_len;
1442 return buf_len;
1443 }
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 c72fb2697c..0000000000
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ /dev/null
@@ -1,2100 +0,0 @@
1/* crypto/ec/ec_curve.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2010 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#include <openssl/opensslconf.h>
76
77typedef struct {
78 int field_type, /* either NID_X9_62_prime_field or
79 * NID_X9_62_characteristic_two_field */
80 seed_len,
81 param_len;
82 unsigned int cofactor; /* promoted to BN_ULONG */
83} EC_CURVE_DATA;
84
85/* the nist prime curves */
86static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
87 _EC_NIST_PRIME_192 = {
88 { NID_X9_62_prime_field,20,24,1 },
89 { 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, /* seed */
90 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5,
91
92 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
93 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
94 0xFF,0xFF,0xFF,0xFF,
95 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
96 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
97 0xFF,0xFF,0xFF,0xFC,
98 0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7, /* b */
99 0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC,
100 0xC1,0x46,0xB9,0xB1,
101 0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF, /* x */
102 0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD,
103 0x82,0xFF,0x10,0x12,
104 0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10, /* y */
105 0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1,
106 0x1e,0x79,0x48,0x11,
107 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
108 0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1,
109 0xB4,0xD2,0x28,0x31 }
110 };
111
112static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; }
113 _EC_NIST_PRIME_224 = {
114 { NID_X9_62_prime_field,20,28,1 },
115 { 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, /* seed */
116 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5,
117
118 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
119 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
120 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
121 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
122 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
123 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
124 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
125 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
126 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
127 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
128 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
129 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
130 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
131 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
132 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
133 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
134 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
135 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
136 };
137
138static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; }
139 _EC_NIST_PRIME_384 = {
140 { NID_X9_62_prime_field,20,48,1 },
141 { 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, /* seed */
142 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73,
143
144 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
145 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
146 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
147 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
148 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
149 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
150 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
151 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
152 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
153 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC,
154 0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E, /* b */
155 0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E,
156 0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13,
157 0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D,
158 0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF,
159 0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1, /* x */
160 0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62,
161 0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54,
162 0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C,
163 0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7,
164 0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e, /* y */
165 0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd,
166 0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0,
167 0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d,
168 0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f,
169 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
170 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
171 0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37,
172 0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A,
173 0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 }
174 };
175
176static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; }
177 _EC_NIST_PRIME_521 = {
178 { NID_X9_62_prime_field,20,66,1 },
179 { 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, /* seed */
180 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA,
181
182 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
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,0xFF,0xFF,0xFF,0xFF,
188 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
189 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
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,0xFF,0xFF,0xFF,0xFF,0xFF,
195 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
196 0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F, /* b */
197 0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA,
198 0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91,
199 0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E,
200 0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07,
201 0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45,
202 0x1F,0xD4,0x6B,0x50,0x3F,0x00,
203 0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD, /* x */
204 0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64,
205 0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60,
206 0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7,
207 0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE,
208 0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E,
209 0x7E,0x31,0xC2,0xE5,0xBD,0x66,
210 0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04, /* y */
211 0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5,
212 0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17,
213 0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4,
214 0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61,
215 0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe,
216 0x94,0x76,0x9f,0xd1,0x66,0x50,
217 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
218 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
219 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
220 0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F,
221 0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0,
222 0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F,
223 0xB7,0x1E,0x91,0x38,0x64,0x09 }
224 };
225
226/* the x9.62 prime curves (minus the nist prime curves) */
227static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
228 _EC_X9_62_PRIME_192V2 = {
229 { NID_X9_62_prime_field,20,24,1 },
230 { 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, /* seed */
231 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6,
232
233 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
234 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
235 0xFF,0xFF,0xFF,0xFF,
236 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
237 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
238 0xFF,0xFF,0xFF,0xFC,
239 0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C, /* b */
240 0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2,
241 0x16,0x68,0xD9,0x53,
242 0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE, /* x */
243 0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69,
244 0x6F,0x48,0x03,0x4A,
245 0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b, /* y */
246 0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9,
247 0x70,0xb2,0xde,0x15,
248 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
249 0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86,
250 0x48,0xD8,0xDD,0x31 }
251 };
252
253static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
254 _EC_X9_62_PRIME_192V3 = {
255 { NID_X9_62_prime_field,20,24,1 },
256 { 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, /* seed */
257 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E,
258
259 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
260 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
261 0xFF,0xFF,0xFF,0xFF,
262 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
263 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
264 0xFF,0xFF,0xFF,0xFC,
265 0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42, /* b */
266 0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25,
267 0x6B,0xD5,0x69,0x16,
268 0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78, /* x */
269 0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E,
270 0x22,0x8F,0x18,0x96,
271 0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49, /* y */
272 0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76,
273 0x48,0xa9,0x43,0xb0,
274 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
275 0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94,
276 0xF6,0x40,0xEC,0x13 }
277 };
278
279static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
280 _EC_X9_62_PRIME_239V1 = {
281 { NID_X9_62_prime_field,20,30,1 },
282 { 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, /* seed */
283 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D,
284
285 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
286 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
287 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
288
289 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
290 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
291 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
292
293 0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6, /* b */
294 0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2,
295 0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A,
296
297 0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33, /* x */
298 0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57,
299 0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF,
300
301 0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40, /* y */
302 0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18,
303 0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae,
304
305 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
306 0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D,
307 0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B }
308 };
309
310static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
311 _EC_X9_62_PRIME_239V2 = {
312 { NID_X9_62_prime_field,20,30,1 },
313 { 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, /* seed */
314 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16,
315
316 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
317 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
318 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
319
320 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
321 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
322 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
323
324 0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5, /* b */
325 0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B,
326 0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C,
327
328 0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9, /* x */
329 0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2,
330 0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7,
331
332 0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d, /* y */
333 0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55,
334 0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba,
335
336 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
337 0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43,
338 0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 }
339 };
340
341static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
342 _EC_X9_62_PRIME_239V3 = {
343 { NID_X9_62_prime_field,20,30,1 },
344 { 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, /* seed */
345 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF,
346
347 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
348 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
349 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
350
351 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
352 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
353 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
354
355 0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4, /* b */
356 0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02,
357 0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E,
358
359 0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00, /* x */
360 0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6,
361 0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A,
362
363 0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d, /* y */
364 0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b,
365 0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3,
366
367 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
368 0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3,
369 0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 }
370 };
371
372
373static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; }
374 _EC_X9_62_PRIME_256V1 = {
375 { NID_X9_62_prime_field,20,32,1 },
376 { 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, /* seed */
377 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90,
378
379 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* p */
380 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
381 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
382 0xFF,0xFF,
383 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* a */
384 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
385 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
386 0xFF,0xFC,
387 0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB, /* b */
388 0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,
389 0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2,
390 0x60,0x4B,
391 0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC, /* x */
392 0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,
393 0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,
394 0xC2,0x96,
395 0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7, /* y */
396 0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57,
397 0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,
398 0x51,0xf5,
399 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF, /* order */
400 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,
401 0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63,
402 0x25,0x51 }
403 };
404
405/* the secg prime curves (minus the nist and x9.62 prime curves) */
406static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
407 _EC_SECG_PRIME_112R1 = {
408 { NID_X9_62_prime_field,20,14,1 },
409 { 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, /* seed */
410 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1,
411
412 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */
413 0xBE,0xAD,0x20,0x8B,
414 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* a */
415 0xBE,0xAD,0x20,0x88,
416 0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89, /* b */
417 0x11,0x70,0x2B,0x22,
418 0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55, /* x */
419 0xF9,0xC2,0xF0,0x98,
420 0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e, /* y */
421 0x0f,0xf7,0x75,0x00,
422 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF, /* order */
423 0xAC,0x65,0x61,0xC5 }
424 };
425
426static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
427 _EC_SECG_PRIME_112R2 = {
428 { NID_X9_62_prime_field,20,14,4 },
429 { 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, /* seed */
430 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4,
431
432 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */
433 0xBE,0xAD,0x20,0x8B,
434 0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6, /* a */
435 0x5C,0x0E,0xF0,0x2C,
436 0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3, /* b */
437 0x4C,0x85,0xD7,0x09,
438 0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D, /* x */
439 0xD0,0x92,0x86,0x43,
440 0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3, /* y */
441 0x6e,0x95,0x6e,0x97,
442 0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1, /* order */
443 0x05,0x20,0xD0,0x4B }
444 };
445
446static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
447 _EC_SECG_PRIME_128R1 = {
448 { NID_X9_62_prime_field,20,16,1 },
449 { 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
450 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79,
451
452 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
453 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
454 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
455 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
456 0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24, /* b */
457 0x99,0x3C,0x2C,0xEE,0x5E,0xD3,
458 0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28, /* x */
459 0x60,0x7C,0xA5,0x2C,0x5B,0x86,
460 0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d, /* y */
461 0xa2,0x92,0xdd,0xed,0x7a,0x83,
462 0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3, /* order */
463 0x0D,0x1B,0x90,0x38,0xA1,0x15 }
464 };
465
466static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
467 _EC_SECG_PRIME_128R2 = {
468 { NID_X9_62_prime_field,20,16,4 },
469 { 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, /* seed */
470 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4,
471
472 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
473 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
474 0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59, /* a */
475 0xCC,0x9B,0xBF,0xF9,0xAE,0xE1,
476 0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C, /* b */
477 0x65,0x58,0xBB,0x6D,0x8A,0x5D,
478 0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB, /* x */
479 0x32,0xA7,0xCD,0xEB,0xC1,0x40,
480 0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06, /* y */
481 0xfe,0x80,0x5f,0xc3,0x4b,0x44,
482 0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00, /* order */
483 0x24,0x72,0x06,0x13,0xB5,0xA3 }
484 };
485
486static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
487 _EC_SECG_PRIME_160K1 = {
488 { NID_X9_62_prime_field,0,21,1 },
489 { /* no seed */
490 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
491 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
492 0x73,
493 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
494 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
495 0x00,
496 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
497 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
498 0x07,
499 0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4, /* x */
500 0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E,
501 0xBB,
502 0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b, /* y */
503 0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f,
504 0xee,
505 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
506 0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6,
507 0xB3 }
508 };
509
510static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
511 _EC_SECG_PRIME_160R1 = {
512 { NID_X9_62_prime_field,20,21,1 },
513 { 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, /* seed */
514 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45,
515
516 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
517 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
518 0xFF,
519 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
520 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
521 0xFC,
522 0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65, /* b */
523 0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA,
524 0x45,
525 0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46, /* x */
526 0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC,
527 0x82,
528 0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59, /* y */
529 0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb,
530 0x32,
531 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
532 0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22,
533 0x57 }
534 };
535
536static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
537 _EC_SECG_PRIME_160R2 = {
538 { NID_X9_62_prime_field,20,21,1 },
539 { 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, /* seed */
540 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51,
541
542 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
543 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
544 0x73,
545 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
546 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
547 0x70,
548 0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB, /* b */
549 0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88,
550 0xBA,
551 0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F, /* x */
552 0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE,
553 0x6D,
554 0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0, /* y */
555 0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f,
556 0x2e,
557 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
558 0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1,
559 0x6B }
560 };
561
562static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
563 _EC_SECG_PRIME_192K1 = {
564 { NID_X9_62_prime_field,0,24,1 },
565 { /* no seed */
566 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
567 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
568 0xFF,0xFF,0xEE,0x37,
569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
570 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
571 0x00,0x00,0x00,0x00,
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
574 0x00,0x00,0x00,0x03,
575 0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0, /* x */
576 0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1,
577 0xEA,0xE0,0x6C,0x7D,
578 0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41, /* y */
579 0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88,
580 0xd9,0x5e,0x2f,0x9d,
581 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
582 0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A,
583 0x74,0xDE,0xFD,0x8D }
584 };
585
586static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; }
587 _EC_SECG_PRIME_224K1 = {
588 { NID_X9_62_prime_field,0,29,1 },
589 { /* no seed */
590 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
591 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
592 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D,
593 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
594 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
595 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
596 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
597 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
598 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
599 0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30, /* x */
600 0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75,
601 0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C,
602 0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82, /* y */
603 0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd,
604 0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5,
605 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
606 0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61,
607 0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 }
608 };
609
610static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; }
611 _EC_SECG_PRIME_256K1 = {
612 { NID_X9_62_prime_field,0,32,1 },
613 { /* no seed */
614 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
615 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
616 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,
617 0xFC,0x2F,
618 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
619 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
620 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
621 0x00,0x00,
622 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
623 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
624 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
625 0x00,0x07,
626 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0, /* x */
627 0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB,
628 0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
629 0x17,0x98,
630 0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4, /* y */
631 0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,
632 0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,
633 0xd4,0xb8,
634 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
635 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,
636 0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36,
637 0x41,0x41 }
638 };
639
640/* some wap/wtls curves */
641static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
642 _EC_WTLS_8 = {
643 { NID_X9_62_prime_field,0,15,1 },
644 { /* no seed */
645 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
646 0xFF,0xFF,0xFF,0xFD,0xE7,
647 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
648 0x00,0x00,0x00,0x00,0x00,
649 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
650 0x00,0x00,0x00,0x00,0x03,
651 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
652 0x00,0x00,0x00,0x00,0x01,
653 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
654 0x00,0x00,0x00,0x00,0x02,
655 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA, /* order */
656 0x55,0x1A,0xD8,0x37,0xE9 }
657 };
658
659static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
660 _EC_WTLS_9 = {
661 { NID_X9_62_prime_field,0,21,1 },
662 { /* no seed */
663 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
664 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80,
665 0x8F,
666 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
667 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
668 0x00,
669 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
670 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
671 0x03,
672 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
673 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
674 0x01,
675 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
676 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
677 0x02,
678 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
679 0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF,
680 0x33 }
681 };
682
683static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; }
684 _EC_WTLS_12 = {
685 { NID_X9_62_prime_field,0,28,1 },
686 { /* no seed */
687 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
688 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
689 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
690 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
691 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
692 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
693 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
694 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
695 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
696 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
697 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
698 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
699 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
700 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
701 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
702 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
703 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
704 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
705 };
706
707#ifndef OPENSSL_NO_EC2M
708
709/* characteristic two curves */
710static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
711 _EC_SECG_CHAR2_113R1 = {
712 { NID_X9_62_characteristic_two_field,20,15,2 },
713 { 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, /* seed */
714 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9,
715
716 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
717 0x00,0x00,0x00,0x02,0x01,
718 0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64, /* a */
719 0x9C,0xE8,0x58,0x20,0xF7,
720 0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18, /* b */
721 0x8B,0xE0,0xE9,0xC7,0x23,
722 0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07, /* x */
723 0xD7,0x35,0x62,0xC1,0x0F,
724 0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1, /* y */
725 0x31,0x5E,0xD3,0x18,0x86,
726 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC, /* order */
727 0xEC,0x8A,0x39,0xE5,0x6F }
728 };
729
730static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
731 _EC_SECG_CHAR2_113R2 = {
732 { NID_X9_62_characteristic_two_field,20,15,2 },
733 { 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, /* seed */
734 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D,
735
736 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
737 0x00,0x00,0x00,0x02,0x01,
738 0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6, /* a */
739 0xDF,0xC0,0xAA,0x55,0xC7,
740 0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF, /* b */
741 0x36,0xE0,0x59,0x18,0x4F,
742 0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F, /* x */
743 0xCD,0xB8,0x16,0x47,0x97,
744 0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06, /* y */
745 0xE6,0x95,0xBA,0xBA,0x1D,
746 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78, /* order */
747 0x9B,0x24,0x96,0xAF,0x93 }
748 };
749
750static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
751 _EC_SECG_CHAR2_131R1 = {
752 { NID_X9_62_characteristic_two_field,20,17,2 },
753 { 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, /* seed */
754 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2,
755
756 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
757 0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
758 0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41, /* a */
759 0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8,
760 0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6, /* b */
761 0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41,
762 0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F, /* x */
763 0x9C,0x18,0x13,0x43,0x63,0x83,0x99,
764 0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8, /* y */
765 0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50,
766 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31, /* order */
767 0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D }
768 };
769
770static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
771 _EC_SECG_CHAR2_131R2 = {
772 { NID_X9_62_characteristic_two_field,20,17,2 },
773 { 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, /* seed */
774 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3,
775
776 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
777 0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
778 0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41, /* a */
779 0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2,
780 0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73, /* b */
781 0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92,
782 0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65, /* x */
783 0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8,
784 0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D, /* y */
785 0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F,
786 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69, /* order */
787 0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F }
788 };
789
790static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
791 _EC_NIST_CHAR2_163K = {
792 { NID_X9_62_characteristic_two_field,0,21,2 },
793 { /* no seed */
794 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
795 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
796 0xC9,
797 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
798 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
799 0x01,
800 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
801 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
802 0x01,
803 0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA, /* x */
804 0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE,
805 0xE8,
806 0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32, /* y */
807 0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3,
808 0xD9,
809 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
810 0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5,
811 0xEF }
812 };
813
814static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
815 _EC_SECG_CHAR2_163R1 = {
816 { NID_X9_62_characteristic_two_field,0,21,2 },
817 { /* no seed */
818#if 0
819/* The algorithm used to derive the curve parameters from
820 * the seed used here is slightly different than the
821 * algorithm described in X9.62 . */
822 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
823 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C,
824#endif
825 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
826 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
827 0xC9,
828 0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54, /* a */
829 0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A,
830 0xE2,
831 0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94, /* b */
832 0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF,
833 0xD9,
834 0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89, /* x */
835 0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6,
836 0x54,
837 0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D, /* y */
838 0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8,
839 0x83,
840 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
841 0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27,
842 0x9B }
843 };
844
845static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
846 _EC_NIST_CHAR2_163B = {
847 { NID_X9_62_characteristic_two_field,0,21,2 },
848 { /* no seed */
849#if 0
850/* The seed here was used to created the curve parameters in normal
851 * basis representation (and not the polynomial representation used here) */
852 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
853 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68,
854#endif
855 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
856 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
857 0xC9,
858 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
859 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
860 0x01,
861 0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14, /* b */
862 0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05,
863 0xFD,
864 0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0, /* x */
865 0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E,
866 0x36,
867 0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2, /* y */
868 0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24,
869 0xF1,
870 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
871 0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C,
872 0x33 }
873 };
874
875static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
876 _EC_SECG_CHAR2_193R1 = {
877 { NID_X9_62_characteristic_two_field,20,25,2 },
878 { 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, /* seed */
879 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30,
880
881 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
882 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
883 0x00,0x00,0x00,0x80,0x01,
884 0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69, /* a */
885 0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8,
886 0xA9,0x11,0xDF,0x7B,0x01,
887 0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC, /* b */
888 0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5,
889 0xD8,0x31,0x47,0x88,0x14,
890 0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD, /* x */
891 0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53,
892 0x72,0xD8,0xC0,0xC5,0xE1,
893 0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3, /* y */
894 0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B,
895 0x6A,0xF7,0xCE,0x1B,0x05,
896 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
897 0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A,
898 0xCC,0x92,0x0E,0xBA,0x49 }
899 };
900
901static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
902 _EC_SECG_CHAR2_193R2 = {
903 { NID_X9_62_characteristic_two_field,20,25,2 },
904 { 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, /* seed */
905 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11,
906
907 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
908 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
909 0x00,0x00,0x00,0x80,0x01,
910 0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6, /* a */
911 0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69,
912 0x97,0x77,0x02,0x70,0x9B,
913 0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37, /* b */
914 0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7,
915 0xF6,0x1D,0x43,0x16,0xAE,
916 0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03, /* x */
917 0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35,
918 0x0A,0xAE,0x61,0x7E,0x8F,
919 0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29, /* y */
920 0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27,
921 0x22,0x4C,0xDE,0xCF,0x6C,
922 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
923 0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13,
924 0xCC,0xD4,0xEE,0x99,0xD5 }
925 };
926
927static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
928 _EC_NIST_CHAR2_233K = {
929 { NID_X9_62_characteristic_two_field,0,30,4 },
930 { /* no seed */
931 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
932 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
933 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
934
935 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
936 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
937 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
938
939 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
940 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
941 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
942
943 0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1, /* x */
944 0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2,
945 0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26,
946
947 0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F, /* y */
948 0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A,
949 0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3,
950
951 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
952 0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15,
953 0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF }
954 };
955
956static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
957 _EC_NIST_CHAR2_233B = {
958 { NID_X9_62_characteristic_two_field,20,30,2 },
959 { 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, /* seed */
960 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3,
961
962 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
963 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
964 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
965
966 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
967 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
968 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
969
970 0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C, /* b */
971 0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9,
972 0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD,
973
974 0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21, /* x */
975 0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F,
976 0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B,
977
978 0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78, /* y */
979 0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67,
980 0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52,
981
982 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
983 0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F,
984 0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 }
985 };
986
987static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
988 _EC_SECG_CHAR2_239K1 = {
989 { NID_X9_62_characteristic_two_field,0,30,4 },
990 { /* no seed */
991 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
992 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
993 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
994
995 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
996 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
997 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
998
999 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1000 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1001 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1002
1003 0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09, /* x */
1004 0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C,
1005 0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC,
1006
1007 0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01, /* y */
1008 0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75,
1009 0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA,
1010
1011 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1012 0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C,
1013 0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 }
1014 };
1015
1016static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; }
1017 _EC_NIST_CHAR2_283K = {
1018 { NID_X9_62_characteristic_two_field,0,36,4 },
1019 { /* no seed */
1020 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1021 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1022 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1023 0x00,0x00,0x00,0x00,0x10,0xA1,
1024 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1025 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1026 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1027 0x00,0x00,0x00,0x00,0x00,0x00,
1028 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1029 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1030 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1031 0x00,0x00,0x00,0x00,0x00,0x01,
1032 0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A, /* x */
1033 0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F,
1034 0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2,
1035 0xAC,0x24,0x58,0x49,0x28,0x36,
1036 0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90, /* y */
1037 0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0,
1038 0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34,
1039 0x11,0x61,0x77,0xDD,0x22,0x59,
1040 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1041 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE,
1042 0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45,
1043 0x1E,0x06,0x1E,0x16,0x3C,0x61 }
1044 };
1045
1046static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; }
1047 _EC_NIST_CHAR2_283B = {
1048 { NID_X9_62_characteristic_two_field,20,36,2 },
1049 { 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, /* no seed */
1050 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE,
1051
1052 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1053 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1054 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1055 0x00,0x00,0x00,0x00,0x10,0xA1,
1056 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1057 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1058 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1059 0x00,0x00,0x00,0x00,0x00,0x01,
1060 0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4, /* b */
1061 0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76,
1062 0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26,
1063 0x3E,0x31,0x3B,0x79,0xA2,0xF5,
1064 0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93, /* x */
1065 0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8,
1066 0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD,
1067 0xBE,0xCD,0x86,0xB1,0x20,0x53,
1068 0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F, /* y */
1069 0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02,
1070 0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0,
1071 0xDF,0x45,0xBE,0x81,0x12,0xF4,
1072 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1073 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90,
1074 0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04,
1075 0x2A,0x7C,0xEF,0xAD,0xB3,0x07 }
1076 };
1077
1078static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; }
1079 _EC_NIST_CHAR2_409K = {
1080 { NID_X9_62_characteristic_two_field,0,52,4 },
1081 { /* no seed */
1082 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1083 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1084 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1085 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1086 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1087 0x00,0x01,
1088 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1089 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1090 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1091 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1092 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1093 0x00,0x00,
1094 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1095 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1096 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1097 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1098 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1099 0x00,0x01,
1100 0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A, /* x */
1101 0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87,
1102 0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6,
1103 0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62,
1104 0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02,
1105 0x37,0x46,
1106 0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA, /* y */
1107 0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F,
1108 0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA,
1109 0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15,
1110 0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0,
1111 0x28,0x6B,
1112 0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1113 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1114 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2,
1115 0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3,
1116 0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E,
1117 0x5F,0xCF }
1118 };
1119
1120static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; }
1121 _EC_NIST_CHAR2_409B = {
1122 { NID_X9_62_characteristic_two_field,20,52,2 },
1123 { 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, /* seed */
1124 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B,
1125
1126 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1127 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1128 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1129 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1130 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1131 0x00,0x01,
1132 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1133 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1135 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1136 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1137 0x00,0x01,
1138 0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B, /* b */
1139 0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E,
1140 0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC,
1141 0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C,
1142 0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13,
1143 0x54,0x5F,
1144 0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B, /* x */
1145 0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A,
1146 0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5,
1147 0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51,
1148 0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79,
1149 0x96,0xA7,
1150 0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF, /* y */
1151 0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5,
1152 0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88,
1153 0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40,
1154 0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73,
1155 0xC7,0x06,
1156 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1157 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1158 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6,
1159 0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C,
1160 0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2,
1161 0x11,0x73 }
1162 };
1163
1164static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; }
1165 _EC_NIST_CHAR2_571K = {
1166 { NID_X9_62_characteristic_two_field,0,72,4 },
1167 { /* no seed */
1168 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
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 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1173 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1174 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1175 0x04,0x25,
1176 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1181 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1182 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1183 0x00,0x00,
1184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1189 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1190 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1191 0x00,0x01,
1192 0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18, /* x */
1193 0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97,
1194 0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84,
1195 0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6,
1196 0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1,
1197 0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17,
1198 0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C,
1199 0x89,0x72,
1200 0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A, /* y */
1201 0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC,
1202 0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D,
1203 0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7,
1204 0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20,
1205 0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8,
1206 0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1,
1207 0xC7,0xA3,
1208 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1209 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1210 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1211 0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1,
1212 0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F,
1213 0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38,
1214 0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C,
1215 0x10,0x01 }
1216 };
1217
1218static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; }
1219 _EC_NIST_CHAR2_571B = {
1220 { NID_X9_62_characteristic_two_field,20,72,2 },
1221 { 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, /* seed */
1222 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10,
1223
1224 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
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 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1229 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1230 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1231 0x04,0x25,
1232 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1237 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1238 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1239 0x00,0x01,
1240 0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29, /* b */
1241 0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF,
1242 0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A,
1243 0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33,
1244 0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD,
1245 0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7,
1246 0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55,
1247 0x72,0x7A,
1248 0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16, /* x */
1249 0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2,
1250 0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B,
1251 0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93,
1252 0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE,
1253 0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4,
1254 0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC,
1255 0x2D,0x19,
1256 0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC, /* y */
1257 0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6,
1258 0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21,
1259 0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57,
1260 0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53,
1261 0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51,
1262 0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A,
1263 0xC1,0x5B,
1264 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1265 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1266 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1267 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18,
1268 0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23,
1269 0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D,
1270 0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8,
1271 0x4E,0x47 }
1272 };
1273
1274static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
1275 _EC_X9_62_CHAR2_163V1 = {
1276 { NID_X9_62_characteristic_two_field,20,21,2 },
1277 { 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
1278 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54, /* seed */
1279
1280 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1281 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1282 0x07,
1283 0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0, /* a */
1284 0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52,
1285 0x42,
1286 0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF, /* b */
1287 0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4,
1288 0xD9,
1289 0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32, /* x */
1290 0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03,
1291 0xCB,
1292 0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D, /* y */
1293 0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA,
1294 0x9F,
1295 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1296 0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF,
1297 0xC1 }
1298 };
1299
1300static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
1301 _EC_X9_62_CHAR2_163V2 = {
1302 { NID_X9_62_characteristic_two_field,20,21,2 },
1303 { 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, /* seed */
1304 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD,
1305
1306 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1307 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1308 0x07,
1309 0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9, /* a */
1310 0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0,
1311 0x72,
1312 0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40, /* b */
1313 0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF,
1314 0x20,
1315 0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96, /* x */
1316 0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C,
1317 0xC5,
1318 0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25, /* y */
1319 0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F,
1320 0xC5,
1321 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1322 0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10,
1323 0xA7 }
1324 };
1325
1326static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
1327 _EC_X9_62_CHAR2_163V3 = {
1328 { NID_X9_62_characteristic_two_field,20,21,2 },
1329 { 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, /* seed */
1330 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8,
1331
1332 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1333 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1334 0x07,
1335 0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0, /* a */
1336 0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5,
1337 0x0E,
1338 0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD, /* b */
1339 0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25,
1340 0x2B,
1341 0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF, /* x */
1342 0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD,
1343 0xCB,
1344 0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48, /* y */
1345 0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05,
1346 0xD0,
1347 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1348 0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13,
1349 0x09 }
1350 };
1351
1352static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; }
1353 _EC_X9_62_CHAR2_176V1 = {
1354 { NID_X9_62_characteristic_two_field,0,23,0xFF6E },
1355 { /* no seed */
1356 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1357 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
1358 0x00,0x00,0x07,
1359 0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D, /* a */
1360 0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8,
1361 0xE9,0xC9,0x0B,
1362 0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E, /* b */
1363 0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A,
1364 0xE0,0xFF,0xF2,
1365 0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9, /* x */
1366 0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0,
1367 0x4A,0x57,0x98,
1368 0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA, /* y */
1369 0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1,
1370 0x6A,0x56,0x2C,
1371 0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4, /* order */
1372 0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06,
1373 0xFE,0x26,0xAD }
1374 };
1375
1376static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
1377 _EC_X9_62_CHAR2_191V1 = {
1378 { NID_X9_62_characteristic_two_field,20,24,2 },
1379 { 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, /* seed */
1380 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84,
1381
1382 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1383 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1384 0x00,0x00,0x02,0x01,
1385 0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68, /* a */
1386 0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E,
1387 0xF7,0x52,0x62,0x67,
1388 0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0, /* b */
1389 0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE,
1390 0x0A,0xA1,0x85,0xEC,
1391 0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2, /* x */
1392 0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8,
1393 0x4A,0xE1,0xAA,0x0D,
1394 0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29, /* y */
1395 0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E,
1396 0xF9,0x80,0x18,0xFB,
1397 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1398 0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8,
1399 0x93,0xBB,0xB9,0xA5 }
1400 };
1401
1402static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
1403 _EC_X9_62_CHAR2_191V2 = {
1404 { NID_X9_62_characteristic_two_field,20,24,4 },
1405 { 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, /* seed */
1406 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15,
1407
1408 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1409 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1410 0x00,0x00,0x02,0x01,
1411 0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66, /* a */
1412 0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89,
1413 0xFF,0x01,0xE7,0x18,
1414 0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24, /* b */
1415 0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3,
1416 0x62,0xC4,0x6A,0x01,
1417 0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87, /* x */
1418 0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2,
1419 0xC9,0xE3,0xBF,0x10,
1420 0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0, /* y */
1421 0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC,
1422 0x43,0x7D,0x66,0x8A,
1423 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1424 0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24,
1425 0xE0,0x6B,0x81,0x73 }
1426 };
1427
1428static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
1429 _EC_X9_62_CHAR2_191V3 = {
1430 { NID_X9_62_characteristic_two_field,20,24,6 },
1431 { 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, /* seed */
1432 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F,
1433
1434 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1435 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1436 0x00,0x00,0x02,0x01,
1437 0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10, /* a */
1438 0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7,
1439 0xE7,0xE7,0x7F,0xCB,
1440 0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF, /* b */
1441 0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32,
1442 0xAD,0x3F,0x15,0xE8,
1443 0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE, /* x */
1444 0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E,
1445 0x38,0xA9,0x26,0xDD,
1446 0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59, /* y */
1447 0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7,
1448 0x12,0x7B,0x06,0xBE,
1449 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */
1450 0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6,
1451 0x28,0x8A,0x3E,0xA3 }
1452 };
1453
1454static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; }
1455 _EC_X9_62_CHAR2_208W1 = {
1456 { NID_X9_62_characteristic_two_field,0,27,0xFE48 },
1457 { /* no seed */
1458 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1459 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
1460 0x00,0x00,0x00,0x00,0x00,0x00,0x07,
1461 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1462 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1463 0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1464 0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E, /* b */
1465 0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA,
1466 0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E,
1467 0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95, /* x */
1468 0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27,
1469 0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A,
1470 0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3, /* y */
1471 0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE,
1472 0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3,
1473 0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5, /* order */
1474 0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88,
1475 0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D }
1476 };
1477
1478static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
1479 _EC_X9_62_CHAR2_239V1 = {
1480 { NID_X9_62_characteristic_two_field,20,30,4 },
1481 { 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
1482 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D,
1483
1484 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1485 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1486 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
1487
1488 0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A, /* a */
1489 0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E,
1490 0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76,
1491
1492 0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12, /* b */
1493 0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C,
1494 0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16,
1495
1496 0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96, /* x */
1497 0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56,
1498 0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D,
1499
1500 0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1, /* y */
1501 0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E,
1502 0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05,
1503
1504 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1505 0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1,
1506 0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 }
1507 };
1508
1509static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
1510 _EC_X9_62_CHAR2_239V2 = {
1511 { NID_X9_62_characteristic_two_field,20,30,6 },
1512 { 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, /* seed */
1513 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D,
1514
1515 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1516 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1517 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
1518
1519 0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23, /* a */
1520 0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF,
1521 0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F,
1522
1523 0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82, /* b */
1524 0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52,
1525 0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B,
1526
1527 0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47, /* x */
1528 0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7,
1529 0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05,
1530
1531 0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B, /* y */
1532 0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56,
1533 0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33,
1534
1535 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */
1536 0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25,
1537 0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D }
1538 };
1539
1540static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
1541 _EC_X9_62_CHAR2_239V3 = {
1542 { NID_X9_62_characteristic_two_field,20,30,0xA },
1543 { 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
1544 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41,
1545
1546 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1547 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1548 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
1549
1550 0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66, /* a */
1551 0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66,
1552 0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F,
1553
1554 0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99, /* b */
1555 0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5,
1556 0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40,
1557
1558 0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91, /* x */
1559 0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42,
1560 0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92,
1561
1562 0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00, /* y */
1563 0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08,
1564 0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61,
1565
1566 0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, /* order */
1567 0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9,
1568 0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF }
1569 };
1570
1571static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; }
1572 _EC_X9_62_CHAR2_272W1 = {
1573 { NID_X9_62_characteristic_two_field,0,35,0xFF06 },
1574 { /* no seed */
1575 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1576 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1577 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
1578 0x00,0x00,0x00,0x00,0x0B,
1579 0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2, /* a */
1580 0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71,
1581 0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA,
1582 0xCD,0xB5,0x86,0xFB,0x20,
1583 0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C, /* b */
1584 0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03,
1585 0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC,
1586 0x84,0x82,0xE5,0x40,0xF7,
1587 0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87, /* x */
1588 0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77,
1589 0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D,
1590 0x10,0xD1,0x71,0xDD,0x8D,
1591 0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B, /* y */
1592 0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8,
1593 0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02,
1594 0x00,0x5D,0xDE,0x9D,0x23,
1595 0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3, /* order */
1596 0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16,
1597 0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B,
1598 0x8F,0x1E,0x62,0x95,0x21 }
1599 };
1600
1601static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; }
1602 _EC_X9_62_CHAR2_304W1 = {
1603 { NID_X9_62_characteristic_two_field,0,39,0xFE2E },
1604 { /* no seed */
1605 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1606 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1607 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1608 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07,
1609 0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51, /* a */
1610 0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88,
1611 0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28,
1612 0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81,
1613 0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E, /* b */
1614 0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F,
1615 0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1,
1616 0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE,
1617 0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A, /* x */
1618 0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E,
1619 0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD,
1620 0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14,
1621 0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51, /* y */
1622 0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10,
1623 0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80,
1624 0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B,
1625 0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC, /* order */
1626 0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80,
1627 0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5,
1628 0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D }
1629 };
1630
1631static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; }
1632 _EC_X9_62_CHAR2_359V1 = {
1633 { NID_X9_62_characteristic_two_field,20,45,0x4C },
1634 { 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, /* seed */
1635 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6,
1636
1637 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1638 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1639 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1640 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
1641 0x00,0x00,0x00,0x00,0x01,
1642 0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35, /* a */
1643 0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67,
1644 0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67,
1645 0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16,
1646 0xA9,0x66,0x56,0xA5,0x57,
1647 0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F, /* b */
1648 0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D,
1649 0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34,
1650 0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7,
1651 0x06,0x80,0x23,0x19,0x88,
1652 0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0, /* x */
1653 0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A,
1654 0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF,
1655 0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A,
1656 0x22,0x39,0xB1,0xB0,0x97,
1657 0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E, /* y */
1658 0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48,
1659 0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC,
1660 0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30,
1661 0x5A,0x40,0x71,0x04,0xBD,
1662 0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1, /* order */
1663 0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF,
1664 0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89,
1665 0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74,
1666 0xF4,0x90,0x75,0x8D,0x3B }
1667 };
1668
1669static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; }
1670 _EC_X9_62_CHAR2_368W1 = {
1671 { NID_X9_62_characteristic_two_field,0,47,0xFF70 },
1672 { /* no seed */
1673 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1674 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1675 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1676 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
1677 0x00,0x00,0x00,0x00,0x00,0x00,0x07,
1678 0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2, /* a */
1679 0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0,
1680 0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9,
1681 0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C,
1682 0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D,
1683 0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C, /* b */
1684 0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B,
1685 0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5,
1686 0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4,
1687 0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A,
1688 0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3, /* x */
1689 0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82,
1690 0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B,
1691 0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21,
1692 0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F,
1693 0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8, /* y */
1694 0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C,
1695 0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE,
1696 0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A,
1697 0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10,
1698 0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72, /* order */
1699 0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53,
1700 0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A,
1701 0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1,
1702 0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 }
1703 };
1704
1705static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; }
1706 _EC_X9_62_CHAR2_431R1 = {
1707 { NID_X9_62_characteristic_two_field,0,54,0x2760 },
1708 { /* no seed */
1709 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1710 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1711 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1712 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
1713 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1714 0x00,0x00,0x00,0x01,
1715 0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C, /* a */
1716 0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23,
1717 0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9,
1718 0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F,
1719 0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D,
1720 0xE2,0x96,0xCD,0x8F,
1721 0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43, /* b */
1722 0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB,
1723 0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67,
1724 0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD,
1725 0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8,
1726 0x07,0xBF,0x26,0x18,
1727 0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61, /* x */
1728 0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4,
1729 0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2,
1730 0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65,
1731 0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB,
1732 0xD7,0x0C,0xE6,0xB7,
1733 0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2, /* y */
1734 0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93,
1735 0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B,
1736 0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C,
1737 0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A,
1738 0x59,0x8B,0x37,0x60,
1739 0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34, /* order */
1740 0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,
1741 0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23,
1742 0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6,
1743 0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49,
1744 0xC1,0xAD,0x4A,0x91 }
1745 };
1746
1747static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
1748 _EC_WTLS_1 = {
1749 { NID_X9_62_characteristic_two_field,0,15,2 },
1750 { /* no seed */
1751 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1752 0x00,0x00,0x00,0x02,0x01,
1753 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1754 0x00,0x00,0x00,0x00,0x01,
1755 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1756 0x00,0x00,0x00,0x00,0x01,
1757 0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5, /* x */
1758 0xC2,0x70,0x78,0x06,0x17,
1759 0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08, /* y */
1760 0x78,0x5C,0xEB,0xCC,0x15,
1761 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF, /* order */
1762 0x91,0xAF,0x6D,0xEA,0x73 }
1763 };
1764
1765/* IPSec curves */
1766/* NOTE: The of curves over a extension field of non prime degree
1767 * is not recommended (Weil-descent).
1768 * As the group order is not a prime this curve is not suitable
1769 * for ECDSA.
1770 */
1771static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; }
1772 _EC_IPSEC_155_ID3 = {
1773 { NID_X9_62_characteristic_two_field,0,20,3 },
1774 { /* no seed */
1775 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1776 0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1777
1778 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1779 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1780
1781 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1782 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f,
1783
1784 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
1785 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,
1786
1787 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
1788 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8,
1789
1790 0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, /* order */
1791 0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C }
1792 };
1793
1794/* NOTE: The of curves over a extension field of non prime degree
1795 * is not recommended (Weil-descent).
1796 * As the group order is not a prime this curve is not suitable
1797 * for ECDSA.
1798 */
1799static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
1800 _EC_IPSEC_185_ID4 = {
1801 { NID_X9_62_characteristic_two_field,0,24,2 },
1802 { /* no seed */
1803 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1804 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,
1805 0x00,0x00,0x00,0x01,
1806 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1807 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1808 0x00,0x00,0x00,0x00,
1809 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1810 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1811 0x00,0x00,0x1e,0xe9,
1812 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
1813 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1814 0x00,0x00,0x00,0x18,
1815 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
1816 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1817 0x00,0x00,0x00,0x0d,
1818 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1819 0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20,
1820 0xBA,0xFC,0xA7,0x5E }
1821 };
1822
1823#endif
1824
1825typedef struct _ec_list_element_st {
1826 int nid;
1827 const EC_CURVE_DATA *data;
1828 const EC_METHOD *(*meth)(void);
1829 const char *comment;
1830 } ec_list_element;
1831
1832static const ec_list_element curve_list[] = {
1833 /* prime field curves */
1834 /* secg curves */
1835 { NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field" },
1836 { NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, "SECG curve over a 112 bit prime field" },
1837 { NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, "SECG curve over a 128 bit prime field" },
1838 { NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, "SECG curve over a 128 bit prime field" },
1839 { NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, "SECG curve over a 160 bit prime field" },
1840 { NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, "SECG curve over a 160 bit prime field" },
1841 { NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field" },
1842 /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
1843 { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field" },
1844 { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field" },
1845#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1846 { NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field" },
1847#else
1848 { NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field" },
1849#endif
1850 { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field" },
1851 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
1852 { NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field" },
1853#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1854 { NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field" },
1855#else
1856 { NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field" },
1857#endif
1858 /* X9.62 curves */
1859 { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field" },
1860 { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, "X9.62 curve over a 192 bit prime field" },
1861 { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, "X9.62 curve over a 192 bit prime field" },
1862 { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field" },
1863 { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field" },
1864 { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field" },
1865#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1866 { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field" },
1867#else
1868 { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field" },
1869#endif
1870#ifndef OPENSSL_NO_EC2M
1871 /* characteristic two field curves */
1872 /* NIST/SECG curves */
1873 { NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
1874 { NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, "SECG curve over a 113 bit binary field" },
1875 { NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, "SECG/WTLS curve over a 131 bit binary field" },
1876 { NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, "SECG curve over a 131 bit binary field" },
1877 { NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field" },
1878 { NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, "SECG curve over a 163 bit binary field" },
1879 { NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, "NIST/SECG curve over a 163 bit binary field" },
1880 { NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, "SECG curve over a 193 bit binary field" },
1881 { NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, "SECG curve over a 193 bit binary field" },
1882 { NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1883 { NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1884 { NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, "SECG curve over a 239 bit binary field" },
1885 { NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, "NIST/SECG curve over a 283 bit binary field" },
1886 { NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, "NIST/SECG curve over a 283 bit binary field" },
1887 { NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, "NIST/SECG curve over a 409 bit binary field" },
1888 { NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, "NIST/SECG curve over a 409 bit binary field" },
1889 { NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, "NIST/SECG curve over a 571 bit binary field" },
1890 { NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, "NIST/SECG curve over a 571 bit binary field" },
1891 /* X9.62 curves */
1892 { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field" },
1893 { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, "X9.62 curve over a 163 bit binary field" },
1894 { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, "X9.62 curve over a 163 bit binary field" },
1895 { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, "X9.62 curve over a 176 bit binary field" },
1896 { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, "X9.62 curve over a 191 bit binary field" },
1897 { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, "X9.62 curve over a 191 bit binary field" },
1898 { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, "X9.62 curve over a 191 bit binary field" },
1899 { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, "X9.62 curve over a 208 bit binary field" },
1900 { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, "X9.62 curve over a 239 bit binary field" },
1901 { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, "X9.62 curve over a 239 bit binary field" },
1902 { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, "X9.62 curve over a 239 bit binary field" },
1903 { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, "X9.62 curve over a 272 bit binary field" },
1904 { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, "X9.62 curve over a 304 bit binary field" },
1905 { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, "X9.62 curve over a 359 bit binary field" },
1906 { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, "X9.62 curve over a 368 bit binary field" },
1907 { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, "X9.62 curve over a 431 bit binary field" },
1908 /* the WAP/WTLS curves
1909 * [unlike SECG, spec has its own OIDs for curves from X9.62] */
1910 { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, "WTLS curve over a 113 bit binary field" },
1911 { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field" },
1912 { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
1913 { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field" },
1914#endif
1915 { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field" },
1916 { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field" },
1917 { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, "WTLS curve over a 112 bit prime field" },
1918 { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field" },
1919#ifndef OPENSSL_NO_EC2M
1920 { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1921 { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1922#endif
1923 { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curvs over a 224 bit prime field" },
1924#ifndef OPENSSL_NO_EC2M
1925 /* IPSec curves */
1926 { NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
1927 "\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
1928 { NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
1929 "\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
1930#endif
1931};
1932
1933#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
1934
1935static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
1936 {
1937 EC_GROUP *group=NULL;
1938 EC_POINT *P=NULL;
1939 BN_CTX *ctx=NULL;
1940 BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
1941 int ok=0;
1942 int seed_len,param_len;
1943 const EC_METHOD *meth;
1944 const EC_CURVE_DATA *data;
1945 const unsigned char *params;
1946
1947 if ((ctx = BN_CTX_new()) == NULL)
1948 {
1949 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
1950 goto err;
1951 }
1952
1953 data = curve.data;
1954 seed_len = data->seed_len;
1955 param_len = data->param_len;
1956 params = (const unsigned char *)(data+1); /* skip header */
1957 params += seed_len; /* skip seed */
1958
1959 if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
1960 || !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
1961 || !(b = BN_bin2bn(params+2*param_len, param_len, NULL)))
1962 {
1963 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1964 goto err;
1965 }
1966
1967 if (curve.meth != 0)
1968 {
1969 meth = curve.meth();
1970 if (((group = EC_GROUP_new(meth)) == NULL) ||
1971 (!(group->meth->group_set_curve(group, p, a, b, ctx))))
1972 {
1973 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1974 goto err;
1975 }
1976 }
1977 else if (data->field_type == NID_X9_62_prime_field)
1978 {
1979 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
1980 {
1981 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1982 goto err;
1983 }
1984 }
1985#ifndef OPENSSL_NO_EC2M
1986 else /* field_type == NID_X9_62_characteristic_two_field */
1987 {
1988 if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
1989 {
1990 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1991 goto err;
1992 }
1993 }
1994#endif
1995
1996 if ((P = EC_POINT_new(group)) == NULL)
1997 {
1998 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1999 goto err;
2000 }
2001
2002 if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
2003 || !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
2004 {
2005 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
2006 goto err;
2007 }
2008 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
2009 {
2010 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
2011 goto err;
2012 }
2013 if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
2014 || !BN_set_word(x, (BN_ULONG)data->cofactor))
2015 {
2016 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
2017 goto err;
2018 }
2019 if (!EC_GROUP_set_generator(group, P, order, x))
2020 {
2021 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
2022 goto err;
2023 }
2024 if (seed_len)
2025 {
2026 if (!EC_GROUP_set_seed(group, params-seed_len, seed_len))
2027 {
2028 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
2029 goto err;
2030 }
2031 }
2032 ok=1;
2033err:
2034 if (!ok)
2035 {
2036 EC_GROUP_free(group);
2037 group = NULL;
2038 }
2039 if (P)
2040 EC_POINT_free(P);
2041 if (ctx)
2042 BN_CTX_free(ctx);
2043 if (p)
2044 BN_free(p);
2045 if (a)
2046 BN_free(a);
2047 if (b)
2048 BN_free(b);
2049 if (order)
2050 BN_free(order);
2051 if (x)
2052 BN_free(x);
2053 if (y)
2054 BN_free(y);
2055 return group;
2056 }
2057
2058EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
2059 {
2060 size_t i;
2061 EC_GROUP *ret = NULL;
2062
2063 if (nid <= 0)
2064 return NULL;
2065
2066 for (i=0; i<curve_list_length; i++)
2067 if (curve_list[i].nid == nid)
2068 {
2069 ret = ec_group_new_from_data(curve_list[i]);
2070 break;
2071 }
2072
2073 if (ret == NULL)
2074 {
2075 ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
2076 return NULL;
2077 }
2078
2079 EC_GROUP_set_curve_name(ret, nid);
2080
2081 return ret;
2082 }
2083
2084size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
2085 {
2086 size_t i, min;
2087
2088 if (r == NULL || nitems == 0)
2089 return curve_list_length;
2090
2091 min = nitems < curve_list_length ? nitems : curve_list_length;
2092
2093 for (i = 0; i < min; i++)
2094 {
2095 r[i].nid = curve_list[i].nid;
2096 r[i].comment = curve_list[i].comment;
2097 }
2098
2099 return curve_list_length;
2100 }
diff --git a/src/lib/libcrypto/ec/ec_cvt.c b/src/lib/libcrypto/ec/ec_cvt.c
deleted file mode 100644
index bfcbab35fe..0000000000
--- a/src/lib/libcrypto/ec/ec_cvt.c
+++ /dev/null
@@ -1,170 +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#if defined(OPENSSL_BN_ASM_MONT)
82 /*
83 * This might appear controversial, but the fact is that generic
84 * prime method was observed to deliver better performance even
85 * for NIST primes on a range of platforms, e.g.: 60%-15%
86 * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
87 * in 32-bit build and 35%--12% in 64-bit build on Core2...
88 * Coefficients are relative to optimized bn_nist.c for most
89 * intensive ECDSA verify and ECDH operations for 192- and 521-
90 * bit keys respectively. Choice of these boundary values is
91 * arguable, because the dependency of improvement coefficient
92 * from key length is not a "monotone" curve. For example while
93 * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
94 * generally faster, sometimes "respectfully" faster, sometimes
95 * "tolerably" slower... What effectively happens is that loop
96 * with bn_mul_add_words is put against bn_mul_mont, and the
97 * latter "wins" on short vectors. Correct solution should be
98 * implementing dedicated NxN multiplication subroutines for
99 * small N. But till it materializes, let's stick to generic
100 * prime method...
101 * <appro>
102 */
103 meth = EC_GFp_mont_method();
104#else
105 meth = EC_GFp_nist_method();
106#endif
107
108 ret = EC_GROUP_new(meth);
109 if (ret == NULL)
110 return NULL;
111
112 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
113 {
114 unsigned long err;
115
116 err = ERR_peek_last_error();
117
118 if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
119 ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
120 (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME))))
121 {
122 /* real error */
123
124 EC_GROUP_clear_free(ret);
125 return NULL;
126 }
127
128
129 /* not an actual error, we just cannot use EC_GFp_nist_method */
130
131 ERR_clear_error();
132
133 EC_GROUP_clear_free(ret);
134 meth = EC_GFp_mont_method();
135
136 ret = EC_GROUP_new(meth);
137 if (ret == NULL)
138 return NULL;
139
140 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
141 {
142 EC_GROUP_clear_free(ret);
143 return NULL;
144 }
145 }
146
147 return ret;
148 }
149
150#ifndef OPENSSL_NO_EC2M
151EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
152 {
153 const EC_METHOD *meth;
154 EC_GROUP *ret;
155
156 meth = EC_GF2m_simple_method();
157
158 ret = EC_GROUP_new(meth);
159 if (ret == NULL)
160 return NULL;
161
162 if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx))
163 {
164 EC_GROUP_clear_free(ret);
165 return NULL;
166 }
167
168 return ret;
169 }
170#endif
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
deleted file mode 100644
index 0d19398731..0000000000
--- a/src/lib/libcrypto/ec/ec_err.c
+++ /dev/null
@@ -1,276 +0,0 @@
1/* crypto/ec/ec_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2011 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_BN_TO_FELEM), "BN_TO_FELEM"},
74{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
75{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
76{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
77{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
78{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"},
79{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"},
80{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"},
81{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"},
82{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"},
83{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"},
84{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"},
85{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"},
86{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
87{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
88{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
89{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
90{ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"},
91{ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"},
92{ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"},
93{ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"},
94{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"},
95{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"},
96{ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"},
97{ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"},
98{ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"},
99{ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"},
100{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"},
101{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
102{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GF2m_simple_group_check_discriminant"},
103{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), "ec_GF2m_simple_group_set_curve"},
104{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
105{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
106{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GF2m_simple_point_get_affine_coordinates"},
107{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GF2m_simple_point_set_affine_coordinates"},
108{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GF2m_simple_set_compressed_coordinates"},
109{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
110{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
111{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
112{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), "ec_GFp_mont_field_set_to_one"},
113{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
114{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), "ec_GFp_mont_group_set_curve"},
115{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), "EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
116{ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), "ec_GFp_nistp224_group_set_curve"},
117{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
118{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp224_point_get_affine_coordinates"},
119{ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), "ec_GFp_nistp256_group_set_curve"},
120{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
121{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp256_point_get_affine_coordinates"},
122{ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), "ec_GFp_nistp521_group_set_curve"},
123{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
124{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp521_point_get_affine_coordinates"},
125{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
126{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
127{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
128{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GFp_simple_group_check_discriminant"},
129{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), "ec_GFp_simple_group_set_curve"},
130{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
131{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
132{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
133{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
134{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
135{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), "ec_GFp_simple_points_make_affine"},
136{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GFp_simple_point_get_affine_coordinates"},
137{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
138{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GFp_simple_point_set_affine_coordinates"},
139{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
140{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GFp_simple_set_compressed_coordinates"},
141{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
142{ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
143{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), "EC_GROUP_check_discriminant"},
144{ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
145{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"},
146{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"},
147{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
148{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
149{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
150{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
151{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), "EC_GROUP_get_pentanomial_basis"},
152{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"},
153{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
154{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
155{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
156{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"},
157{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
158{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
159{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"},
160{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
161{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
162{ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
163{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
164{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
165{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
166{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
167{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), "EC_KEY_set_public_key_affine_coordinates"},
168{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
169{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
170{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
171{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
172{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
173{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), "EC_POINT_get_affine_coordinates_GF2m"},
174{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), "EC_POINT_get_affine_coordinates_GFp"},
175{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"},
176{ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
177{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
178{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
179{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
180{ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"},
181{ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
182{ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
183{ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
184{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), "EC_POINT_set_affine_coordinates_GF2m"},
185{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), "EC_POINT_set_affine_coordinates_GFp"},
186{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), "EC_POINT_set_compressed_coordinates_GF2m"},
187{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), "EC_POINT_set_compressed_coordinates_GFp"},
188{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_set_Jprojective_coordinates_GFp"},
189{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
190{ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"},
191{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"},
192{ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
193{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
194{ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
195{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
196{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
197{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
198{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"},
199{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"},
200{ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"},
201{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
202{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
203{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
204{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"},
205{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"},
206{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
207{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
208{ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
209{0,NULL}
210 };
211
212static ERR_STRING_DATA EC_str_reasons[]=
213 {
214{ERR_REASON(EC_R_ASN1_ERROR) ,"asn1 error"},
215{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"},
216{ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE) ,"bignum out of range"},
217{ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"},
218{ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE),"coordinates out of range"},
219{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
220{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"},
221{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"},
222{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
223{ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"},
224{ERR_REASON(EC_R_GF2M_NOT_SUPPORTED) ,"gf2m not supported"},
225{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
226{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
227{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"},
228{ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"},
229{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
230{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"},
231{ERR_REASON(EC_R_INVALID_CURVE) ,"invalid curve"},
232{ERR_REASON(EC_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
233{ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"},
234{ERR_REASON(EC_R_INVALID_FIELD) ,"invalid field"},
235{ERR_REASON(EC_R_INVALID_FORM) ,"invalid form"},
236{ERR_REASON(EC_R_INVALID_GROUP_ORDER) ,"invalid group order"},
237{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"},
238{ERR_REASON(EC_R_INVALID_PRIVATE_KEY) ,"invalid private key"},
239{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"},
240{ERR_REASON(EC_R_KEYS_NOT_SET) ,"keys not set"},
241{ERR_REASON(EC_R_MISSING_PARAMETERS) ,"missing parameters"},
242{ERR_REASON(EC_R_MISSING_PRIVATE_KEY) ,"missing private key"},
243{ERR_REASON(EC_R_NOT_A_NIST_PRIME) ,"not a NIST prime"},
244{ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME),"not a supported NIST prime"},
245{ERR_REASON(EC_R_NOT_IMPLEMENTED) ,"not implemented"},
246{ERR_REASON(EC_R_NOT_INITIALIZED) ,"not initialized"},
247{ERR_REASON(EC_R_NO_FIELD_MOD) ,"no field mod"},
248{ERR_REASON(EC_R_NO_PARAMETERS_SET) ,"no parameters set"},
249{ERR_REASON(EC_R_PASSED_NULL_PARAMETER) ,"passed null parameter"},
250{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"},
251{ERR_REASON(EC_R_POINT_AT_INFINITY) ,"point at infinity"},
252{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE) ,"point is not on curve"},
253{ERR_REASON(EC_R_SLOT_FULL) ,"slot full"},
254{ERR_REASON(EC_R_UNDEFINED_GENERATOR) ,"undefined generator"},
255{ERR_REASON(EC_R_UNDEFINED_ORDER) ,"undefined order"},
256{ERR_REASON(EC_R_UNKNOWN_GROUP) ,"unknown group"},
257{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"},
258{ERR_REASON(EC_R_UNSUPPORTED_FIELD) ,"unsupported field"},
259{ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS) ,"wrong curve parameters"},
260{ERR_REASON(EC_R_WRONG_ORDER) ,"wrong order"},
261{0,NULL}
262 };
263
264#endif
265
266void ERR_load_EC_strings(void)
267 {
268#ifndef OPENSSL_NO_ERR
269
270 if (ERR_func_error_string(EC_str_functs[0].error) == NULL)
271 {
272 ERR_load_strings(0,EC_str_functs);
273 ERR_load_strings(0,EC_str_reasons);
274 }
275#endif
276 }
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
deleted file mode 100644
index bf9fd2dc2c..0000000000
--- a/src/lib/libcrypto/ec/ec_key.c
+++ /dev/null
@@ -1,563 +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#ifdef OPENSSL_FIPS
68#include <openssl/fips.h>
69#endif
70
71EC_KEY *EC_KEY_new(void)
72 {
73 EC_KEY *ret;
74
75 ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
76 if (ret == NULL)
77 {
78 ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
79 return(NULL);
80 }
81
82 ret->version = 1;
83 ret->flags = 0;
84 ret->group = NULL;
85 ret->pub_key = NULL;
86 ret->priv_key= NULL;
87 ret->enc_flag= 0;
88 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
89 ret->references= 1;
90 ret->method_data = NULL;
91 return(ret);
92 }
93
94EC_KEY *EC_KEY_new_by_curve_name(int nid)
95 {
96 EC_KEY *ret = EC_KEY_new();
97 if (ret == NULL)
98 return NULL;
99 ret->group = EC_GROUP_new_by_curve_name(nid);
100 if (ret->group == NULL)
101 {
102 EC_KEY_free(ret);
103 return NULL;
104 }
105 return ret;
106 }
107
108void EC_KEY_free(EC_KEY *r)
109 {
110 int i;
111
112 if (r == NULL) return;
113
114 i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
115#ifdef REF_PRINT
116 REF_PRINT("EC_KEY",r);
117#endif
118 if (i > 0) return;
119#ifdef REF_CHECK
120 if (i < 0)
121 {
122 fprintf(stderr,"EC_KEY_free, bad reference count\n");
123 abort();
124 }
125#endif
126
127 if (r->group != NULL)
128 EC_GROUP_free(r->group);
129 if (r->pub_key != NULL)
130 EC_POINT_free(r->pub_key);
131 if (r->priv_key != NULL)
132 BN_clear_free(r->priv_key);
133
134 EC_EX_DATA_free_all_data(&r->method_data);
135
136 OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
137
138 OPENSSL_free(r);
139 }
140
141EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
142 {
143 EC_EXTRA_DATA *d;
144
145 if (dest == NULL || src == NULL)
146 {
147 ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
148 return NULL;
149 }
150 /* copy the parameters */
151 if (src->group)
152 {
153 const EC_METHOD *meth = EC_GROUP_method_of(src->group);
154 /* clear the old group */
155 if (dest->group)
156 EC_GROUP_free(dest->group);
157 dest->group = EC_GROUP_new(meth);
158 if (dest->group == NULL)
159 return NULL;
160 if (!EC_GROUP_copy(dest->group, src->group))
161 return NULL;
162 }
163 /* copy the public key */
164 if (src->pub_key && src->group)
165 {
166 if (dest->pub_key)
167 EC_POINT_free(dest->pub_key);
168 dest->pub_key = EC_POINT_new(src->group);
169 if (dest->pub_key == NULL)
170 return NULL;
171 if (!EC_POINT_copy(dest->pub_key, src->pub_key))
172 return NULL;
173 }
174 /* copy the private key */
175 if (src->priv_key)
176 {
177 if (dest->priv_key == NULL)
178 {
179 dest->priv_key = BN_new();
180 if (dest->priv_key == NULL)
181 return NULL;
182 }
183 if (!BN_copy(dest->priv_key, src->priv_key))
184 return NULL;
185 }
186 /* copy method/extra data */
187 EC_EX_DATA_free_all_data(&dest->method_data);
188
189 for (d = src->method_data; d != NULL; d = d->next)
190 {
191 void *t = d->dup_func(d->data);
192
193 if (t == NULL)
194 return 0;
195 if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
196 return 0;
197 }
198
199 /* copy the rest */
200 dest->enc_flag = src->enc_flag;
201 dest->conv_form = src->conv_form;
202 dest->version = src->version;
203 dest->flags = src->flags;
204
205 return dest;
206 }
207
208EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
209 {
210 EC_KEY *ret = EC_KEY_new();
211 if (ret == NULL)
212 return NULL;
213 if (EC_KEY_copy(ret, ec_key) == NULL)
214 {
215 EC_KEY_free(ret);
216 return NULL;
217 }
218 return ret;
219 }
220
221int EC_KEY_up_ref(EC_KEY *r)
222 {
223 int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
224#ifdef REF_PRINT
225 REF_PRINT("EC_KEY",r);
226#endif
227#ifdef REF_CHECK
228 if (i < 2)
229 {
230 fprintf(stderr, "EC_KEY_up, bad reference count\n");
231 abort();
232 }
233#endif
234 return ((i > 1) ? 1 : 0);
235 }
236
237int EC_KEY_generate_key(EC_KEY *eckey)
238 {
239 int ok = 0;
240 BN_CTX *ctx = NULL;
241 BIGNUM *priv_key = NULL, *order = NULL;
242 EC_POINT *pub_key = NULL;
243
244#ifdef OPENSSL_FIPS
245 if (FIPS_mode())
246 return FIPS_ec_key_generate_key(eckey);
247#endif
248
249 if (!eckey || !eckey->group)
250 {
251 ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
252 return 0;
253 }
254
255 if ((order = BN_new()) == NULL) goto err;
256 if ((ctx = BN_CTX_new()) == NULL) goto err;
257
258 if (eckey->priv_key == NULL)
259 {
260 priv_key = BN_new();
261 if (priv_key == NULL)
262 goto err;
263 }
264 else
265 priv_key = eckey->priv_key;
266
267 if (!EC_GROUP_get_order(eckey->group, order, ctx))
268 goto err;
269
270 do
271 if (!BN_rand_range(priv_key, order))
272 goto err;
273 while (BN_is_zero(priv_key));
274
275 if (eckey->pub_key == NULL)
276 {
277 pub_key = EC_POINT_new(eckey->group);
278 if (pub_key == NULL)
279 goto err;
280 }
281 else
282 pub_key = eckey->pub_key;
283
284 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
285 goto err;
286
287 eckey->priv_key = priv_key;
288 eckey->pub_key = pub_key;
289
290 ok=1;
291
292err:
293 if (order)
294 BN_free(order);
295 if (pub_key != NULL && eckey->pub_key == NULL)
296 EC_POINT_free(pub_key);
297 if (priv_key != NULL && eckey->priv_key == NULL)
298 BN_free(priv_key);
299 if (ctx != NULL)
300 BN_CTX_free(ctx);
301 return(ok);
302 }
303
304int EC_KEY_check_key(const EC_KEY *eckey)
305 {
306 int ok = 0;
307 BN_CTX *ctx = NULL;
308 const BIGNUM *order = NULL;
309 EC_POINT *point = NULL;
310
311 if (!eckey || !eckey->group || !eckey->pub_key)
312 {
313 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
314 return 0;
315 }
316
317 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key))
318 {
319 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
320 goto err;
321 }
322
323 if ((ctx = BN_CTX_new()) == NULL)
324 goto err;
325 if ((point = EC_POINT_new(eckey->group)) == NULL)
326 goto err;
327
328 /* testing whether the pub_key is on the elliptic curve */
329 if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
330 {
331 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
332 goto err;
333 }
334 /* testing whether pub_key * order is the point at infinity */
335 order = &eckey->group->order;
336 if (BN_is_zero(order))
337 {
338 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
339 goto err;
340 }
341 if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx))
342 {
343 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
344 goto err;
345 }
346 if (!EC_POINT_is_at_infinity(eckey->group, point))
347 {
348 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
349 goto err;
350 }
351 /* in case the priv_key is present :
352 * check if generator * priv_key == pub_key
353 */
354 if (eckey->priv_key)
355 {
356 if (BN_cmp(eckey->priv_key, order) >= 0)
357 {
358 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
359 goto err;
360 }
361 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
362 NULL, NULL, ctx))
363 {
364 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
365 goto err;
366 }
367 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
368 ctx) != 0)
369 {
370 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
371 goto err;
372 }
373 }
374 ok = 1;
375err:
376 if (ctx != NULL)
377 BN_CTX_free(ctx);
378 if (point != NULL)
379 EC_POINT_free(point);
380 return(ok);
381 }
382
383int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y)
384 {
385 BN_CTX *ctx = NULL;
386 BIGNUM *tx, *ty;
387 EC_POINT *point = NULL;
388 int ok = 0, tmp_nid, is_char_two = 0;
389
390 if (!key || !key->group || !x || !y)
391 {
392 ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
393 ERR_R_PASSED_NULL_PARAMETER);
394 return 0;
395 }
396 ctx = BN_CTX_new();
397 if (!ctx)
398 goto err;
399
400 point = EC_POINT_new(key->group);
401
402 if (!point)
403 goto err;
404
405 tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
406
407 if (tmp_nid == NID_X9_62_characteristic_two_field)
408 is_char_two = 1;
409
410 tx = BN_CTX_get(ctx);
411 ty = BN_CTX_get(ctx);
412#ifndef OPENSSL_NO_EC2M
413 if (is_char_two)
414 {
415 if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
416 x, y, ctx))
417 goto err;
418 if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
419 tx, ty, ctx))
420 goto err;
421 }
422 else
423#endif
424 {
425 if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
426 x, y, ctx))
427 goto err;
428 if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
429 tx, ty, ctx))
430 goto err;
431 }
432 /* Check if retrieved coordinates match originals: if not values
433 * are out of range.
434 */
435 if (BN_cmp(x, tx) || BN_cmp(y, ty))
436 {
437 ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
438 EC_R_COORDINATES_OUT_OF_RANGE);
439 goto err;
440 }
441
442 if (!EC_KEY_set_public_key(key, point))
443 goto err;
444
445 if (EC_KEY_check_key(key) == 0)
446 goto err;
447
448 ok = 1;
449
450 err:
451 if (ctx)
452 BN_CTX_free(ctx);
453 if (point)
454 EC_POINT_free(point);
455 return ok;
456
457 }
458
459const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
460 {
461 return key->group;
462 }
463
464int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
465 {
466 if (key->group != NULL)
467 EC_GROUP_free(key->group);
468 key->group = EC_GROUP_dup(group);
469 return (key->group == NULL) ? 0 : 1;
470 }
471
472const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
473 {
474 return key->priv_key;
475 }
476
477int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
478 {
479 if (key->priv_key)
480 BN_clear_free(key->priv_key);
481 key->priv_key = BN_dup(priv_key);
482 return (key->priv_key == NULL) ? 0 : 1;
483 }
484
485const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
486 {
487 return key->pub_key;
488 }
489
490int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
491 {
492 if (key->pub_key != NULL)
493 EC_POINT_free(key->pub_key);
494 key->pub_key = EC_POINT_dup(pub_key, key->group);
495 return (key->pub_key == NULL) ? 0 : 1;
496 }
497
498unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
499 {
500 return key->enc_flag;
501 }
502
503void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
504 {
505 key->enc_flag = flags;
506 }
507
508point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
509 {
510 return key->conv_form;
511 }
512
513void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
514 {
515 key->conv_form = cform;
516 if (key->group != NULL)
517 EC_GROUP_set_point_conversion_form(key->group, cform);
518 }
519
520void *EC_KEY_get_key_method_data(EC_KEY *key,
521 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
522 {
523 return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
524 }
525
526void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
527 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
528 {
529 EC_EXTRA_DATA *ex_data;
530 CRYPTO_w_lock(CRYPTO_LOCK_EC);
531 ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
532 if (ex_data == NULL)
533 EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
534 CRYPTO_w_unlock(CRYPTO_LOCK_EC);
535 }
536
537void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
538 {
539 if (key->group != NULL)
540 EC_GROUP_set_asn1_flag(key->group, flag);
541 }
542
543int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
544 {
545 if (key->group == NULL)
546 return 0;
547 return EC_GROUP_precompute_mult(key->group, ctx);
548 }
549
550int EC_KEY_get_flags(const EC_KEY *key)
551 {
552 return key->flags;
553 }
554
555void EC_KEY_set_flags(EC_KEY *key, int flags)
556 {
557 key->flags |= flags;
558 }
559
560void EC_KEY_clear_flags(EC_KEY *key, int flags)
561 {
562 key->flags &= ~flags;
563 }
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h
deleted file mode 100644
index da7967df38..0000000000
--- a/src/lib/libcrypto/ec/ec_lcl.h
+++ /dev/null
@@ -1,446 +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-2010 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/* Use default functions for poin2oct, oct2point and compressed coordinates */
86#define EC_FLAGS_DEFAULT_OCT 0x1
87
88/* Structure details are not part of the exported interface,
89 * so all this may change in future versions. */
90
91struct ec_method_st {
92 /* Various method flags */
93 int flags;
94 /* used by EC_METHOD_get_field_type: */
95 int field_type; /* a NID */
96
97 /* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
98 int (*group_init)(EC_GROUP *);
99 void (*group_finish)(EC_GROUP *);
100 void (*group_clear_finish)(EC_GROUP *);
101 int (*group_copy)(EC_GROUP *, const EC_GROUP *);
102
103 /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
104 /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
105 int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
106 int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
107
108 /* used by EC_GROUP_get_degree: */
109 int (*group_get_degree)(const EC_GROUP *);
110
111 /* used by EC_GROUP_check: */
112 int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
113
114 /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
115 int (*point_init)(EC_POINT *);
116 void (*point_finish)(EC_POINT *);
117 void (*point_clear_finish)(EC_POINT *);
118 int (*point_copy)(EC_POINT *, const EC_POINT *);
119
120 /* used by EC_POINT_set_to_infinity,
121 * EC_POINT_set_Jprojective_coordinates_GFp,
122 * EC_POINT_get_Jprojective_coordinates_GFp,
123 * EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
124 * EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
125 * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
126 */
127 int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
128 int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
129 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
130 int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
131 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
132 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
133 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
134 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
135 BIGNUM *x, BIGNUM *y, BN_CTX *);
136 int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
137 const BIGNUM *x, int y_bit, BN_CTX *);
138
139 /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
140 size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
141 unsigned char *buf, size_t len, BN_CTX *);
142 int (*oct2point)(const EC_GROUP *, EC_POINT *,
143 const unsigned char *buf, size_t len, BN_CTX *);
144
145 /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
146 int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
147 int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
148 int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
149
150 /* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
151 int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
152 int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
153 int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
154
155 /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
156 int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
157 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
158
159 /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
160 * (default implementations are used if the 'mul' pointer is 0): */
161 int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
162 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
163 int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
164 int (*have_precompute_mult)(const EC_GROUP *group);
165
166
167 /* internal functions */
168
169 /* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that
170 * the same implementations of point operations can be used with different
171 * optimized implementations of expensive field operations: */
172 int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
173 int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
174 int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
175
176 int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
177 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
178 int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
179} /* EC_METHOD */;
180
181typedef struct ec_extra_data_st {
182 struct ec_extra_data_st *next;
183 void *data;
184 void *(*dup_func)(void *);
185 void (*free_func)(void *);
186 void (*clear_free_func)(void *);
187} EC_EXTRA_DATA; /* used in EC_GROUP */
188
189struct ec_group_st {
190 const EC_METHOD *meth;
191
192 EC_POINT *generator; /* optional */
193 BIGNUM order, cofactor;
194
195 int curve_name;/* optional NID for named curve */
196 int asn1_flag; /* flag to control the asn1 encoding */
197 point_conversion_form_t asn1_form;
198
199 unsigned char *seed; /* optional seed for parameters (appears in ASN1) */
200 size_t seed_len;
201
202 EC_EXTRA_DATA *extra_data; /* linked list */
203
204 /* The following members are handled by the method functions,
205 * even if they appear generic */
206
207 BIGNUM field; /* Field specification.
208 * For curves over GF(p), this is the modulus;
209 * for curves over GF(2^m), this is the
210 * irreducible polynomial defining the field.
211 */
212
213 int poly[6]; /* Field specification for curves over GF(2^m).
214 * The irreducible f(t) is then of the form:
215 * t^poly[0] + t^poly[1] + ... + t^poly[k]
216 * where m = poly[0] > poly[1] > ... > poly[k] = 0.
217 * The array is terminated with poly[k+1]=-1.
218 * All elliptic curve irreducibles have at most 5
219 * non-zero terms.
220 */
221
222 BIGNUM a, b; /* Curve coefficients.
223 * (Here the assumption is that BIGNUMs can be used
224 * or abused for all kinds of fields, not just GF(p).)
225 * For characteristic > 3, the curve is defined
226 * by a Weierstrass equation of the form
227 * y^2 = x^3 + a*x + b.
228 * For characteristic 2, the curve is defined by
229 * an equation of the form
230 * y^2 + x*y = x^3 + a*x^2 + b.
231 */
232
233 int a_is_minus3; /* enable optimized point arithmetics for special case */
234
235 void *field_data1; /* method-specific (e.g., Montgomery structure) */
236 void *field_data2; /* method-specific */
237 int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */
238} /* EC_GROUP */;
239
240struct ec_key_st {
241 int version;
242
243 EC_GROUP *group;
244
245 EC_POINT *pub_key;
246 BIGNUM *priv_key;
247
248 unsigned int enc_flag;
249 point_conversion_form_t conv_form;
250
251 int references;
252 int flags;
253
254 EC_EXTRA_DATA *method_data;
255} /* EC_KEY */;
256
257/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
258 * (with visibility limited to 'package' level for now).
259 * We use the function pointers as index for retrieval; this obviates
260 * global ex_data-style index tables.
261 */
262int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
263 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
264void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
265 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
266void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
267 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
268void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
269 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
270void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
271void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
272
273
274
275struct ec_point_st {
276 const EC_METHOD *meth;
277
278 /* All members except 'meth' are handled by the method functions,
279 * even if they appear generic */
280
281 BIGNUM X;
282 BIGNUM Y;
283 BIGNUM Z; /* Jacobian projective coordinates:
284 * (X, Y, Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
285 int Z_is_one; /* enable optimized point arithmetics for special case */
286} /* EC_POINT */;
287
288
289
290/* method functions in ec_mult.c
291 * (ec_lib.c uses these as defaults if group->method->mul is 0) */
292int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
293 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
294int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
295int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
296
297
298/* method functions in ecp_smpl.c */
299int ec_GFp_simple_group_init(EC_GROUP *);
300void ec_GFp_simple_group_finish(EC_GROUP *);
301void ec_GFp_simple_group_clear_finish(EC_GROUP *);
302int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
303int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
304int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
305int ec_GFp_simple_group_get_degree(const EC_GROUP *);
306int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
307int ec_GFp_simple_point_init(EC_POINT *);
308void ec_GFp_simple_point_finish(EC_POINT *);
309void ec_GFp_simple_point_clear_finish(EC_POINT *);
310int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
311int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
312int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
313 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
314int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
315 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
316int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
317 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
318int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
319 BIGNUM *x, BIGNUM *y, BN_CTX *);
320int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
321 const BIGNUM *x, int y_bit, BN_CTX *);
322size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
323 unsigned char *buf, size_t len, BN_CTX *);
324int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
325 const unsigned char *buf, size_t len, BN_CTX *);
326int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
327int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
328int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
329int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
330int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
331int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
332int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
333int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
334int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
335int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
336
337
338/* method functions in ecp_mont.c */
339int ec_GFp_mont_group_init(EC_GROUP *);
340int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
341void ec_GFp_mont_group_finish(EC_GROUP *);
342void ec_GFp_mont_group_clear_finish(EC_GROUP *);
343int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
344int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
345int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
346int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
347int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
348int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
349
350
351/* method functions in ecp_nist.c */
352int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
353int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
354int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
355int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
356
357
358/* method functions in ec2_smpl.c */
359int ec_GF2m_simple_group_init(EC_GROUP *);
360void ec_GF2m_simple_group_finish(EC_GROUP *);
361void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
362int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
363int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
364int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
365int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
366int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
367int ec_GF2m_simple_point_init(EC_POINT *);
368void ec_GF2m_simple_point_finish(EC_POINT *);
369void ec_GF2m_simple_point_clear_finish(EC_POINT *);
370int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
371int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
372int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
373 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
374int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
375 BIGNUM *x, BIGNUM *y, BN_CTX *);
376int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
377 const BIGNUM *x, int y_bit, BN_CTX *);
378size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
379 unsigned char *buf, size_t len, BN_CTX *);
380int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
381 const unsigned char *buf, size_t len, BN_CTX *);
382int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
383int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
384int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
385int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
386int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
387int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
388int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
389int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
390int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
391int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
392int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
393
394
395/* method functions in ec2_mult.c */
396int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
397 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
398int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
399int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
400
401/* method functions in ec2_mult.c */
402int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
403 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
404int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
405int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
406
407#ifndef OPENSSL_EC_NISTP_64_GCC_128
408/* method functions in ecp_nistp224.c */
409int ec_GFp_nistp224_group_init(EC_GROUP *group);
410int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
411int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
412int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
413int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
414int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
415int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
416
417/* method functions in ecp_nistp256.c */
418int ec_GFp_nistp256_group_init(EC_GROUP *group);
419int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
420int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
421int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
422int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
423int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
424int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
425
426/* method functions in ecp_nistp521.c */
427int ec_GFp_nistp521_group_init(EC_GROUP *group);
428int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
429int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
430int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
431int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
432int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
433int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
434
435/* utility functions in ecp_nistputil.c */
436void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
437 size_t felem_size, void *tmp_felems,
438 void (*felem_one)(void *out),
439 int (*felem_is_zero)(const void *in),
440 void (*felem_assign)(void *out, const void *in),
441 void (*felem_square)(void *out, const void *in),
442 void (*felem_mul)(void *out, const void *in1, const void *in2),
443 void (*felem_inv)(void *out, const void *in),
444 void (*felem_contract)(void *out, const void *in));
445void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in);
446#endif
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
deleted file mode 100644
index 25247b5803..0000000000
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ /dev/null
@@ -1,1096 +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#ifndef OPENSSL_NO_EC2M
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#endif
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#ifndef OPENSSL_NO_EC2M
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#endif
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#ifndef OPENSSL_NO_EC2M
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#endif
910
911int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
912 {
913 if (group->meth->add == 0)
914 {
915 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
916 return 0;
917 }
918 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth))
919 {
920 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
921 return 0;
922 }
923 return group->meth->add(group, r, a, b, ctx);
924 }
925
926
927int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
928 {
929 if (group->meth->dbl == 0)
930 {
931 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
932 return 0;
933 }
934 if ((group->meth != r->meth) || (r->meth != a->meth))
935 {
936 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
937 return 0;
938 }
939 return group->meth->dbl(group, r, a, ctx);
940 }
941
942
943int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
944 {
945 if (group->meth->dbl == 0)
946 {
947 ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
948 return 0;
949 }
950 if (group->meth != a->meth)
951 {
952 ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
953 return 0;
954 }
955 return group->meth->invert(group, a, ctx);
956 }
957
958
959int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
960 {
961 if (group->meth->is_at_infinity == 0)
962 {
963 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
964 return 0;
965 }
966 if (group->meth != point->meth)
967 {
968 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
969 return 0;
970 }
971 return group->meth->is_at_infinity(group, point);
972 }
973
974
975int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
976 {
977 if (group->meth->is_on_curve == 0)
978 {
979 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
980 return 0;
981 }
982 if (group->meth != point->meth)
983 {
984 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
985 return 0;
986 }
987 return group->meth->is_on_curve(group, point, ctx);
988 }
989
990
991int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
992 {
993 if (group->meth->point_cmp == 0)
994 {
995 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
996 return 0;
997 }
998 if ((group->meth != a->meth) || (a->meth != b->meth))
999 {
1000 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
1001 return 0;
1002 }
1003 return group->meth->point_cmp(group, a, b, ctx);
1004 }
1005
1006
1007int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1008 {
1009 if (group->meth->make_affine == 0)
1010 {
1011 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1012 return 0;
1013 }
1014 if (group->meth != point->meth)
1015 {
1016 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1017 return 0;
1018 }
1019 return group->meth->make_affine(group, point, ctx);
1020 }
1021
1022
1023int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1024 {
1025 size_t i;
1026
1027 if (group->meth->points_make_affine == 0)
1028 {
1029 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1030 return 0;
1031 }
1032 for (i = 0; i < num; i++)
1033 {
1034 if (group->meth != points[i]->meth)
1035 {
1036 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
1037 return 0;
1038 }
1039 }
1040 return group->meth->points_make_affine(group, num, points, ctx);
1041 }
1042
1043
1044/* Functions for point multiplication.
1045 *
1046 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1047 * otherwise we dispatch through methods.
1048 */
1049
1050int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1051 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1052 {
1053 if (group->meth->mul == 0)
1054 /* use default */
1055 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
1056
1057 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
1058 }
1059
1060int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1061 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1062 {
1063 /* just a convenient interface to EC_POINTs_mul() */
1064
1065 const EC_POINT *points[1];
1066 const BIGNUM *scalars[1];
1067
1068 points[0] = point;
1069 scalars[0] = p_scalar;
1070
1071 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx);
1072 }
1073
1074int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
1075 {
1076 if (group->meth->mul == 0)
1077 /* use default */
1078 return ec_wNAF_precompute_mult(group, ctx);
1079
1080 if (group->meth->precompute_mult != 0)
1081 return group->meth->precompute_mult(group, ctx);
1082 else
1083 return 1; /* nothing to do, so report success */
1084 }
1085
1086int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1087 {
1088 if (group->meth->mul == 0)
1089 /* use default */
1090 return ec_wNAF_have_precompute_mult(group);
1091
1092 if (group->meth->have_precompute_mult != 0)
1093 return group->meth->have_precompute_mult(group);
1094 else
1095 return 0; /* cannot tell whether precomputation has been performed */
1096 }
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_oct.c b/src/lib/libcrypto/ec/ec_oct.c
deleted file mode 100644
index fd9db0798d..0000000000
--- a/src/lib/libcrypto/ec/ec_oct.c
+++ /dev/null
@@ -1,199 +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
71int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
72 const BIGNUM *x, int y_bit, BN_CTX *ctx)
73 {
74 if (group->meth->point_set_compressed_coordinates == 0
75 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
76 {
77 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
78 return 0;
79 }
80 if (group->meth != point->meth)
81 {
82 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
83 return 0;
84 }
85 if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
86 {
87 if (group->meth->field_type == NID_X9_62_prime_field)
88 return ec_GFp_simple_set_compressed_coordinates(
89 group, point, x, y_bit, ctx);
90 else
91#ifdef OPENSSL_NO_EC2M
92 {
93 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_GF2M_NOT_SUPPORTED);
94 return 0;
95 }
96#else
97 return ec_GF2m_simple_set_compressed_coordinates(
98 group, point, x, y_bit, ctx);
99#endif
100 }
101 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
102 }
103
104#ifndef OPENSSL_NO_EC2M
105int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
106 const BIGNUM *x, int y_bit, BN_CTX *ctx)
107 {
108 if (group->meth->point_set_compressed_coordinates == 0
109 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
110 {
111 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
112 return 0;
113 }
114 if (group->meth != point->meth)
115 {
116 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
117 return 0;
118 }
119 if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
120 {
121 if (group->meth->field_type == NID_X9_62_prime_field)
122 return ec_GFp_simple_set_compressed_coordinates(
123 group, point, x, y_bit, ctx);
124 else
125 return ec_GF2m_simple_set_compressed_coordinates(
126 group, point, x, y_bit, ctx);
127 }
128 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
129 }
130#endif
131
132size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
133 unsigned char *buf, size_t len, BN_CTX *ctx)
134 {
135 if (group->meth->point2oct == 0
136 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
137 {
138 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
139 return 0;
140 }
141 if (group->meth != point->meth)
142 {
143 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
144 return 0;
145 }
146 if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
147 {
148 if (group->meth->field_type == NID_X9_62_prime_field)
149 return ec_GFp_simple_point2oct(group, point,
150 form, buf, len, ctx);
151 else
152#ifdef OPENSSL_NO_EC2M
153 {
154 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
155 return 0;
156 }
157#else
158 return ec_GF2m_simple_point2oct(group, point,
159 form, buf, len, ctx);
160#endif
161 }
162
163 return group->meth->point2oct(group, point, form, buf, len, ctx);
164 }
165
166
167int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
168 const unsigned char *buf, size_t len, BN_CTX *ctx)
169 {
170 if (group->meth->oct2point == 0
171 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT))
172 {
173 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
174 return 0;
175 }
176 if (group->meth != point->meth)
177 {
178 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
179 return 0;
180 }
181 if(group->meth->flags & EC_FLAGS_DEFAULT_OCT)
182 {
183 if (group->meth->field_type == NID_X9_62_prime_field)
184 return ec_GFp_simple_oct2point(group, point,
185 buf, len, ctx);
186 else
187#ifdef OPENSSL_NO_EC2M
188 {
189 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
190 return 0;
191 }
192#else
193 return ec_GF2m_simple_oct2point(group, point,
194 buf, len, ctx);
195#endif
196 }
197 return group->meth->oct2point(group, point, buf, len, ctx);
198 }
199
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
deleted file mode 100644
index d1ed66c37e..0000000000
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ /dev/null
@@ -1,341 +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_ecdsa_with_SHA1 &&
225 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
226 EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
227 EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
228 EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
229 {
230 ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
231 return 0;
232 }
233 dctx->md = p2;
234 return 1;
235
236 case EVP_PKEY_CTRL_PEER_KEY:
237 /* Default behaviour is OK */
238 case EVP_PKEY_CTRL_DIGESTINIT:
239 case EVP_PKEY_CTRL_PKCS7_SIGN:
240 case EVP_PKEY_CTRL_CMS_SIGN:
241 return 1;
242
243 default:
244 return -2;
245
246 }
247 }
248
249static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
250 const char *type, const char *value)
251 {
252 if (!strcmp(type, "ec_paramgen_curve"))
253 {
254 int nid;
255 nid = OBJ_sn2nid(value);
256 if (nid == NID_undef)
257 nid = OBJ_ln2nid(value);
258 if (nid == NID_undef)
259 {
260 ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
261 return 0;
262 }
263 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
264 }
265 return -2;
266 }
267
268static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
269 {
270 EC_KEY *ec = NULL;
271 EC_PKEY_CTX *dctx = ctx->data;
272 int ret = 0;
273 if (dctx->gen_group == NULL)
274 {
275 ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
276 return 0;
277 }
278 ec = EC_KEY_new();
279 if (!ec)
280 return 0;
281 ret = EC_KEY_set_group(ec, dctx->gen_group);
282 if (ret)
283 EVP_PKEY_assign_EC_KEY(pkey, ec);
284 else
285 EC_KEY_free(ec);
286 return ret;
287 }
288
289static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
290 {
291 EC_KEY *ec = NULL;
292 if (ctx->pkey == NULL)
293 {
294 ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
295 return 0;
296 }
297 ec = EC_KEY_new();
298 if (!ec)
299 return 0;
300 EVP_PKEY_assign_EC_KEY(pkey, ec);
301 /* Note: if error return, pkey is freed by parent routine */
302 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
303 return 0;
304 return EC_KEY_generate_key(pkey->pkey.ec);
305 }
306
307const EVP_PKEY_METHOD ec_pkey_meth =
308 {
309 EVP_PKEY_EC,
310 0,
311 pkey_ec_init,
312 pkey_ec_copy,
313 pkey_ec_cleanup,
314
315 0,
316 pkey_ec_paramgen,
317
318 0,
319 pkey_ec_keygen,
320
321 0,
322 pkey_ec_sign,
323
324 0,
325 pkey_ec_verify,
326
327 0,0,
328
329 0,0,0,0,
330
331 0,0,
332
333 0,0,
334
335 0,
336 pkey_ec_derive,
337
338 pkey_ec_ctrl,
339 pkey_ec_ctrl_str
340
341 };
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 06de8f3959..0000000000
--- a/src/lib/libcrypto/ec/eck_prn.c
+++ /dev/null
@@ -1,392 +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#ifndef OPENSSL_NO_EC2M
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#endif
221 {
222 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
223 {
224 reason = ERR_R_EC_LIB;
225 goto err;
226 }
227 }
228
229 if ((point = EC_GROUP_get0_generator(x)) == NULL)
230 {
231 reason = ERR_R_EC_LIB;
232 goto err;
233 }
234 if (!EC_GROUP_get_order(x, order, NULL) ||
235 !EC_GROUP_get_cofactor(x, cofactor, NULL))
236 {
237 reason = ERR_R_EC_LIB;
238 goto err;
239 }
240
241 form = EC_GROUP_get_point_conversion_form(x);
242
243 if ((gen = EC_POINT_point2bn(x, point,
244 form, NULL, ctx)) == NULL)
245 {
246 reason = ERR_R_EC_LIB;
247 goto err;
248 }
249
250 buf_len = (size_t)BN_num_bytes(p);
251 if (buf_len < (i = (size_t)BN_num_bytes(a)))
252 buf_len = i;
253 if (buf_len < (i = (size_t)BN_num_bytes(b)))
254 buf_len = i;
255 if (buf_len < (i = (size_t)BN_num_bytes(gen)))
256 buf_len = i;
257 if (buf_len < (i = (size_t)BN_num_bytes(order)))
258 buf_len = i;
259 if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
260 buf_len = i;
261
262 if ((seed = EC_GROUP_get0_seed(x)) != NULL)
263 seed_len = EC_GROUP_get_seed_len(x);
264
265 buf_len += 10;
266 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
267 {
268 reason = ERR_R_MALLOC_FAILURE;
269 goto err;
270 }
271
272 if (!BIO_indent(bp, off, 128))
273 goto err;
274
275 /* print the 'short name' of the field type */
276 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
277 <= 0)
278 goto err;
279
280 if (is_char_two)
281 {
282 /* print the 'short name' of the base type OID */
283 int basis_type = EC_GROUP_get_basis_type(x);
284 if (basis_type == 0)
285 goto err;
286
287 if (!BIO_indent(bp, off, 128))
288 goto err;
289
290 if (BIO_printf(bp, "Basis Type: %s\n",
291 OBJ_nid2sn(basis_type)) <= 0)
292 goto err;
293
294 /* print the polynomial */
295 if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
296 off))
297 goto err;
298 }
299 else
300 {
301 if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off))
302 goto err;
303 }
304 if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
305 goto err;
306 if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
307 goto err;
308 if (form == POINT_CONVERSION_COMPRESSED)
309 {
310 if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
311 buffer, off))
312 goto err;
313 }
314 else if (form == POINT_CONVERSION_UNCOMPRESSED)
315 {
316 if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
317 buffer, off))
318 goto err;
319 }
320 else /* form == POINT_CONVERSION_HYBRID */
321 {
322 if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
323 buffer, off))
324 goto err;
325 }
326 if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
327 buffer, off)) goto err;
328 if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
329 buffer, off)) goto err;
330 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
331 goto err;
332 }
333 ret=1;
334err:
335 if (!ret)
336 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
337 if (p)
338 BN_free(p);
339 if (a)
340 BN_free(a);
341 if (b)
342 BN_free(b);
343 if (gen)
344 BN_free(gen);
345 if (order)
346 BN_free(order);
347 if (cofactor)
348 BN_free(cofactor);
349 if (ctx)
350 BN_CTX_free(ctx);
351 if (buffer != NULL)
352 OPENSSL_free(buffer);
353 return(ret);
354 }
355
356static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
357 size_t len, int off)
358 {
359 size_t i;
360 char str[128];
361
362 if (buf == NULL)
363 return 1;
364 if (off)
365 {
366 if (off > 128)
367 off=128;
368 memset(str,' ',off);
369 if (BIO_write(fp, str, off) <= 0)
370 return 0;
371 }
372
373 if (BIO_printf(fp,"%s", name) <= 0)
374 return 0;
375
376 for (i=0; i<len; i++)
377 {
378 if ((i%15) == 0)
379 {
380 str[0]='\n';
381 memset(&(str[1]),' ',off+4);
382 if (BIO_write(fp, str, off+1+4) <= 0)
383 return 0;
384 }
385 if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
386 return 0;
387 }
388 if (BIO_write(fp,"\n",1) <= 0)
389 return 0;
390
391 return 1;
392 }
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
deleted file mode 100644
index 079e47431b..0000000000
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ /dev/null
@@ -1,323 +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#ifdef OPENSSL_FIPS
67#include <openssl/fips.h>
68#endif
69
70#include "ec_lcl.h"
71
72
73const EC_METHOD *EC_GFp_mont_method(void)
74 {
75#ifdef OPENSSL_FIPS
76 return fips_ec_gfp_mont_method();
77#else
78 static const EC_METHOD ret = {
79 EC_FLAGS_DEFAULT_OCT,
80 NID_X9_62_prime_field,
81 ec_GFp_mont_group_init,
82 ec_GFp_mont_group_finish,
83 ec_GFp_mont_group_clear_finish,
84 ec_GFp_mont_group_copy,
85 ec_GFp_mont_group_set_curve,
86 ec_GFp_simple_group_get_curve,
87 ec_GFp_simple_group_get_degree,
88 ec_GFp_simple_group_check_discriminant,
89 ec_GFp_simple_point_init,
90 ec_GFp_simple_point_finish,
91 ec_GFp_simple_point_clear_finish,
92 ec_GFp_simple_point_copy,
93 ec_GFp_simple_point_set_to_infinity,
94 ec_GFp_simple_set_Jprojective_coordinates_GFp,
95 ec_GFp_simple_get_Jprojective_coordinates_GFp,
96 ec_GFp_simple_point_set_affine_coordinates,
97 ec_GFp_simple_point_get_affine_coordinates,
98 0,0,0,
99 ec_GFp_simple_add,
100 ec_GFp_simple_dbl,
101 ec_GFp_simple_invert,
102 ec_GFp_simple_is_at_infinity,
103 ec_GFp_simple_is_on_curve,
104 ec_GFp_simple_cmp,
105 ec_GFp_simple_make_affine,
106 ec_GFp_simple_points_make_affine,
107 0 /* mul */,
108 0 /* precompute_mult */,
109 0 /* have_precompute_mult */,
110 ec_GFp_mont_field_mul,
111 ec_GFp_mont_field_sqr,
112 0 /* field_div */,
113 ec_GFp_mont_field_encode,
114 ec_GFp_mont_field_decode,
115 ec_GFp_mont_field_set_to_one };
116
117
118 return &ret;
119#endif
120 }
121
122
123int ec_GFp_mont_group_init(EC_GROUP *group)
124 {
125 int ok;
126
127 ok = ec_GFp_simple_group_init(group);
128 group->field_data1 = NULL;
129 group->field_data2 = NULL;
130 return ok;
131 }
132
133
134void ec_GFp_mont_group_finish(EC_GROUP *group)
135 {
136 if (group->field_data1 != NULL)
137 {
138 BN_MONT_CTX_free(group->field_data1);
139 group->field_data1 = NULL;
140 }
141 if (group->field_data2 != NULL)
142 {
143 BN_free(group->field_data2);
144 group->field_data2 = NULL;
145 }
146 ec_GFp_simple_group_finish(group);
147 }
148
149
150void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
151 {
152 if (group->field_data1 != NULL)
153 {
154 BN_MONT_CTX_free(group->field_data1);
155 group->field_data1 = NULL;
156 }
157 if (group->field_data2 != NULL)
158 {
159 BN_clear_free(group->field_data2);
160 group->field_data2 = NULL;
161 }
162 ec_GFp_simple_group_clear_finish(group);
163 }
164
165
166int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
167 {
168 if (dest->field_data1 != NULL)
169 {
170 BN_MONT_CTX_free(dest->field_data1);
171 dest->field_data1 = NULL;
172 }
173 if (dest->field_data2 != NULL)
174 {
175 BN_clear_free(dest->field_data2);
176 dest->field_data2 = NULL;
177 }
178
179 if (!ec_GFp_simple_group_copy(dest, src)) return 0;
180
181 if (src->field_data1 != NULL)
182 {
183 dest->field_data1 = BN_MONT_CTX_new();
184 if (dest->field_data1 == NULL) return 0;
185 if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
186 }
187 if (src->field_data2 != NULL)
188 {
189 dest->field_data2 = BN_dup(src->field_data2);
190 if (dest->field_data2 == NULL) goto err;
191 }
192
193 return 1;
194
195 err:
196 if (dest->field_data1 != NULL)
197 {
198 BN_MONT_CTX_free(dest->field_data1);
199 dest->field_data1 = NULL;
200 }
201 return 0;
202 }
203
204
205int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
206 {
207 BN_CTX *new_ctx = NULL;
208 BN_MONT_CTX *mont = NULL;
209 BIGNUM *one = NULL;
210 int ret = 0;
211
212 if (group->field_data1 != NULL)
213 {
214 BN_MONT_CTX_free(group->field_data1);
215 group->field_data1 = NULL;
216 }
217 if (group->field_data2 != NULL)
218 {
219 BN_free(group->field_data2);
220 group->field_data2 = NULL;
221 }
222
223 if (ctx == NULL)
224 {
225 ctx = new_ctx = BN_CTX_new();
226 if (ctx == NULL)
227 return 0;
228 }
229
230 mont = BN_MONT_CTX_new();
231 if (mont == NULL) goto err;
232 if (!BN_MONT_CTX_set(mont, p, ctx))
233 {
234 ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
235 goto err;
236 }
237 one = BN_new();
238 if (one == NULL) goto err;
239 if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
240
241 group->field_data1 = mont;
242 mont = NULL;
243 group->field_data2 = one;
244 one = NULL;
245
246 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
247
248 if (!ret)
249 {
250 BN_MONT_CTX_free(group->field_data1);
251 group->field_data1 = NULL;
252 BN_free(group->field_data2);
253 group->field_data2 = NULL;
254 }
255
256 err:
257 if (new_ctx != NULL)
258 BN_CTX_free(new_ctx);
259 if (mont != NULL)
260 BN_MONT_CTX_free(mont);
261 return ret;
262 }
263
264
265int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
266 {
267 if (group->field_data1 == NULL)
268 {
269 ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
270 return 0;
271 }
272
273 return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
274 }
275
276
277int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
278 {
279 if (group->field_data1 == NULL)
280 {
281 ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
282 return 0;
283 }
284
285 return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
286 }
287
288
289int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
290 {
291 if (group->field_data1 == NULL)
292 {
293 ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
294 return 0;
295 }
296
297 return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
298 }
299
300
301int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
302 {
303 if (group->field_data1 == NULL)
304 {
305 ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
306 return 0;
307 }
308
309 return BN_from_montgomery(r, a, group->field_data1, ctx);
310 }
311
312
313int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
314 {
315 if (group->field_data2 == NULL)
316 {
317 ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
318 return 0;
319 }
320
321 if (!BN_copy(r, group->field_data2)) return 0;
322 return 1;
323 }
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
deleted file mode 100644
index aad2d5f443..0000000000
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ /dev/null
@@ -1,217 +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
70#ifdef OPENSSL_FIPS
71#include <openssl/fips.h>
72#endif
73
74const EC_METHOD *EC_GFp_nist_method(void)
75 {
76#ifdef OPENSSL_FIPS
77 return fips_ec_gfp_nist_method();
78#else
79 static const EC_METHOD ret = {
80 EC_FLAGS_DEFAULT_OCT,
81 NID_X9_62_prime_field,
82 ec_GFp_simple_group_init,
83 ec_GFp_simple_group_finish,
84 ec_GFp_simple_group_clear_finish,
85 ec_GFp_nist_group_copy,
86 ec_GFp_nist_group_set_curve,
87 ec_GFp_simple_group_get_curve,
88 ec_GFp_simple_group_get_degree,
89 ec_GFp_simple_group_check_discriminant,
90 ec_GFp_simple_point_init,
91 ec_GFp_simple_point_finish,
92 ec_GFp_simple_point_clear_finish,
93 ec_GFp_simple_point_copy,
94 ec_GFp_simple_point_set_to_infinity,
95 ec_GFp_simple_set_Jprojective_coordinates_GFp,
96 ec_GFp_simple_get_Jprojective_coordinates_GFp,
97 ec_GFp_simple_point_set_affine_coordinates,
98 ec_GFp_simple_point_get_affine_coordinates,
99 0,0,0,
100 ec_GFp_simple_add,
101 ec_GFp_simple_dbl,
102 ec_GFp_simple_invert,
103 ec_GFp_simple_is_at_infinity,
104 ec_GFp_simple_is_on_curve,
105 ec_GFp_simple_cmp,
106 ec_GFp_simple_make_affine,
107 ec_GFp_simple_points_make_affine,
108 0 /* mul */,
109 0 /* precompute_mult */,
110 0 /* have_precompute_mult */,
111 ec_GFp_nist_field_mul,
112 ec_GFp_nist_field_sqr,
113 0 /* field_div */,
114 0 /* field_encode */,
115 0 /* field_decode */,
116 0 /* field_set_to_one */ };
117
118 return &ret;
119#endif
120 }
121
122int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
123 {
124 dest->field_mod_func = src->field_mod_func;
125
126 return ec_GFp_simple_group_copy(dest, src);
127 }
128
129int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
130 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
131 {
132 int ret = 0;
133 BN_CTX *new_ctx = NULL;
134 BIGNUM *tmp_bn;
135
136 if (ctx == NULL)
137 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
138
139 BN_CTX_start(ctx);
140 if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
141
142 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
143 group->field_mod_func = BN_nist_mod_192;
144 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
145 group->field_mod_func = BN_nist_mod_224;
146 else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
147 group->field_mod_func = BN_nist_mod_256;
148 else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
149 group->field_mod_func = BN_nist_mod_384;
150 else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
151 group->field_mod_func = BN_nist_mod_521;
152 else
153 {
154 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
155 goto err;
156 }
157
158 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
159
160 err:
161 BN_CTX_end(ctx);
162 if (new_ctx != NULL)
163 BN_CTX_free(new_ctx);
164 return ret;
165 }
166
167
168int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
169 const BIGNUM *b, BN_CTX *ctx)
170 {
171 int ret=0;
172 BN_CTX *ctx_new=NULL;
173
174 if (!group || !r || !a || !b)
175 {
176 ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
177 goto err;
178 }
179 if (!ctx)
180 if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
181
182 if (!BN_mul(r, a, b, ctx)) goto err;
183 if (!group->field_mod_func(r, r, &group->field, ctx))
184 goto err;
185
186 ret=1;
187err:
188 if (ctx_new)
189 BN_CTX_free(ctx_new);
190 return ret;
191 }
192
193
194int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
195 BN_CTX *ctx)
196 {
197 int ret=0;
198 BN_CTX *ctx_new=NULL;
199
200 if (!group || !r || !a)
201 {
202 ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
203 goto err;
204 }
205 if (!ctx)
206 if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
207
208 if (!BN_sqr(r, a, ctx)) goto err;
209 if (!group->field_mod_func(r, r, &group->field, ctx))
210 goto err;
211
212 ret=1;
213err:
214 if (ctx_new)
215 BN_CTX_free(ctx_new);
216 return ret;
217 }
diff --git a/src/lib/libcrypto/ec/ecp_nistp224.c b/src/lib/libcrypto/ec/ecp_nistp224.c
deleted file mode 100644
index b5ff56c252..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp224.c
+++ /dev/null
@@ -1,1658 +0,0 @@
1/* crypto/ec/ecp_nistp224.c */
2/*
3 * Written by Emilia Kasper (Google) for the OpenSSL project.
4 */
5/* Copyright 2011 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 *
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21/*
22 * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
23 *
24 * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
25 * and Adam Langley's public domain 64-bit C implementation of curve25519
26 */
27
28#include <openssl/opensslconf.h>
29#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
30
31#ifndef OPENSSL_SYS_VMS
32#include <stdint.h>
33#else
34#include <inttypes.h>
35#endif
36
37#include <string.h>
38#include <openssl/err.h>
39#include "ec_lcl.h"
40
41#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
42 /* even with gcc, the typedef won't work for 32-bit platforms */
43 typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
44#else
45 #error "Need GCC 3.1 or later to define type uint128_t"
46#endif
47
48typedef uint8_t u8;
49typedef uint64_t u64;
50typedef int64_t s64;
51
52
53/******************************************************************************/
54/* INTERNAL REPRESENTATION OF FIELD ELEMENTS
55 *
56 * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
57 * using 64-bit coefficients called 'limbs',
58 * and sometimes (for multiplication results) as
59 * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6
60 * using 128-bit coefficients called 'widelimbs'.
61 * A 4-limb representation is an 'felem';
62 * a 7-widelimb representation is a 'widefelem'.
63 * Even within felems, bits of adjacent limbs overlap, and we don't always
64 * reduce the representations: we ensure that inputs to each felem
65 * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60,
66 * and fit into a 128-bit word without overflow. The coefficients are then
67 * again partially reduced to obtain an felem satisfying a_i < 2^57.
68 * We only reduce to the unique minimal representation at the end of the
69 * computation.
70 */
71
72typedef uint64_t limb;
73typedef uint128_t widelimb;
74
75typedef limb felem[4];
76typedef widelimb widefelem[7];
77
78/* Field element represented as a byte arrary.
79 * 28*8 = 224 bits is also the group order size for the elliptic curve,
80 * and we also use this type for scalars for point multiplication.
81 */
82typedef u8 felem_bytearray[28];
83
84static const felem_bytearray nistp224_curve_params[5] = {
85 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
86 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
87 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
88 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
89 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
90 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE},
91 {0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
92 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
93 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4},
94 {0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
95 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
96 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21},
97 {0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
98 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
99 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34}
100};
101
102/* Precomputed multiples of the standard generator
103 * Points are given in coordinates (X, Y, Z) where Z normally is 1
104 * (0 for the point at infinity).
105 * For each field element, slice a_0 is word 0, etc.
106 *
107 * The table has 2 * 16 elements, starting with the following:
108 * index | bits | point
109 * ------+---------+------------------------------
110 * 0 | 0 0 0 0 | 0G
111 * 1 | 0 0 0 1 | 1G
112 * 2 | 0 0 1 0 | 2^56G
113 * 3 | 0 0 1 1 | (2^56 + 1)G
114 * 4 | 0 1 0 0 | 2^112G
115 * 5 | 0 1 0 1 | (2^112 + 1)G
116 * 6 | 0 1 1 0 | (2^112 + 2^56)G
117 * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
118 * 8 | 1 0 0 0 | 2^168G
119 * 9 | 1 0 0 1 | (2^168 + 1)G
120 * 10 | 1 0 1 0 | (2^168 + 2^56)G
121 * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
122 * 12 | 1 1 0 0 | (2^168 + 2^112)G
123 * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
124 * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
125 * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
126 * followed by a copy of this with each element multiplied by 2^28.
127 *
128 * The reason for this is so that we can clock bits into four different
129 * locations when doing simple scalar multiplies against the base point,
130 * and then another four locations using the second 16 elements.
131 */
132static const felem gmul[2][16][3] =
133{{{{0, 0, 0, 0},
134 {0, 0, 0, 0},
135 {0, 0, 0, 0}},
136 {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
137 {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
138 {1, 0, 0, 0}},
139 {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
140 {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
141 {1, 0, 0, 0}},
142 {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
143 {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
144 {1, 0, 0, 0}},
145 {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
146 {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
147 {1, 0, 0, 0}},
148 {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
149 {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
150 {1, 0, 0, 0}},
151 {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
152 {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
153 {1, 0, 0, 0}},
154 {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
155 {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
156 {1, 0, 0, 0}},
157 {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
158 {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
159 {1, 0, 0, 0}},
160 {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
161 {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
162 {1, 0, 0, 0}},
163 {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
164 {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
165 {1, 0, 0, 0}},
166 {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
167 {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
168 {1, 0, 0, 0}},
169 {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
170 {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
171 {1, 0, 0, 0}},
172 {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
173 {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
174 {1, 0, 0, 0}},
175 {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
176 {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
177 {1, 0, 0, 0}},
178 {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
179 {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
180 {1, 0, 0, 0}}},
181 {{{0, 0, 0, 0},
182 {0, 0, 0, 0},
183 {0, 0, 0, 0}},
184 {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
185 {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
186 {1, 0, 0, 0}},
187 {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
188 {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
189 {1, 0, 0, 0}},
190 {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
191 {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
192 {1, 0, 0, 0}},
193 {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
194 {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
195 {1, 0, 0, 0}},
196 {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
197 {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
198 {1, 0, 0, 0}},
199 {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
200 {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
201 {1, 0, 0, 0}},
202 {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
203 {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
204 {1, 0, 0, 0}},
205 {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
206 {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
207 {1, 0, 0, 0}},
208 {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
209 {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
210 {1, 0, 0, 0}},
211 {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
212 {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
213 {1, 0, 0, 0}},
214 {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
215 {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
216 {1, 0, 0, 0}},
217 {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
218 {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
219 {1, 0, 0, 0}},
220 {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
221 {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
222 {1, 0, 0, 0}},
223 {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
224 {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
225 {1, 0, 0, 0}},
226 {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
227 {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
228 {1, 0, 0, 0}}}};
229
230/* Precomputation for the group generator. */
231typedef struct {
232 felem g_pre_comp[2][16][3];
233 int references;
234} NISTP224_PRE_COMP;
235
236const EC_METHOD *EC_GFp_nistp224_method(void)
237 {
238 static const EC_METHOD ret = {
239 EC_FLAGS_DEFAULT_OCT,
240 NID_X9_62_prime_field,
241 ec_GFp_nistp224_group_init,
242 ec_GFp_simple_group_finish,
243 ec_GFp_simple_group_clear_finish,
244 ec_GFp_nist_group_copy,
245 ec_GFp_nistp224_group_set_curve,
246 ec_GFp_simple_group_get_curve,
247 ec_GFp_simple_group_get_degree,
248 ec_GFp_simple_group_check_discriminant,
249 ec_GFp_simple_point_init,
250 ec_GFp_simple_point_finish,
251 ec_GFp_simple_point_clear_finish,
252 ec_GFp_simple_point_copy,
253 ec_GFp_simple_point_set_to_infinity,
254 ec_GFp_simple_set_Jprojective_coordinates_GFp,
255 ec_GFp_simple_get_Jprojective_coordinates_GFp,
256 ec_GFp_simple_point_set_affine_coordinates,
257 ec_GFp_nistp224_point_get_affine_coordinates,
258 0 /* point_set_compressed_coordinates */,
259 0 /* point2oct */,
260 0 /* oct2point */,
261 ec_GFp_simple_add,
262 ec_GFp_simple_dbl,
263 ec_GFp_simple_invert,
264 ec_GFp_simple_is_at_infinity,
265 ec_GFp_simple_is_on_curve,
266 ec_GFp_simple_cmp,
267 ec_GFp_simple_make_affine,
268 ec_GFp_simple_points_make_affine,
269 ec_GFp_nistp224_points_mul,
270 ec_GFp_nistp224_precompute_mult,
271 ec_GFp_nistp224_have_precompute_mult,
272 ec_GFp_nist_field_mul,
273 ec_GFp_nist_field_sqr,
274 0 /* field_div */,
275 0 /* field_encode */,
276 0 /* field_decode */,
277 0 /* field_set_to_one */ };
278
279 return &ret;
280 }
281
282/* Helper functions to convert field elements to/from internal representation */
283static void bin28_to_felem(felem out, const u8 in[28])
284 {
285 out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
286 out[1] = (*((const uint64_t *)(in+7))) & 0x00ffffffffffffff;
287 out[2] = (*((const uint64_t *)(in+14))) & 0x00ffffffffffffff;
288 out[3] = (*((const uint64_t *)(in+21))) & 0x00ffffffffffffff;
289 }
290
291static void felem_to_bin28(u8 out[28], const felem in)
292 {
293 unsigned i;
294 for (i = 0; i < 7; ++i)
295 {
296 out[i] = in[0]>>(8*i);
297 out[i+7] = in[1]>>(8*i);
298 out[i+14] = in[2]>>(8*i);
299 out[i+21] = in[3]>>(8*i);
300 }
301 }
302
303/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
304static void flip_endian(u8 *out, const u8 *in, unsigned len)
305 {
306 unsigned i;
307 for (i = 0; i < len; ++i)
308 out[i] = in[len-1-i];
309 }
310
311/* From OpenSSL BIGNUM to internal representation */
312static int BN_to_felem(felem out, const BIGNUM *bn)
313 {
314 felem_bytearray b_in;
315 felem_bytearray b_out;
316 unsigned num_bytes;
317
318 /* BN_bn2bin eats leading zeroes */
319 memset(b_out, 0, sizeof b_out);
320 num_bytes = BN_num_bytes(bn);
321 if (num_bytes > sizeof b_out)
322 {
323 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
324 return 0;
325 }
326 if (BN_is_negative(bn))
327 {
328 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
329 return 0;
330 }
331 num_bytes = BN_bn2bin(bn, b_in);
332 flip_endian(b_out, b_in, num_bytes);
333 bin28_to_felem(out, b_out);
334 return 1;
335 }
336
337/* From internal representation to OpenSSL BIGNUM */
338static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
339 {
340 felem_bytearray b_in, b_out;
341 felem_to_bin28(b_in, in);
342 flip_endian(b_out, b_in, sizeof b_out);
343 return BN_bin2bn(b_out, sizeof b_out, out);
344 }
345
346/******************************************************************************/
347/* FIELD OPERATIONS
348 *
349 * Field operations, using the internal representation of field elements.
350 * NB! These operations are specific to our point multiplication and cannot be
351 * expected to be correct in general - e.g., multiplication with a large scalar
352 * will cause an overflow.
353 *
354 */
355
356static void felem_one(felem out)
357 {
358 out[0] = 1;
359 out[1] = 0;
360 out[2] = 0;
361 out[3] = 0;
362 }
363
364static void felem_assign(felem out, const felem in)
365 {
366 out[0] = in[0];
367 out[1] = in[1];
368 out[2] = in[2];
369 out[3] = in[3];
370 }
371
372/* Sum two field elements: out += in */
373static void felem_sum(felem out, const felem in)
374 {
375 out[0] += in[0];
376 out[1] += in[1];
377 out[2] += in[2];
378 out[3] += in[3];
379 }
380
381/* Get negative value: out = -in */
382/* Assumes in[i] < 2^57 */
383static void felem_neg(felem out, const felem in)
384 {
385 static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
386 static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
387 static const limb two58m42m2 = (((limb) 1) << 58) -
388 (((limb) 1) << 42) - (((limb) 1) << 2);
389
390 /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
391 out[0] = two58p2 - in[0];
392 out[1] = two58m42m2 - in[1];
393 out[2] = two58m2 - in[2];
394 out[3] = two58m2 - in[3];
395 }
396
397/* Subtract field elements: out -= in */
398/* Assumes in[i] < 2^57 */
399static void felem_diff(felem out, const felem in)
400 {
401 static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
402 static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
403 static const limb two58m42m2 = (((limb) 1) << 58) -
404 (((limb) 1) << 42) - (((limb) 1) << 2);
405
406 /* Add 0 mod 2^224-2^96+1 to ensure out > in */
407 out[0] += two58p2;
408 out[1] += two58m42m2;
409 out[2] += two58m2;
410 out[3] += two58m2;
411
412 out[0] -= in[0];
413 out[1] -= in[1];
414 out[2] -= in[2];
415 out[3] -= in[3];
416 }
417
418/* Subtract in unreduced 128-bit mode: out -= in */
419/* Assumes in[i] < 2^119 */
420static void widefelem_diff(widefelem out, const widefelem in)
421 {
422 static const widelimb two120 = ((widelimb) 1) << 120;
423 static const widelimb two120m64 = (((widelimb) 1) << 120) -
424 (((widelimb) 1) << 64);
425 static const widelimb two120m104m64 = (((widelimb) 1) << 120) -
426 (((widelimb) 1) << 104) - (((widelimb) 1) << 64);
427
428 /* Add 0 mod 2^224-2^96+1 to ensure out > in */
429 out[0] += two120;
430 out[1] += two120m64;
431 out[2] += two120m64;
432 out[3] += two120;
433 out[4] += two120m104m64;
434 out[5] += two120m64;
435 out[6] += two120m64;
436
437 out[0] -= in[0];
438 out[1] -= in[1];
439 out[2] -= in[2];
440 out[3] -= in[3];
441 out[4] -= in[4];
442 out[5] -= in[5];
443 out[6] -= in[6];
444 }
445
446/* Subtract in mixed mode: out128 -= in64 */
447/* in[i] < 2^63 */
448static void felem_diff_128_64(widefelem out, const felem in)
449 {
450 static const widelimb two64p8 = (((widelimb) 1) << 64) +
451 (((widelimb) 1) << 8);
452 static const widelimb two64m8 = (((widelimb) 1) << 64) -
453 (((widelimb) 1) << 8);
454 static const widelimb two64m48m8 = (((widelimb) 1) << 64) -
455 (((widelimb) 1) << 48) - (((widelimb) 1) << 8);
456
457 /* Add 0 mod 2^224-2^96+1 to ensure out > in */
458 out[0] += two64p8;
459 out[1] += two64m48m8;
460 out[2] += two64m8;
461 out[3] += two64m8;
462
463 out[0] -= in[0];
464 out[1] -= in[1];
465 out[2] -= in[2];
466 out[3] -= in[3];
467 }
468
469/* Multiply a field element by a scalar: out = out * scalar
470 * The scalars we actually use are small, so results fit without overflow */
471static void felem_scalar(felem out, const limb scalar)
472 {
473 out[0] *= scalar;
474 out[1] *= scalar;
475 out[2] *= scalar;
476 out[3] *= scalar;
477 }
478
479/* Multiply an unreduced field element by a scalar: out = out * scalar
480 * The scalars we actually use are small, so results fit without overflow */
481static void widefelem_scalar(widefelem out, const widelimb scalar)
482 {
483 out[0] *= scalar;
484 out[1] *= scalar;
485 out[2] *= scalar;
486 out[3] *= scalar;
487 out[4] *= scalar;
488 out[5] *= scalar;
489 out[6] *= scalar;
490 }
491
492/* Square a field element: out = in^2 */
493static void felem_square(widefelem out, const felem in)
494 {
495 limb tmp0, tmp1, tmp2;
496 tmp0 = 2 * in[0]; tmp1 = 2 * in[1]; tmp2 = 2 * in[2];
497 out[0] = ((widelimb) in[0]) * in[0];
498 out[1] = ((widelimb) in[0]) * tmp1;
499 out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1];
500 out[3] = ((widelimb) in[3]) * tmp0 +
501 ((widelimb) in[1]) * tmp2;
502 out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2];
503 out[5] = ((widelimb) in[3]) * tmp2;
504 out[6] = ((widelimb) in[3]) * in[3];
505 }
506
507/* Multiply two field elements: out = in1 * in2 */
508static void felem_mul(widefelem out, const felem in1, const felem in2)
509 {
510 out[0] = ((widelimb) in1[0]) * in2[0];
511 out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
512 out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
513 ((widelimb) in1[2]) * in2[0];
514 out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
515 ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
516 out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
517 ((widelimb) in1[3]) * in2[1];
518 out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
519 out[6] = ((widelimb) in1[3]) * in2[3];
520 }
521
522/* Reduce seven 128-bit coefficients to four 64-bit coefficients.
523 * Requires in[i] < 2^126,
524 * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
525static void felem_reduce(felem out, const widefelem in)
526 {
527 static const widelimb two127p15 = (((widelimb) 1) << 127) +
528 (((widelimb) 1) << 15);
529 static const widelimb two127m71 = (((widelimb) 1) << 127) -
530 (((widelimb) 1) << 71);
531 static const widelimb two127m71m55 = (((widelimb) 1) << 127) -
532 (((widelimb) 1) << 71) - (((widelimb) 1) << 55);
533 widelimb output[5];
534
535 /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
536 output[0] = in[0] + two127p15;
537 output[1] = in[1] + two127m71m55;
538 output[2] = in[2] + two127m71;
539 output[3] = in[3];
540 output[4] = in[4];
541
542 /* Eliminate in[4], in[5], in[6] */
543 output[4] += in[6] >> 16;
544 output[3] += (in[6] & 0xffff) << 40;
545 output[2] -= in[6];
546
547 output[3] += in[5] >> 16;
548 output[2] += (in[5] & 0xffff) << 40;
549 output[1] -= in[5];
550
551 output[2] += output[4] >> 16;
552 output[1] += (output[4] & 0xffff) << 40;
553 output[0] -= output[4];
554
555 /* Carry 2 -> 3 -> 4 */
556 output[3] += output[2] >> 56;
557 output[2] &= 0x00ffffffffffffff;
558
559 output[4] = output[3] >> 56;
560 output[3] &= 0x00ffffffffffffff;
561
562 /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
563
564 /* Eliminate output[4] */
565 output[2] += output[4] >> 16;
566 /* output[2] < 2^56 + 2^56 = 2^57 */
567 output[1] += (output[4] & 0xffff) << 40;
568 output[0] -= output[4];
569
570 /* Carry 0 -> 1 -> 2 -> 3 */
571 output[1] += output[0] >> 56;
572 out[0] = output[0] & 0x00ffffffffffffff;
573
574 output[2] += output[1] >> 56;
575 /* output[2] < 2^57 + 2^72 */
576 out[1] = output[1] & 0x00ffffffffffffff;
577 output[3] += output[2] >> 56;
578 /* output[3] <= 2^56 + 2^16 */
579 out[2] = output[2] & 0x00ffffffffffffff;
580
581 /* out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
582 * out[3] <= 2^56 + 2^16 (due to final carry),
583 * so out < 2*p */
584 out[3] = output[3];
585 }
586
587static void felem_square_reduce(felem out, const felem in)
588 {
589 widefelem tmp;
590 felem_square(tmp, in);
591 felem_reduce(out, tmp);
592 }
593
594static void felem_mul_reduce(felem out, const felem in1, const felem in2)
595 {
596 widefelem tmp;
597 felem_mul(tmp, in1, in2);
598 felem_reduce(out, tmp);
599 }
600
601/* Reduce to unique minimal representation.
602 * Requires 0 <= in < 2*p (always call felem_reduce first) */
603static void felem_contract(felem out, const felem in)
604 {
605 static const int64_t two56 = ((limb) 1) << 56;
606 /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
607 /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
608 int64_t tmp[4], a;
609 tmp[0] = in[0];
610 tmp[1] = in[1];
611 tmp[2] = in[2];
612 tmp[3] = in[3];
613 /* Case 1: a = 1 iff in >= 2^224 */
614 a = (in[3] >> 56);
615 tmp[0] -= a;
616 tmp[1] += a << 40;
617 tmp[3] &= 0x00ffffffffffffff;
618 /* Case 2: a = 0 iff p <= in < 2^224, i.e.,
619 * the high 128 bits are all 1 and the lower part is non-zero */
620 a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
621 (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
622 a &= 0x00ffffffffffffff;
623 /* turn a into an all-one mask (if a = 0) or an all-zero mask */
624 a = (a - 1) >> 63;
625 /* subtract 2^224 - 2^96 + 1 if a is all-one*/
626 tmp[3] &= a ^ 0xffffffffffffffff;
627 tmp[2] &= a ^ 0xffffffffffffffff;
628 tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
629 tmp[0] -= 1 & a;
630
631 /* eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
632 * be non-zero, so we only need one step */
633 a = tmp[0] >> 63;
634 tmp[0] += two56 & a;
635 tmp[1] -= 1 & a;
636
637 /* carry 1 -> 2 -> 3 */
638 tmp[2] += tmp[1] >> 56;
639 tmp[1] &= 0x00ffffffffffffff;
640
641 tmp[3] += tmp[2] >> 56;
642 tmp[2] &= 0x00ffffffffffffff;
643
644 /* Now 0 <= out < p */
645 out[0] = tmp[0];
646 out[1] = tmp[1];
647 out[2] = tmp[2];
648 out[3] = tmp[3];
649 }
650
651/* Zero-check: returns 1 if input is 0, and 0 otherwise.
652 * We know that field elements are reduced to in < 2^225,
653 * so we only need to check three cases: 0, 2^224 - 2^96 + 1,
654 * and 2^225 - 2^97 + 2 */
655static limb felem_is_zero(const felem in)
656 {
657 limb zero, two224m96p1, two225m97p2;
658
659 zero = in[0] | in[1] | in[2] | in[3];
660 zero = (((int64_t)(zero) - 1) >> 63) & 1;
661 two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000)
662 | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff);
663 two224m96p1 = (((int64_t)(two224m96p1) - 1) >> 63) & 1;
664 two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000)
665 | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff);
666 two225m97p2 = (((int64_t)(two225m97p2) - 1) >> 63) & 1;
667 return (zero | two224m96p1 | two225m97p2);
668 }
669
670static limb felem_is_zero_int(const felem in)
671 {
672 return (int) (felem_is_zero(in) & ((limb)1));
673 }
674
675/* Invert a field element */
676/* Computation chain copied from djb's code */
677static void felem_inv(felem out, const felem in)
678 {
679 felem ftmp, ftmp2, ftmp3, ftmp4;
680 widefelem tmp;
681 unsigned i;
682
683 felem_square(tmp, in); felem_reduce(ftmp, tmp); /* 2 */
684 felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^2 - 1 */
685 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2 */
686 felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 1 */
687 felem_square(tmp, ftmp); felem_reduce(ftmp2, tmp); /* 2^4 - 2 */
688 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^5 - 4 */
689 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^6 - 8 */
690 felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp, tmp); /* 2^6 - 1 */
691 felem_square(tmp, ftmp); felem_reduce(ftmp2, tmp); /* 2^7 - 2 */
692 for (i = 0; i < 5; ++i) /* 2^12 - 2^6 */
693 {
694 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
695 }
696 felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp2, tmp); /* 2^12 - 1 */
697 felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp); /* 2^13 - 2 */
698 for (i = 0; i < 11; ++i) /* 2^24 - 2^12 */
699 {
700 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);
701 }
702 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp2, tmp); /* 2^24 - 1 */
703 felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp); /* 2^25 - 2 */
704 for (i = 0; i < 23; ++i) /* 2^48 - 2^24 */
705 {
706 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp);
707 }
708 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^48 - 1 */
709 felem_square(tmp, ftmp3); felem_reduce(ftmp4, tmp); /* 2^49 - 2 */
710 for (i = 0; i < 47; ++i) /* 2^96 - 2^48 */
711 {
712 felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp);
713 }
714 felem_mul(tmp, ftmp3, ftmp4); felem_reduce(ftmp3, tmp); /* 2^96 - 1 */
715 felem_square(tmp, ftmp3); felem_reduce(ftmp4, tmp); /* 2^97 - 2 */
716 for (i = 0; i < 23; ++i) /* 2^120 - 2^24 */
717 {
718 felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp);
719 }
720 felem_mul(tmp, ftmp2, ftmp4); felem_reduce(ftmp2, tmp); /* 2^120 - 1 */
721 for (i = 0; i < 6; ++i) /* 2^126 - 2^6 */
722 {
723 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
724 }
725 felem_mul(tmp, ftmp2, ftmp); felem_reduce(ftmp, tmp); /* 2^126 - 1 */
726 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^127 - 2 */
727 felem_mul(tmp, ftmp, in); felem_reduce(ftmp, tmp); /* 2^127 - 1 */
728 for (i = 0; i < 97; ++i) /* 2^224 - 2^97 */
729 {
730 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
731 }
732 felem_mul(tmp, ftmp, ftmp3); felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */
733 }
734
735/* Copy in constant time:
736 * if icopy == 1, copy in to out,
737 * if icopy == 0, copy out to itself. */
738static void
739copy_conditional(felem out, const felem in, limb icopy)
740 {
741 unsigned i;
742 /* icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one */
743 const limb copy = -icopy;
744 for (i = 0; i < 4; ++i)
745 {
746 const limb tmp = copy & (in[i] ^ out[i]);
747 out[i] ^= tmp;
748 }
749 }
750
751/******************************************************************************/
752/* ELLIPTIC CURVE POINT OPERATIONS
753 *
754 * Points are represented in Jacobian projective coordinates:
755 * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
756 * or to the point at infinity if Z == 0.
757 *
758 */
759
760/* Double an elliptic curve point:
761 * (X', Y', Z') = 2 * (X, Y, Z), where
762 * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
763 * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
764 * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
765 * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
766 * while x_out == y_in is not (maybe this works, but it's not tested). */
767static void
768point_double(felem x_out, felem y_out, felem z_out,
769 const felem x_in, const felem y_in, const felem z_in)
770 {
771 widefelem tmp, tmp2;
772 felem delta, gamma, beta, alpha, ftmp, ftmp2;
773
774 felem_assign(ftmp, x_in);
775 felem_assign(ftmp2, x_in);
776
777 /* delta = z^2 */
778 felem_square(tmp, z_in);
779 felem_reduce(delta, tmp);
780
781 /* gamma = y^2 */
782 felem_square(tmp, y_in);
783 felem_reduce(gamma, tmp);
784
785 /* beta = x*gamma */
786 felem_mul(tmp, x_in, gamma);
787 felem_reduce(beta, tmp);
788
789 /* alpha = 3*(x-delta)*(x+delta) */
790 felem_diff(ftmp, delta);
791 /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
792 felem_sum(ftmp2, delta);
793 /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
794 felem_scalar(ftmp2, 3);
795 /* ftmp2[i] < 3 * 2^58 < 2^60 */
796 felem_mul(tmp, ftmp, ftmp2);
797 /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
798 felem_reduce(alpha, tmp);
799
800 /* x' = alpha^2 - 8*beta */
801 felem_square(tmp, alpha);
802 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
803 felem_assign(ftmp, beta);
804 felem_scalar(ftmp, 8);
805 /* ftmp[i] < 8 * 2^57 = 2^60 */
806 felem_diff_128_64(tmp, ftmp);
807 /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
808 felem_reduce(x_out, tmp);
809
810 /* z' = (y + z)^2 - gamma - delta */
811 felem_sum(delta, gamma);
812 /* delta[i] < 2^57 + 2^57 = 2^58 */
813 felem_assign(ftmp, y_in);
814 felem_sum(ftmp, z_in);
815 /* ftmp[i] < 2^57 + 2^57 = 2^58 */
816 felem_square(tmp, ftmp);
817 /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
818 felem_diff_128_64(tmp, delta);
819 /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
820 felem_reduce(z_out, tmp);
821
822 /* y' = alpha*(4*beta - x') - 8*gamma^2 */
823 felem_scalar(beta, 4);
824 /* beta[i] < 4 * 2^57 = 2^59 */
825 felem_diff(beta, x_out);
826 /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
827 felem_mul(tmp, alpha, beta);
828 /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
829 felem_square(tmp2, gamma);
830 /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
831 widefelem_scalar(tmp2, 8);
832 /* tmp2[i] < 8 * 2^116 = 2^119 */
833 widefelem_diff(tmp, tmp2);
834 /* tmp[i] < 2^119 + 2^120 < 2^121 */
835 felem_reduce(y_out, tmp);
836 }
837
838/* Add two elliptic curve points:
839 * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
840 * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
841 * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
842 * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) -
843 * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
844 * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
845 *
846 * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
847 */
848
849/* This function is not entirely constant-time:
850 * it includes a branch for checking whether the two input points are equal,
851 * (while not equal to the point at infinity).
852 * This case never happens during single point multiplication,
853 * so there is no timing leak for ECDH or ECDSA signing. */
854static void point_add(felem x3, felem y3, felem z3,
855 const felem x1, const felem y1, const felem z1,
856 const int mixed, const felem x2, const felem y2, const felem z2)
857 {
858 felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
859 widefelem tmp, tmp2;
860 limb z1_is_zero, z2_is_zero, x_equal, y_equal;
861
862 if (!mixed)
863 {
864 /* ftmp2 = z2^2 */
865 felem_square(tmp, z2);
866 felem_reduce(ftmp2, tmp);
867
868 /* ftmp4 = z2^3 */
869 felem_mul(tmp, ftmp2, z2);
870 felem_reduce(ftmp4, tmp);
871
872 /* ftmp4 = z2^3*y1 */
873 felem_mul(tmp2, ftmp4, y1);
874 felem_reduce(ftmp4, tmp2);
875
876 /* ftmp2 = z2^2*x1 */
877 felem_mul(tmp2, ftmp2, x1);
878 felem_reduce(ftmp2, tmp2);
879 }
880 else
881 {
882 /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
883
884 /* ftmp4 = z2^3*y1 */
885 felem_assign(ftmp4, y1);
886
887 /* ftmp2 = z2^2*x1 */
888 felem_assign(ftmp2, x1);
889 }
890
891 /* ftmp = z1^2 */
892 felem_square(tmp, z1);
893 felem_reduce(ftmp, tmp);
894
895 /* ftmp3 = z1^3 */
896 felem_mul(tmp, ftmp, z1);
897 felem_reduce(ftmp3, tmp);
898
899 /* tmp = z1^3*y2 */
900 felem_mul(tmp, ftmp3, y2);
901 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
902
903 /* ftmp3 = z1^3*y2 - z2^3*y1 */
904 felem_diff_128_64(tmp, ftmp4);
905 /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
906 felem_reduce(ftmp3, tmp);
907
908 /* tmp = z1^2*x2 */
909 felem_mul(tmp, ftmp, x2);
910 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
911
912 /* ftmp = z1^2*x2 - z2^2*x1 */
913 felem_diff_128_64(tmp, ftmp2);
914 /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
915 felem_reduce(ftmp, tmp);
916
917 /* the formulae are incorrect if the points are equal
918 * so we check for this and do doubling if this happens */
919 x_equal = felem_is_zero(ftmp);
920 y_equal = felem_is_zero(ftmp3);
921 z1_is_zero = felem_is_zero(z1);
922 z2_is_zero = felem_is_zero(z2);
923 /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
924 if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
925 {
926 point_double(x3, y3, z3, x1, y1, z1);
927 return;
928 }
929
930 /* ftmp5 = z1*z2 */
931 if (!mixed)
932 {
933 felem_mul(tmp, z1, z2);
934 felem_reduce(ftmp5, tmp);
935 }
936 else
937 {
938 /* special case z2 = 0 is handled later */
939 felem_assign(ftmp5, z1);
940 }
941
942 /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
943 felem_mul(tmp, ftmp, ftmp5);
944 felem_reduce(z_out, tmp);
945
946 /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
947 felem_assign(ftmp5, ftmp);
948 felem_square(tmp, ftmp);
949 felem_reduce(ftmp, tmp);
950
951 /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
952 felem_mul(tmp, ftmp, ftmp5);
953 felem_reduce(ftmp5, tmp);
954
955 /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
956 felem_mul(tmp, ftmp2, ftmp);
957 felem_reduce(ftmp2, tmp);
958
959 /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
960 felem_mul(tmp, ftmp4, ftmp5);
961 /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
962
963 /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
964 felem_square(tmp2, ftmp3);
965 /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
966
967 /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
968 felem_diff_128_64(tmp2, ftmp5);
969 /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
970
971 /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
972 felem_assign(ftmp5, ftmp2);
973 felem_scalar(ftmp5, 2);
974 /* ftmp5[i] < 2 * 2^57 = 2^58 */
975
976 /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
977 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
978 felem_diff_128_64(tmp2, ftmp5);
979 /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
980 felem_reduce(x_out, tmp2);
981
982 /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
983 felem_diff(ftmp2, x_out);
984 /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
985
986 /* tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) */
987 felem_mul(tmp2, ftmp3, ftmp2);
988 /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
989
990 /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
991 z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
992 widefelem_diff(tmp2, tmp);
993 /* tmp2[i] < 2^118 + 2^120 < 2^121 */
994 felem_reduce(y_out, tmp2);
995
996 /* the result (x_out, y_out, z_out) is incorrect if one of the inputs is
997 * the point at infinity, so we need to check for this separately */
998
999 /* if point 1 is at infinity, copy point 2 to output, and vice versa */
1000 copy_conditional(x_out, x2, z1_is_zero);
1001 copy_conditional(x_out, x1, z2_is_zero);
1002 copy_conditional(y_out, y2, z1_is_zero);
1003 copy_conditional(y_out, y1, z2_is_zero);
1004 copy_conditional(z_out, z2, z1_is_zero);
1005 copy_conditional(z_out, z1, z2_is_zero);
1006 felem_assign(x3, x_out);
1007 felem_assign(y3, y_out);
1008 felem_assign(z3, z_out);
1009 }
1010
1011/* select_point selects the |idx|th point from a precomputation table and
1012 * copies it to out. */
1013static void select_point(const u64 idx, unsigned int size, const felem pre_comp[/*size*/][3], felem out[3])
1014 {
1015 unsigned i, j;
1016 limb *outlimbs = &out[0][0];
1017 memset(outlimbs, 0, 3 * sizeof(felem));
1018
1019 for (i = 0; i < size; i++)
1020 {
1021 const limb *inlimbs = &pre_comp[i][0][0];
1022 u64 mask = i ^ idx;
1023 mask |= mask >> 4;
1024 mask |= mask >> 2;
1025 mask |= mask >> 1;
1026 mask &= 1;
1027 mask--;
1028 for (j = 0; j < 4 * 3; j++)
1029 outlimbs[j] |= inlimbs[j] & mask;
1030 }
1031 }
1032
1033/* get_bit returns the |i|th bit in |in| */
1034static char get_bit(const felem_bytearray in, unsigned i)
1035 {
1036 if (i >= 224)
1037 return 0;
1038 return (in[i >> 3] >> (i & 7)) & 1;
1039 }
1040
1041/* Interleaved point multiplication using precomputed point multiples:
1042 * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
1043 * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
1044 * of the generator, using certain (large) precomputed multiples in g_pre_comp.
1045 * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
1046static void batch_mul(felem x_out, felem y_out, felem z_out,
1047 const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
1048 const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[2][16][3])
1049 {
1050 int i, skip;
1051 unsigned num;
1052 unsigned gen_mul = (g_scalar != NULL);
1053 felem nq[3], tmp[4];
1054 u64 bits;
1055 u8 sign, digit;
1056
1057 /* set nq to the point at infinity */
1058 memset(nq, 0, 3 * sizeof(felem));
1059
1060 /* Loop over all scalars msb-to-lsb, interleaving additions
1061 * of multiples of the generator (two in each of the last 28 rounds)
1062 * and additions of other points multiples (every 5th round).
1063 */
1064 skip = 1; /* save two point operations in the first round */
1065 for (i = (num_points ? 220 : 27); i >= 0; --i)
1066 {
1067 /* double */
1068 if (!skip)
1069 point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1070
1071 /* add multiples of the generator */
1072 if (gen_mul && (i <= 27))
1073 {
1074 /* first, look 28 bits upwards */
1075 bits = get_bit(g_scalar, i + 196) << 3;
1076 bits |= get_bit(g_scalar, i + 140) << 2;
1077 bits |= get_bit(g_scalar, i + 84) << 1;
1078 bits |= get_bit(g_scalar, i + 28);
1079 /* select the point to add, in constant time */
1080 select_point(bits, 16, g_pre_comp[1], tmp);
1081
1082 if (!skip)
1083 {
1084 point_add(nq[0], nq[1], nq[2],
1085 nq[0], nq[1], nq[2],
1086 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
1087 }
1088 else
1089 {
1090 memcpy(nq, tmp, 3 * sizeof(felem));
1091 skip = 0;
1092 }
1093
1094 /* second, look at the current position */
1095 bits = get_bit(g_scalar, i + 168) << 3;
1096 bits |= get_bit(g_scalar, i + 112) << 2;
1097 bits |= get_bit(g_scalar, i + 56) << 1;
1098 bits |= get_bit(g_scalar, i);
1099 /* select the point to add, in constant time */
1100 select_point(bits, 16, g_pre_comp[0], tmp);
1101 point_add(nq[0], nq[1], nq[2],
1102 nq[0], nq[1], nq[2],
1103 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
1104 }
1105
1106 /* do other additions every 5 doublings */
1107 if (num_points && (i % 5 == 0))
1108 {
1109 /* loop over all scalars */
1110 for (num = 0; num < num_points; ++num)
1111 {
1112 bits = get_bit(scalars[num], i + 4) << 5;
1113 bits |= get_bit(scalars[num], i + 3) << 4;
1114 bits |= get_bit(scalars[num], i + 2) << 3;
1115 bits |= get_bit(scalars[num], i + 1) << 2;
1116 bits |= get_bit(scalars[num], i) << 1;
1117 bits |= get_bit(scalars[num], i - 1);
1118 ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1119
1120 /* select the point to add or subtract */
1121 select_point(digit, 17, pre_comp[num], tmp);
1122 felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
1123 copy_conditional(tmp[1], tmp[3], sign);
1124
1125 if (!skip)
1126 {
1127 point_add(nq[0], nq[1], nq[2],
1128 nq[0], nq[1], nq[2],
1129 mixed, tmp[0], tmp[1], tmp[2]);
1130 }
1131 else
1132 {
1133 memcpy(nq, tmp, 3 * sizeof(felem));
1134 skip = 0;
1135 }
1136 }
1137 }
1138 }
1139 felem_assign(x_out, nq[0]);
1140 felem_assign(y_out, nq[1]);
1141 felem_assign(z_out, nq[2]);
1142 }
1143
1144/******************************************************************************/
1145/* FUNCTIONS TO MANAGE PRECOMPUTATION
1146 */
1147
1148static NISTP224_PRE_COMP *nistp224_pre_comp_new()
1149 {
1150 NISTP224_PRE_COMP *ret = NULL;
1151 ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
1152 if (!ret)
1153 {
1154 ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1155 return ret;
1156 }
1157 memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
1158 ret->references = 1;
1159 return ret;
1160 }
1161
1162static void *nistp224_pre_comp_dup(void *src_)
1163 {
1164 NISTP224_PRE_COMP *src = src_;
1165
1166 /* no need to actually copy, these objects never change! */
1167 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
1168
1169 return src_;
1170 }
1171
1172static void nistp224_pre_comp_free(void *pre_)
1173 {
1174 int i;
1175 NISTP224_PRE_COMP *pre = pre_;
1176
1177 if (!pre)
1178 return;
1179
1180 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1181 if (i > 0)
1182 return;
1183
1184 OPENSSL_free(pre);
1185 }
1186
1187static void nistp224_pre_comp_clear_free(void *pre_)
1188 {
1189 int i;
1190 NISTP224_PRE_COMP *pre = pre_;
1191
1192 if (!pre)
1193 return;
1194
1195 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1196 if (i > 0)
1197 return;
1198
1199 OPENSSL_cleanse(pre, sizeof *pre);
1200 OPENSSL_free(pre);
1201 }
1202
1203/******************************************************************************/
1204/* OPENSSL EC_METHOD FUNCTIONS
1205 */
1206
1207int ec_GFp_nistp224_group_init(EC_GROUP *group)
1208 {
1209 int ret;
1210 ret = ec_GFp_simple_group_init(group);
1211 group->a_is_minus3 = 1;
1212 return ret;
1213 }
1214
1215int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
1216 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1217 {
1218 int ret = 0;
1219 BN_CTX *new_ctx = NULL;
1220 BIGNUM *curve_p, *curve_a, *curve_b;
1221
1222 if (ctx == NULL)
1223 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1224 BN_CTX_start(ctx);
1225 if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
1226 ((curve_a = BN_CTX_get(ctx)) == NULL) ||
1227 ((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
1228 BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
1229 BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
1230 BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
1231 if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
1232 (BN_cmp(curve_b, b)))
1233 {
1234 ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
1235 EC_R_WRONG_CURVE_PARAMETERS);
1236 goto err;
1237 }
1238 group->field_mod_func = BN_nist_mod_224;
1239 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
1240err:
1241 BN_CTX_end(ctx);
1242 if (new_ctx != NULL)
1243 BN_CTX_free(new_ctx);
1244 return ret;
1245 }
1246
1247/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
1248 * (X', Y') = (X/Z^2, Y/Z^3) */
1249int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
1250 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
1251 {
1252 felem z1, z2, x_in, y_in, x_out, y_out;
1253 widefelem tmp;
1254
1255 if (EC_POINT_is_at_infinity(group, point))
1256 {
1257 ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
1258 EC_R_POINT_AT_INFINITY);
1259 return 0;
1260 }
1261 if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
1262 (!BN_to_felem(z1, &point->Z))) return 0;
1263 felem_inv(z2, z1);
1264 felem_square(tmp, z2); felem_reduce(z1, tmp);
1265 felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
1266 felem_contract(x_out, x_in);
1267 if (x != NULL)
1268 {
1269 if (!felem_to_BN(x, x_out)) {
1270 ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
1271 ERR_R_BN_LIB);
1272 return 0;
1273 }
1274 }
1275 felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
1276 felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
1277 felem_contract(y_out, y_in);
1278 if (y != NULL)
1279 {
1280 if (!felem_to_BN(y, y_out)) {
1281 ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
1282 ERR_R_BN_LIB);
1283 return 0;
1284 }
1285 }
1286 return 1;
1287 }
1288
1289static void make_points_affine(size_t num, felem points[/*num*/][3], felem tmp_felems[/*num+1*/])
1290 {
1291 /* Runs in constant time, unless an input is the point at infinity
1292 * (which normally shouldn't happen). */
1293 ec_GFp_nistp_points_make_affine_internal(
1294 num,
1295 points,
1296 sizeof(felem),
1297 tmp_felems,
1298 (void (*)(void *)) felem_one,
1299 (int (*)(const void *)) felem_is_zero_int,
1300 (void (*)(void *, const void *)) felem_assign,
1301 (void (*)(void *, const void *)) felem_square_reduce,
1302 (void (*)(void *, const void *, const void *)) felem_mul_reduce,
1303 (void (*)(void *, const void *)) felem_inv,
1304 (void (*)(void *, const void *)) felem_contract);
1305 }
1306
1307/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
1308 * Result is stored in r (r can equal one of the inputs). */
1309int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
1310 const BIGNUM *scalar, size_t num, const EC_POINT *points[],
1311 const BIGNUM *scalars[], BN_CTX *ctx)
1312 {
1313 int ret = 0;
1314 int j;
1315 unsigned i;
1316 int mixed = 0;
1317 BN_CTX *new_ctx = NULL;
1318 BIGNUM *x, *y, *z, *tmp_scalar;
1319 felem_bytearray g_secret;
1320 felem_bytearray *secrets = NULL;
1321 felem (*pre_comp)[17][3] = NULL;
1322 felem *tmp_felems = NULL;
1323 felem_bytearray tmp;
1324 unsigned num_bytes;
1325 int have_pre_comp = 0;
1326 size_t num_points = num;
1327 felem x_in, y_in, z_in, x_out, y_out, z_out;
1328 NISTP224_PRE_COMP *pre = NULL;
1329 const felem (*g_pre_comp)[16][3] = NULL;
1330 EC_POINT *generator = NULL;
1331 const EC_POINT *p = NULL;
1332 const BIGNUM *p_scalar = NULL;
1333
1334 if (ctx == NULL)
1335 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1336 BN_CTX_start(ctx);
1337 if (((x = BN_CTX_get(ctx)) == NULL) ||
1338 ((y = BN_CTX_get(ctx)) == NULL) ||
1339 ((z = BN_CTX_get(ctx)) == NULL) ||
1340 ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
1341 goto err;
1342
1343 if (scalar != NULL)
1344 {
1345 pre = EC_EX_DATA_get_data(group->extra_data,
1346 nistp224_pre_comp_dup, nistp224_pre_comp_free,
1347 nistp224_pre_comp_clear_free);
1348 if (pre)
1349 /* we have precomputation, try to use it */
1350 g_pre_comp = (const felem (*)[16][3]) pre->g_pre_comp;
1351 else
1352 /* try to use the standard precomputation */
1353 g_pre_comp = &gmul[0];
1354 generator = EC_POINT_new(group);
1355 if (generator == NULL)
1356 goto err;
1357 /* get the generator from precomputation */
1358 if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
1359 !felem_to_BN(y, g_pre_comp[0][1][1]) ||
1360 !felem_to_BN(z, g_pre_comp[0][1][2]))
1361 {
1362 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1363 goto err;
1364 }
1365 if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
1366 generator, x, y, z, ctx))
1367 goto err;
1368 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1369 /* precomputation matches generator */
1370 have_pre_comp = 1;
1371 else
1372 /* we don't have valid precomputation:
1373 * treat the generator as a random point */
1374 num_points = num_points + 1;
1375 }
1376
1377 if (num_points > 0)
1378 {
1379 if (num_points >= 3)
1380 {
1381 /* unless we precompute multiples for just one or two points,
1382 * converting those into affine form is time well spent */
1383 mixed = 1;
1384 }
1385 secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
1386 pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
1387 if (mixed)
1388 tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
1389 if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL)))
1390 {
1391 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1392 goto err;
1393 }
1394
1395 /* we treat NULL scalars as 0, and NULL points as points at infinity,
1396 * i.e., they contribute nothing to the linear combination */
1397 memset(secrets, 0, num_points * sizeof(felem_bytearray));
1398 memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
1399 for (i = 0; i < num_points; ++i)
1400 {
1401 if (i == num)
1402 /* the generator */
1403 {
1404 p = EC_GROUP_get0_generator(group);
1405 p_scalar = scalar;
1406 }
1407 else
1408 /* the i^th point */
1409 {
1410 p = points[i];
1411 p_scalar = scalars[i];
1412 }
1413 if ((p_scalar != NULL) && (p != NULL))
1414 {
1415 /* reduce scalar to 0 <= scalar < 2^224 */
1416 if ((BN_num_bits(p_scalar) > 224) || (BN_is_negative(p_scalar)))
1417 {
1418 /* this is an unusual input, and we don't guarantee
1419 * constant-timeness */
1420 if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
1421 {
1422 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1423 goto err;
1424 }
1425 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1426 }
1427 else
1428 num_bytes = BN_bn2bin(p_scalar, tmp);
1429 flip_endian(secrets[i], tmp, num_bytes);
1430 /* precompute multiples */
1431 if ((!BN_to_felem(x_out, &p->X)) ||
1432 (!BN_to_felem(y_out, &p->Y)) ||
1433 (!BN_to_felem(z_out, &p->Z))) goto err;
1434 felem_assign(pre_comp[i][1][0], x_out);
1435 felem_assign(pre_comp[i][1][1], y_out);
1436 felem_assign(pre_comp[i][1][2], z_out);
1437 for (j = 2; j <= 16; ++j)
1438 {
1439 if (j & 1)
1440 {
1441 point_add(
1442 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1443 pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
1444 0, pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
1445 }
1446 else
1447 {
1448 point_double(
1449 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1450 pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
1451 }
1452 }
1453 }
1454 }
1455 if (mixed)
1456 make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
1457 }
1458
1459 /* the scalar for the generator */
1460 if ((scalar != NULL) && (have_pre_comp))
1461 {
1462 memset(g_secret, 0, sizeof g_secret);
1463 /* reduce scalar to 0 <= scalar < 2^224 */
1464 if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar)))
1465 {
1466 /* this is an unusual input, and we don't guarantee
1467 * constant-timeness */
1468 if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
1469 {
1470 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1471 goto err;
1472 }
1473 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1474 }
1475 else
1476 num_bytes = BN_bn2bin(scalar, tmp);
1477 flip_endian(g_secret, tmp, num_bytes);
1478 /* do the multiplication with generator precomputation*/
1479 batch_mul(x_out, y_out, z_out,
1480 (const felem_bytearray (*)) secrets, num_points,
1481 g_secret,
1482 mixed, (const felem (*)[17][3]) pre_comp,
1483 g_pre_comp);
1484 }
1485 else
1486 /* do the multiplication without generator precomputation */
1487 batch_mul(x_out, y_out, z_out,
1488 (const felem_bytearray (*)) secrets, num_points,
1489 NULL, mixed, (const felem (*)[17][3]) pre_comp, NULL);
1490 /* reduce the output to its unique minimal representation */
1491 felem_contract(x_in, x_out);
1492 felem_contract(y_in, y_out);
1493 felem_contract(z_in, z_out);
1494 if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
1495 (!felem_to_BN(z, z_in)))
1496 {
1497 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
1498 goto err;
1499 }
1500 ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
1501
1502err:
1503 BN_CTX_end(ctx);
1504 if (generator != NULL)
1505 EC_POINT_free(generator);
1506 if (new_ctx != NULL)
1507 BN_CTX_free(new_ctx);
1508 if (secrets != NULL)
1509 OPENSSL_free(secrets);
1510 if (pre_comp != NULL)
1511 OPENSSL_free(pre_comp);
1512 if (tmp_felems != NULL)
1513 OPENSSL_free(tmp_felems);
1514 return ret;
1515 }
1516
1517int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
1518 {
1519 int ret = 0;
1520 NISTP224_PRE_COMP *pre = NULL;
1521 int i, j;
1522 BN_CTX *new_ctx = NULL;
1523 BIGNUM *x, *y;
1524 EC_POINT *generator = NULL;
1525 felem tmp_felems[32];
1526
1527 /* throw away old precomputation */
1528 EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup,
1529 nistp224_pre_comp_free, nistp224_pre_comp_clear_free);
1530 if (ctx == NULL)
1531 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1532 BN_CTX_start(ctx);
1533 if (((x = BN_CTX_get(ctx)) == NULL) ||
1534 ((y = BN_CTX_get(ctx)) == NULL))
1535 goto err;
1536 /* get the generator */
1537 if (group->generator == NULL) goto err;
1538 generator = EC_POINT_new(group);
1539 if (generator == NULL)
1540 goto err;
1541 BN_bin2bn(nistp224_curve_params[3], sizeof (felem_bytearray), x);
1542 BN_bin2bn(nistp224_curve_params[4], sizeof (felem_bytearray), y);
1543 if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
1544 goto err;
1545 if ((pre = nistp224_pre_comp_new()) == NULL)
1546 goto err;
1547 /* if the generator is the standard one, use built-in precomputation */
1548 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1549 {
1550 memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
1551 ret = 1;
1552 goto err;
1553 }
1554 if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) ||
1555 (!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) ||
1556 (!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z)))
1557 goto err;
1558 /* compute 2^56*G, 2^112*G, 2^168*G for the first table,
1559 * 2^28*G, 2^84*G, 2^140*G, 2^196*G for the second one
1560 */
1561 for (i = 1; i <= 8; i <<= 1)
1562 {
1563 point_double(
1564 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
1565 pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
1566 for (j = 0; j < 27; ++j)
1567 {
1568 point_double(
1569 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
1570 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
1571 }
1572 if (i == 8)
1573 break;
1574 point_double(
1575 pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
1576 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
1577 for (j = 0; j < 27; ++j)
1578 {
1579 point_double(
1580 pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
1581 pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2]);
1582 }
1583 }
1584 for (i = 0; i < 2; i++)
1585 {
1586 /* g_pre_comp[i][0] is the point at infinity */
1587 memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
1588 /* the remaining multiples */
1589 /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */
1590 point_add(
1591 pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
1592 pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
1593 pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
1594 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
1595 pre->g_pre_comp[i][2][2]);
1596 /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */
1597 point_add(
1598 pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
1599 pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
1600 pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
1601 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
1602 pre->g_pre_comp[i][2][2]);
1603 /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */
1604 point_add(
1605 pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
1606 pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
1607 pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
1608 0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
1609 pre->g_pre_comp[i][4][2]);
1610 /* 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G */
1611 point_add(
1612 pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
1613 pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
1614 pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
1615 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
1616 pre->g_pre_comp[i][2][2]);
1617 for (j = 1; j < 8; ++j)
1618 {
1619 /* odd multiples: add G resp. 2^28*G */
1620 point_add(
1621 pre->g_pre_comp[i][2*j+1][0], pre->g_pre_comp[i][2*j+1][1],
1622 pre->g_pre_comp[i][2*j+1][2], pre->g_pre_comp[i][2*j][0],
1623 pre->g_pre_comp[i][2*j][1], pre->g_pre_comp[i][2*j][2],
1624 0, pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1],
1625 pre->g_pre_comp[i][1][2]);
1626 }
1627 }
1628 make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems);
1629
1630 if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup,
1631 nistp224_pre_comp_free, nistp224_pre_comp_clear_free))
1632 goto err;
1633 ret = 1;
1634 pre = NULL;
1635 err:
1636 BN_CTX_end(ctx);
1637 if (generator != NULL)
1638 EC_POINT_free(generator);
1639 if (new_ctx != NULL)
1640 BN_CTX_free(new_ctx);
1641 if (pre)
1642 nistp224_pre_comp_free(pre);
1643 return ret;
1644 }
1645
1646int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
1647 {
1648 if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup,
1649 nistp224_pre_comp_free, nistp224_pre_comp_clear_free)
1650 != NULL)
1651 return 1;
1652 else
1653 return 0;
1654 }
1655
1656#else
1657static void *dummy=&dummy;
1658#endif
diff --git a/src/lib/libcrypto/ec/ecp_nistp256.c b/src/lib/libcrypto/ec/ecp_nistp256.c
deleted file mode 100644
index 4bc0f5dce0..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp256.c
+++ /dev/null
@@ -1,2171 +0,0 @@
1/* crypto/ec/ecp_nistp256.c */
2/*
3 * Written by Adam Langley (Google) for the OpenSSL project
4 */
5/* Copyright 2011 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 *
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21/*
22 * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
23 *
24 * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
25 * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
26 * work which got its smarts from Daniel J. Bernstein's work on the same.
27 */
28
29#include <openssl/opensslconf.h>
30#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
31
32#ifndef OPENSSL_SYS_VMS
33#include <stdint.h>
34#else
35#include <inttypes.h>
36#endif
37
38#include <string.h>
39#include <openssl/err.h>
40#include "ec_lcl.h"
41
42#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
43 /* even with gcc, the typedef won't work for 32-bit platforms */
44 typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
45 typedef __int128_t int128_t;
46#else
47 #error "Need GCC 3.1 or later to define type uint128_t"
48#endif
49
50typedef uint8_t u8;
51typedef uint32_t u32;
52typedef uint64_t u64;
53typedef int64_t s64;
54
55/* The underlying field.
56 *
57 * P256 operates over GF(2^256-2^224+2^192+2^96-1). We can serialise an element
58 * of this field into 32 bytes. We call this an felem_bytearray. */
59
60typedef u8 felem_bytearray[32];
61
62/* These are the parameters of P256, taken from FIPS 186-3, page 86. These
63 * values are big-endian. */
64static const felem_bytearray nistp256_curve_params[5] = {
65 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
68 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
69 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
72 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
73 {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
74 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
75 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
76 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
77 {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
78 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
79 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
80 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
81 {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
82 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
83 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
84 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}
85};
86
87/* The representation of field elements.
88 * ------------------------------------
89 *
90 * We represent field elements with either four 128-bit values, eight 128-bit
91 * values, or four 64-bit values. The field element represented is:
92 * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p)
93 * or:
94 * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p)
95 *
96 * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
97 * apart, but are 128-bits wide, the most significant bits of each limb overlap
98 * with the least significant bits of the next.
99 *
100 * A field element with four limbs is an 'felem'. One with eight limbs is a
101 * 'longfelem'
102 *
103 * A field element with four, 64-bit values is called a 'smallfelem'. Small
104 * values are used as intermediate values before multiplication.
105 */
106
107#define NLIMBS 4
108
109typedef uint128_t limb;
110typedef limb felem[NLIMBS];
111typedef limb longfelem[NLIMBS * 2];
112typedef u64 smallfelem[NLIMBS];
113
114/* This is the value of the prime as four 64-bit words, little-endian. */
115static const u64 kPrime[4] = { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
116static const limb bottom32bits = 0xffffffff;
117static const u64 bottom63bits = 0x7ffffffffffffffful;
118
119/* bin32_to_felem takes a little-endian byte array and converts it into felem
120 * form. This assumes that the CPU is little-endian. */
121static void bin32_to_felem(felem out, const u8 in[32])
122 {
123 out[0] = *((u64*) &in[0]);
124 out[1] = *((u64*) &in[8]);
125 out[2] = *((u64*) &in[16]);
126 out[3] = *((u64*) &in[24]);
127 }
128
129/* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
130 * 32 byte array. This assumes that the CPU is little-endian. */
131static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
132 {
133 *((u64*) &out[0]) = in[0];
134 *((u64*) &out[8]) = in[1];
135 *((u64*) &out[16]) = in[2];
136 *((u64*) &out[24]) = in[3];
137 }
138
139/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
140static void flip_endian(u8 *out, const u8 *in, unsigned len)
141 {
142 unsigned i;
143 for (i = 0; i < len; ++i)
144 out[i] = in[len-1-i];
145 }
146
147/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
148static int BN_to_felem(felem out, const BIGNUM *bn)
149 {
150 felem_bytearray b_in;
151 felem_bytearray b_out;
152 unsigned num_bytes;
153
154 /* BN_bn2bin eats leading zeroes */
155 memset(b_out, 0, sizeof b_out);
156 num_bytes = BN_num_bytes(bn);
157 if (num_bytes > sizeof b_out)
158 {
159 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
160 return 0;
161 }
162 if (BN_is_negative(bn))
163 {
164 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
165 return 0;
166 }
167 num_bytes = BN_bn2bin(bn, b_in);
168 flip_endian(b_out, b_in, num_bytes);
169 bin32_to_felem(out, b_out);
170 return 1;
171 }
172
173/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
174static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
175 {
176 felem_bytearray b_in, b_out;
177 smallfelem_to_bin32(b_in, in);
178 flip_endian(b_out, b_in, sizeof b_out);
179 return BN_bin2bn(b_out, sizeof b_out, out);
180 }
181
182
183/* Field operations
184 * ---------------- */
185
186static void smallfelem_one(smallfelem out)
187 {
188 out[0] = 1;
189 out[1] = 0;
190 out[2] = 0;
191 out[3] = 0;
192 }
193
194static void smallfelem_assign(smallfelem out, const smallfelem in)
195 {
196 out[0] = in[0];
197 out[1] = in[1];
198 out[2] = in[2];
199 out[3] = in[3];
200 }
201
202static void felem_assign(felem out, const felem in)
203 {
204 out[0] = in[0];
205 out[1] = in[1];
206 out[2] = in[2];
207 out[3] = in[3];
208 }
209
210/* felem_sum sets out = out + in. */
211static void felem_sum(felem out, const felem in)
212 {
213 out[0] += in[0];
214 out[1] += in[1];
215 out[2] += in[2];
216 out[3] += in[3];
217 }
218
219/* felem_small_sum sets out = out + in. */
220static void felem_small_sum(felem out, const smallfelem in)
221 {
222 out[0] += in[0];
223 out[1] += in[1];
224 out[2] += in[2];
225 out[3] += in[3];
226 }
227
228/* felem_scalar sets out = out * scalar */
229static void felem_scalar(felem out, const u64 scalar)
230 {
231 out[0] *= scalar;
232 out[1] *= scalar;
233 out[2] *= scalar;
234 out[3] *= scalar;
235 }
236
237/* longfelem_scalar sets out = out * scalar */
238static void longfelem_scalar(longfelem out, const u64 scalar)
239 {
240 out[0] *= scalar;
241 out[1] *= scalar;
242 out[2] *= scalar;
243 out[3] *= scalar;
244 out[4] *= scalar;
245 out[5] *= scalar;
246 out[6] *= scalar;
247 out[7] *= scalar;
248 }
249
250#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
251#define two105 (((limb)1) << 105)
252#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
253
254/* zero105 is 0 mod p */
255static const felem zero105 = { two105m41m9, two105, two105m41p9, two105m41p9 };
256
257/* smallfelem_neg sets |out| to |-small|
258 * On exit:
259 * out[i] < out[i] + 2^105
260 */
261static void smallfelem_neg(felem out, const smallfelem small)
262 {
263 /* In order to prevent underflow, we subtract from 0 mod p. */
264 out[0] = zero105[0] - small[0];
265 out[1] = zero105[1] - small[1];
266 out[2] = zero105[2] - small[2];
267 out[3] = zero105[3] - small[3];
268 }
269
270/* felem_diff subtracts |in| from |out|
271 * On entry:
272 * in[i] < 2^104
273 * On exit:
274 * out[i] < out[i] + 2^105
275 */
276static void felem_diff(felem out, const felem in)
277 {
278 /* In order to prevent underflow, we add 0 mod p before subtracting. */
279 out[0] += zero105[0];
280 out[1] += zero105[1];
281 out[2] += zero105[2];
282 out[3] += zero105[3];
283
284 out[0] -= in[0];
285 out[1] -= in[1];
286 out[2] -= in[2];
287 out[3] -= in[3];
288 }
289
290#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
291#define two107 (((limb)1) << 107)
292#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
293
294/* zero107 is 0 mod p */
295static const felem zero107 = { two107m43m11, two107, two107m43p11, two107m43p11 };
296
297/* An alternative felem_diff for larger inputs |in|
298 * felem_diff_zero107 subtracts |in| from |out|
299 * On entry:
300 * in[i] < 2^106
301 * On exit:
302 * out[i] < out[i] + 2^107
303 */
304static void felem_diff_zero107(felem out, const felem in)
305 {
306 /* In order to prevent underflow, we add 0 mod p before subtracting. */
307 out[0] += zero107[0];
308 out[1] += zero107[1];
309 out[2] += zero107[2];
310 out[3] += zero107[3];
311
312 out[0] -= in[0];
313 out[1] -= in[1];
314 out[2] -= in[2];
315 out[3] -= in[3];
316 }
317
318/* longfelem_diff subtracts |in| from |out|
319 * On entry:
320 * in[i] < 7*2^67
321 * On exit:
322 * out[i] < out[i] + 2^70 + 2^40
323 */
324static void longfelem_diff(longfelem out, const longfelem in)
325 {
326 static const limb two70m8p6 = (((limb)1) << 70) - (((limb)1) << 8) + (((limb)1) << 6);
327 static const limb two70p40 = (((limb)1) << 70) + (((limb)1) << 40);
328 static const limb two70 = (((limb)1) << 70);
329 static const limb two70m40m38p6 = (((limb)1) << 70) - (((limb)1) << 40) - (((limb)1) << 38) + (((limb)1) << 6);
330 static const limb two70m6 = (((limb)1) << 70) - (((limb)1) << 6);
331
332 /* add 0 mod p to avoid underflow */
333 out[0] += two70m8p6;
334 out[1] += two70p40;
335 out[2] += two70;
336 out[3] += two70m40m38p6;
337 out[4] += two70m6;
338 out[5] += two70m6;
339 out[6] += two70m6;
340 out[7] += two70m6;
341
342 /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */
343 out[0] -= in[0];
344 out[1] -= in[1];
345 out[2] -= in[2];
346 out[3] -= in[3];
347 out[4] -= in[4];
348 out[5] -= in[5];
349 out[6] -= in[6];
350 out[7] -= in[7];
351 }
352
353#define two64m0 (((limb)1) << 64) - 1
354#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
355#define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
356#define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
357
358/* zero110 is 0 mod p */
359static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
360
361/* felem_shrink converts an felem into a smallfelem. The result isn't quite
362 * minimal as the value may be greater than p.
363 *
364 * On entry:
365 * in[i] < 2^109
366 * On exit:
367 * out[i] < 2^64
368 */
369static void felem_shrink(smallfelem out, const felem in)
370 {
371 felem tmp;
372 u64 a, b, mask;
373 s64 high, low;
374 static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
375
376 /* Carry 2->3 */
377 tmp[3] = zero110[3] + in[3] + ((u64) (in[2] >> 64));
378 /* tmp[3] < 2^110 */
379
380 tmp[2] = zero110[2] + (u64) in[2];
381 tmp[0] = zero110[0] + in[0];
382 tmp[1] = zero110[1] + in[1];
383 /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */
384
385 /* We perform two partial reductions where we eliminate the
386 * high-word of tmp[3]. We don't update the other words till the end.
387 */
388 a = tmp[3] >> 64; /* a < 2^46 */
389 tmp[3] = (u64) tmp[3];
390 tmp[3] -= a;
391 tmp[3] += ((limb)a) << 32;
392 /* tmp[3] < 2^79 */
393
394 b = a;
395 a = tmp[3] >> 64; /* a < 2^15 */
396 b += a; /* b < 2^46 + 2^15 < 2^47 */
397 tmp[3] = (u64) tmp[3];
398 tmp[3] -= a;
399 tmp[3] += ((limb)a) << 32;
400 /* tmp[3] < 2^64 + 2^47 */
401
402 /* This adjusts the other two words to complete the two partial
403 * reductions. */
404 tmp[0] += b;
405 tmp[1] -= (((limb)b) << 32);
406
407 /* In order to make space in tmp[3] for the carry from 2 -> 3, we
408 * conditionally subtract kPrime if tmp[3] is large enough. */
409 high = tmp[3] >> 64;
410 /* As tmp[3] < 2^65, high is either 1 or 0 */
411 high <<= 63;
412 high >>= 63;
413 /* high is:
414 * all ones if the high word of tmp[3] is 1
415 * all zeros if the high word of tmp[3] if 0 */
416 low = tmp[3];
417 mask = low >> 63;
418 /* mask is:
419 * all ones if the MSB of low is 1
420 * all zeros if the MSB of low if 0 */
421 low &= bottom63bits;
422 low -= kPrime3Test;
423 /* if low was greater than kPrime3Test then the MSB is zero */
424 low = ~low;
425 low >>= 63;
426 /* low is:
427 * all ones if low was > kPrime3Test
428 * all zeros if low was <= kPrime3Test */
429 mask = (mask & low) | high;
430 tmp[0] -= mask & kPrime[0];
431 tmp[1] -= mask & kPrime[1];
432 /* kPrime[2] is zero, so omitted */
433 tmp[3] -= mask & kPrime[3];
434 /* tmp[3] < 2**64 - 2**32 + 1 */
435
436 tmp[1] += ((u64) (tmp[0] >> 64)); tmp[0] = (u64) tmp[0];
437 tmp[2] += ((u64) (tmp[1] >> 64)); tmp[1] = (u64) tmp[1];
438 tmp[3] += ((u64) (tmp[2] >> 64)); tmp[2] = (u64) tmp[2];
439 /* tmp[i] < 2^64 */
440
441 out[0] = tmp[0];
442 out[1] = tmp[1];
443 out[2] = tmp[2];
444 out[3] = tmp[3];
445 }
446
447/* smallfelem_expand converts a smallfelem to an felem */
448static void smallfelem_expand(felem out, const smallfelem in)
449 {
450 out[0] = in[0];
451 out[1] = in[1];
452 out[2] = in[2];
453 out[3] = in[3];
454 }
455
456/* smallfelem_square sets |out| = |small|^2
457 * On entry:
458 * small[i] < 2^64
459 * On exit:
460 * out[i] < 7 * 2^64 < 2^67
461 */
462static void smallfelem_square(longfelem out, const smallfelem small)
463 {
464 limb a;
465 u64 high, low;
466
467 a = ((uint128_t) small[0]) * small[0];
468 low = a;
469 high = a >> 64;
470 out[0] = low;
471 out[1] = high;
472
473 a = ((uint128_t) small[0]) * small[1];
474 low = a;
475 high = a >> 64;
476 out[1] += low;
477 out[1] += low;
478 out[2] = high;
479
480 a = ((uint128_t) small[0]) * small[2];
481 low = a;
482 high = a >> 64;
483 out[2] += low;
484 out[2] *= 2;
485 out[3] = high;
486
487 a = ((uint128_t) small[0]) * small[3];
488 low = a;
489 high = a >> 64;
490 out[3] += low;
491 out[4] = high;
492
493 a = ((uint128_t) small[1]) * small[2];
494 low = a;
495 high = a >> 64;
496 out[3] += low;
497 out[3] *= 2;
498 out[4] += high;
499
500 a = ((uint128_t) small[1]) * small[1];
501 low = a;
502 high = a >> 64;
503 out[2] += low;
504 out[3] += high;
505
506 a = ((uint128_t) small[1]) * small[3];
507 low = a;
508 high = a >> 64;
509 out[4] += low;
510 out[4] *= 2;
511 out[5] = high;
512
513 a = ((uint128_t) small[2]) * small[3];
514 low = a;
515 high = a >> 64;
516 out[5] += low;
517 out[5] *= 2;
518 out[6] = high;
519 out[6] += high;
520
521 a = ((uint128_t) small[2]) * small[2];
522 low = a;
523 high = a >> 64;
524 out[4] += low;
525 out[5] += high;
526
527 a = ((uint128_t) small[3]) * small[3];
528 low = a;
529 high = a >> 64;
530 out[6] += low;
531 out[7] = high;
532 }
533
534/* felem_square sets |out| = |in|^2
535 * On entry:
536 * in[i] < 2^109
537 * On exit:
538 * out[i] < 7 * 2^64 < 2^67
539 */
540static void felem_square(longfelem out, const felem in)
541 {
542 u64 small[4];
543 felem_shrink(small, in);
544 smallfelem_square(out, small);
545 }
546
547/* smallfelem_mul sets |out| = |small1| * |small2|
548 * On entry:
549 * small1[i] < 2^64
550 * small2[i] < 2^64
551 * On exit:
552 * out[i] < 7 * 2^64 < 2^67
553 */
554static void smallfelem_mul(longfelem out, const smallfelem small1, const smallfelem small2)
555 {
556 limb a;
557 u64 high, low;
558
559 a = ((uint128_t) small1[0]) * small2[0];
560 low = a;
561 high = a >> 64;
562 out[0] = low;
563 out[1] = high;
564
565
566 a = ((uint128_t) small1[0]) * small2[1];
567 low = a;
568 high = a >> 64;
569 out[1] += low;
570 out[2] = high;
571
572 a = ((uint128_t) small1[1]) * small2[0];
573 low = a;
574 high = a >> 64;
575 out[1] += low;
576 out[2] += high;
577
578
579 a = ((uint128_t) small1[0]) * small2[2];
580 low = a;
581 high = a >> 64;
582 out[2] += low;
583 out[3] = high;
584
585 a = ((uint128_t) small1[1]) * small2[1];
586 low = a;
587 high = a >> 64;
588 out[2] += low;
589 out[3] += high;
590
591 a = ((uint128_t) small1[2]) * small2[0];
592 low = a;
593 high = a >> 64;
594 out[2] += low;
595 out[3] += high;
596
597
598 a = ((uint128_t) small1[0]) * small2[3];
599 low = a;
600 high = a >> 64;
601 out[3] += low;
602 out[4] = high;
603
604 a = ((uint128_t) small1[1]) * small2[2];
605 low = a;
606 high = a >> 64;
607 out[3] += low;
608 out[4] += high;
609
610 a = ((uint128_t) small1[2]) * small2[1];
611 low = a;
612 high = a >> 64;
613 out[3] += low;
614 out[4] += high;
615
616 a = ((uint128_t) small1[3]) * small2[0];
617 low = a;
618 high = a >> 64;
619 out[3] += low;
620 out[4] += high;
621
622
623 a = ((uint128_t) small1[1]) * small2[3];
624 low = a;
625 high = a >> 64;
626 out[4] += low;
627 out[5] = high;
628
629 a = ((uint128_t) small1[2]) * small2[2];
630 low = a;
631 high = a >> 64;
632 out[4] += low;
633 out[5] += high;
634
635 a = ((uint128_t) small1[3]) * small2[1];
636 low = a;
637 high = a >> 64;
638 out[4] += low;
639 out[5] += high;
640
641
642 a = ((uint128_t) small1[2]) * small2[3];
643 low = a;
644 high = a >> 64;
645 out[5] += low;
646 out[6] = high;
647
648 a = ((uint128_t) small1[3]) * small2[2];
649 low = a;
650 high = a >> 64;
651 out[5] += low;
652 out[6] += high;
653
654
655 a = ((uint128_t) small1[3]) * small2[3];
656 low = a;
657 high = a >> 64;
658 out[6] += low;
659 out[7] = high;
660 }
661
662/* felem_mul sets |out| = |in1| * |in2|
663 * On entry:
664 * in1[i] < 2^109
665 * in2[i] < 2^109
666 * On exit:
667 * out[i] < 7 * 2^64 < 2^67
668 */
669static void felem_mul(longfelem out, const felem in1, const felem in2)
670 {
671 smallfelem small1, small2;
672 felem_shrink(small1, in1);
673 felem_shrink(small2, in2);
674 smallfelem_mul(out, small1, small2);
675 }
676
677/* felem_small_mul sets |out| = |small1| * |in2|
678 * On entry:
679 * small1[i] < 2^64
680 * in2[i] < 2^109
681 * On exit:
682 * out[i] < 7 * 2^64 < 2^67
683 */
684static void felem_small_mul(longfelem out, const smallfelem small1, const felem in2)
685 {
686 smallfelem small2;
687 felem_shrink(small2, in2);
688 smallfelem_mul(out, small1, small2);
689 }
690
691#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
692#define two100 (((limb)1) << 100)
693#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
694/* zero100 is 0 mod p */
695static const felem zero100 = { two100m36m4, two100, two100m36p4, two100m36p4 };
696
697/* Internal function for the different flavours of felem_reduce.
698 * felem_reduce_ reduces the higher coefficients in[4]-in[7].
699 * On entry:
700 * out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7]
701 * out[1] >= in[7] + 2^32*in[4]
702 * out[2] >= in[5] + 2^32*in[5]
703 * out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
704 * On exit:
705 * out[0] <= out[0] + in[4] + 2^32*in[5]
706 * out[1] <= out[1] + in[5] + 2^33*in[6]
707 * out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
708 * out[3] <= out[3] + 2^32*in[4] + 3*in[7]
709 */
710static void felem_reduce_(felem out, const longfelem in)
711 {
712 int128_t c;
713 /* combine common terms from below */
714 c = in[4] + (in[5] << 32);
715 out[0] += c;
716 out[3] -= c;
717
718 c = in[5] - in[7];
719 out[1] += c;
720 out[2] -= c;
721
722 /* the remaining terms */
723 /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */
724 out[1] -= (in[4] << 32);
725 out[3] += (in[4] << 32);
726
727 /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */
728 out[2] -= (in[5] << 32);
729
730 /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */
731 out[0] -= in[6];
732 out[0] -= (in[6] << 32);
733 out[1] += (in[6] << 33);
734 out[2] += (in[6] * 2);
735 out[3] -= (in[6] << 32);
736
737 /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */
738 out[0] -= in[7];
739 out[0] -= (in[7] << 32);
740 out[2] += (in[7] << 33);
741 out[3] += (in[7] * 3);
742 }
743
744/* felem_reduce converts a longfelem into an felem.
745 * To be called directly after felem_square or felem_mul.
746 * On entry:
747 * in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
748 * in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
749 * On exit:
750 * out[i] < 2^101
751 */
752static void felem_reduce(felem out, const longfelem in)
753 {
754 out[0] = zero100[0] + in[0];
755 out[1] = zero100[1] + in[1];
756 out[2] = zero100[2] + in[2];
757 out[3] = zero100[3] + in[3];
758
759 felem_reduce_(out, in);
760
761 /* out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
762 * out[1] > 2^100 - 2^64 - 7*2^96 > 0
763 * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0
764 * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0
765 *
766 * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101
767 * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101
768 * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101
769 * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101
770 */
771 }
772
773/* felem_reduce_zero105 converts a larger longfelem into an felem.
774 * On entry:
775 * in[0] < 2^71
776 * On exit:
777 * out[i] < 2^106
778 */
779static void felem_reduce_zero105(felem out, const longfelem in)
780 {
781 out[0] = zero105[0] + in[0];
782 out[1] = zero105[1] + in[1];
783 out[2] = zero105[2] + in[2];
784 out[3] = zero105[3] + in[3];
785
786 felem_reduce_(out, in);
787
788 /* out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
789 * out[1] > 2^105 - 2^71 - 2^103 > 0
790 * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0
791 * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0
792 *
793 * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
794 * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
795 * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106
796 * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
797 */
798 }
799
800/* subtract_u64 sets *result = *result - v and *carry to one if the subtraction
801 * underflowed. */
802static void subtract_u64(u64* result, u64* carry, u64 v)
803 {
804 uint128_t r = *result;
805 r -= v;
806 *carry = (r >> 64) & 1;
807 *result = (u64) r;
808 }
809
810/* felem_contract converts |in| to its unique, minimal representation.
811 * On entry:
812 * in[i] < 2^109
813 */
814static void felem_contract(smallfelem out, const felem in)
815 {
816 unsigned i;
817 u64 all_equal_so_far = 0, result = 0, carry;
818
819 felem_shrink(out, in);
820 /* small is minimal except that the value might be > p */
821
822 all_equal_so_far--;
823 /* We are doing a constant time test if out >= kPrime. We need to
824 * compare each u64, from most-significant to least significant. For
825 * each one, if all words so far have been equal (m is all ones) then a
826 * non-equal result is the answer. Otherwise we continue. */
827 for (i = 3; i < 4; i--)
828 {
829 u64 equal;
830 uint128_t a = ((uint128_t) kPrime[i]) - out[i];
831 /* if out[i] > kPrime[i] then a will underflow and the high
832 * 64-bits will all be set. */
833 result |= all_equal_so_far & ((u64) (a >> 64));
834
835 /* if kPrime[i] == out[i] then |equal| will be all zeros and
836 * the decrement will make it all ones. */
837 equal = kPrime[i] ^ out[i];
838 equal--;
839 equal &= equal << 32;
840 equal &= equal << 16;
841 equal &= equal << 8;
842 equal &= equal << 4;
843 equal &= equal << 2;
844 equal &= equal << 1;
845 equal = ((s64) equal) >> 63;
846
847 all_equal_so_far &= equal;
848 }
849
850 /* if all_equal_so_far is still all ones then the two values are equal
851 * and so out >= kPrime is true. */
852 result |= all_equal_so_far;
853
854 /* if out >= kPrime then we subtract kPrime. */
855 subtract_u64(&out[0], &carry, result & kPrime[0]);
856 subtract_u64(&out[1], &carry, carry);
857 subtract_u64(&out[2], &carry, carry);
858 subtract_u64(&out[3], &carry, carry);
859
860 subtract_u64(&out[1], &carry, result & kPrime[1]);
861 subtract_u64(&out[2], &carry, carry);
862 subtract_u64(&out[3], &carry, carry);
863
864 subtract_u64(&out[2], &carry, result & kPrime[2]);
865 subtract_u64(&out[3], &carry, carry);
866
867 subtract_u64(&out[3], &carry, result & kPrime[3]);
868 }
869
870static void smallfelem_square_contract(smallfelem out, const smallfelem in)
871 {
872 longfelem longtmp;
873 felem tmp;
874
875 smallfelem_square(longtmp, in);
876 felem_reduce(tmp, longtmp);
877 felem_contract(out, tmp);
878 }
879
880static void smallfelem_mul_contract(smallfelem out, const smallfelem in1, const smallfelem in2)
881 {
882 longfelem longtmp;
883 felem tmp;
884
885 smallfelem_mul(longtmp, in1, in2);
886 felem_reduce(tmp, longtmp);
887 felem_contract(out, tmp);
888 }
889
890/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
891 * otherwise.
892 * On entry:
893 * small[i] < 2^64
894 */
895static limb smallfelem_is_zero(const smallfelem small)
896 {
897 limb result;
898 u64 is_p;
899
900 u64 is_zero = small[0] | small[1] | small[2] | small[3];
901 is_zero--;
902 is_zero &= is_zero << 32;
903 is_zero &= is_zero << 16;
904 is_zero &= is_zero << 8;
905 is_zero &= is_zero << 4;
906 is_zero &= is_zero << 2;
907 is_zero &= is_zero << 1;
908 is_zero = ((s64) is_zero) >> 63;
909
910 is_p = (small[0] ^ kPrime[0]) |
911 (small[1] ^ kPrime[1]) |
912 (small[2] ^ kPrime[2]) |
913 (small[3] ^ kPrime[3]);
914 is_p--;
915 is_p &= is_p << 32;
916 is_p &= is_p << 16;
917 is_p &= is_p << 8;
918 is_p &= is_p << 4;
919 is_p &= is_p << 2;
920 is_p &= is_p << 1;
921 is_p = ((s64) is_p) >> 63;
922
923 is_zero |= is_p;
924
925 result = is_zero;
926 result |= ((limb) is_zero) << 64;
927 return result;
928 }
929
930static int smallfelem_is_zero_int(const smallfelem small)
931 {
932 return (int) (smallfelem_is_zero(small) & ((limb)1));
933 }
934
935/* felem_inv calculates |out| = |in|^{-1}
936 *
937 * Based on Fermat's Little Theorem:
938 * a^p = a (mod p)
939 * a^{p-1} = 1 (mod p)
940 * a^{p-2} = a^{-1} (mod p)
941 */
942static void felem_inv(felem out, const felem in)
943 {
944 felem ftmp, ftmp2;
945 /* each e_I will hold |in|^{2^I - 1} */
946 felem e2, e4, e8, e16, e32, e64;
947 longfelem tmp;
948 unsigned i;
949
950 felem_square(tmp, in); felem_reduce(ftmp, tmp); /* 2^1 */
951 felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */
952 felem_assign(e2, ftmp);
953 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */
954 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^4 - 2^2 */
955 felem_mul(tmp, ftmp, e2); felem_reduce(ftmp, tmp); /* 2^4 - 2^0 */
956 felem_assign(e4, ftmp);
957 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^5 - 2^1 */
958 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^6 - 2^2 */
959 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^7 - 2^3 */
960 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^8 - 2^4 */
961 felem_mul(tmp, ftmp, e4); felem_reduce(ftmp, tmp); /* 2^8 - 2^0 */
962 felem_assign(e8, ftmp);
963 for (i = 0; i < 8; i++) {
964 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
965 } /* 2^16 - 2^8 */
966 felem_mul(tmp, ftmp, e8); felem_reduce(ftmp, tmp); /* 2^16 - 2^0 */
967 felem_assign(e16, ftmp);
968 for (i = 0; i < 16; i++) {
969 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
970 } /* 2^32 - 2^16 */
971 felem_mul(tmp, ftmp, e16); felem_reduce(ftmp, tmp); /* 2^32 - 2^0 */
972 felem_assign(e32, ftmp);
973 for (i = 0; i < 32; i++) {
974 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
975 } /* 2^64 - 2^32 */
976 felem_assign(e64, ftmp);
977 felem_mul(tmp, ftmp, in); felem_reduce(ftmp, tmp); /* 2^64 - 2^32 + 2^0 */
978 for (i = 0; i < 192; i++) {
979 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp);
980 } /* 2^256 - 2^224 + 2^192 */
981
982 felem_mul(tmp, e64, e32); felem_reduce(ftmp2, tmp); /* 2^64 - 2^0 */
983 for (i = 0; i < 16; i++) {
984 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
985 } /* 2^80 - 2^16 */
986 felem_mul(tmp, ftmp2, e16); felem_reduce(ftmp2, tmp); /* 2^80 - 2^0 */
987 for (i = 0; i < 8; i++) {
988 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
989 } /* 2^88 - 2^8 */
990 felem_mul(tmp, ftmp2, e8); felem_reduce(ftmp2, tmp); /* 2^88 - 2^0 */
991 for (i = 0; i < 4; i++) {
992 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp);
993 } /* 2^92 - 2^4 */
994 felem_mul(tmp, ftmp2, e4); felem_reduce(ftmp2, tmp); /* 2^92 - 2^0 */
995 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^93 - 2^1 */
996 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^94 - 2^2 */
997 felem_mul(tmp, ftmp2, e2); felem_reduce(ftmp2, tmp); /* 2^94 - 2^0 */
998 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^95 - 2^1 */
999 felem_square(tmp, ftmp2); felem_reduce(ftmp2, tmp); /* 2^96 - 2^2 */
1000 felem_mul(tmp, ftmp2, in); felem_reduce(ftmp2, tmp); /* 2^96 - 3 */
1001
1002 felem_mul(tmp, ftmp2, ftmp); felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
1003 }
1004
1005static void smallfelem_inv_contract(smallfelem out, const smallfelem in)
1006 {
1007 felem tmp;
1008
1009 smallfelem_expand(tmp, in);
1010 felem_inv(tmp, tmp);
1011 felem_contract(out, tmp);
1012 }
1013
1014/* Group operations
1015 * ----------------
1016 *
1017 * Building on top of the field operations we have the operations on the
1018 * elliptic curve group itself. Points on the curve are represented in Jacobian
1019 * coordinates */
1020
1021/* point_double calculates 2*(x_in, y_in, z_in)
1022 *
1023 * The method is taken from:
1024 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
1025 *
1026 * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
1027 * while x_out == y_in is not (maybe this works, but it's not tested). */
1028static void
1029point_double(felem x_out, felem y_out, felem z_out,
1030 const felem x_in, const felem y_in, const felem z_in)
1031 {
1032 longfelem tmp, tmp2;
1033 felem delta, gamma, beta, alpha, ftmp, ftmp2;
1034 smallfelem small1, small2;
1035
1036 felem_assign(ftmp, x_in);
1037 /* ftmp[i] < 2^106 */
1038 felem_assign(ftmp2, x_in);
1039 /* ftmp2[i] < 2^106 */
1040
1041 /* delta = z^2 */
1042 felem_square(tmp, z_in);
1043 felem_reduce(delta, tmp);
1044 /* delta[i] < 2^101 */
1045
1046 /* gamma = y^2 */
1047 felem_square(tmp, y_in);
1048 felem_reduce(gamma, tmp);
1049 /* gamma[i] < 2^101 */
1050 felem_shrink(small1, gamma);
1051
1052 /* beta = x*gamma */
1053 felem_small_mul(tmp, small1, x_in);
1054 felem_reduce(beta, tmp);
1055 /* beta[i] < 2^101 */
1056
1057 /* alpha = 3*(x-delta)*(x+delta) */
1058 felem_diff(ftmp, delta);
1059 /* ftmp[i] < 2^105 + 2^106 < 2^107 */
1060 felem_sum(ftmp2, delta);
1061 /* ftmp2[i] < 2^105 + 2^106 < 2^107 */
1062 felem_scalar(ftmp2, 3);
1063 /* ftmp2[i] < 3 * 2^107 < 2^109 */
1064 felem_mul(tmp, ftmp, ftmp2);
1065 felem_reduce(alpha, tmp);
1066 /* alpha[i] < 2^101 */
1067 felem_shrink(small2, alpha);
1068
1069 /* x' = alpha^2 - 8*beta */
1070 smallfelem_square(tmp, small2);
1071 felem_reduce(x_out, tmp);
1072 felem_assign(ftmp, beta);
1073 felem_scalar(ftmp, 8);
1074 /* ftmp[i] < 8 * 2^101 = 2^104 */
1075 felem_diff(x_out, ftmp);
1076 /* x_out[i] < 2^105 + 2^101 < 2^106 */
1077
1078 /* z' = (y + z)^2 - gamma - delta */
1079 felem_sum(delta, gamma);
1080 /* delta[i] < 2^101 + 2^101 = 2^102 */
1081 felem_assign(ftmp, y_in);
1082 felem_sum(ftmp, z_in);
1083 /* ftmp[i] < 2^106 + 2^106 = 2^107 */
1084 felem_square(tmp, ftmp);
1085 felem_reduce(z_out, tmp);
1086 felem_diff(z_out, delta);
1087 /* z_out[i] < 2^105 + 2^101 < 2^106 */
1088
1089 /* y' = alpha*(4*beta - x') - 8*gamma^2 */
1090 felem_scalar(beta, 4);
1091 /* beta[i] < 4 * 2^101 = 2^103 */
1092 felem_diff_zero107(beta, x_out);
1093 /* beta[i] < 2^107 + 2^103 < 2^108 */
1094 felem_small_mul(tmp, small2, beta);
1095 /* tmp[i] < 7 * 2^64 < 2^67 */
1096 smallfelem_square(tmp2, small1);
1097 /* tmp2[i] < 7 * 2^64 */
1098 longfelem_scalar(tmp2, 8);
1099 /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */
1100 longfelem_diff(tmp, tmp2);
1101 /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
1102 felem_reduce_zero105(y_out, tmp);
1103 /* y_out[i] < 2^106 */
1104 }
1105
1106/* point_double_small is the same as point_double, except that it operates on
1107 * smallfelems */
1108static void
1109point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out,
1110 const smallfelem x_in, const smallfelem y_in, const smallfelem z_in)
1111 {
1112 felem felem_x_out, felem_y_out, felem_z_out;
1113 felem felem_x_in, felem_y_in, felem_z_in;
1114
1115 smallfelem_expand(felem_x_in, x_in);
1116 smallfelem_expand(felem_y_in, y_in);
1117 smallfelem_expand(felem_z_in, z_in);
1118 point_double(felem_x_out, felem_y_out, felem_z_out,
1119 felem_x_in, felem_y_in, felem_z_in);
1120 felem_shrink(x_out, felem_x_out);
1121 felem_shrink(y_out, felem_y_out);
1122 felem_shrink(z_out, felem_z_out);
1123 }
1124
1125/* copy_conditional copies in to out iff mask is all ones. */
1126static void
1127copy_conditional(felem out, const felem in, limb mask)
1128 {
1129 unsigned i;
1130 for (i = 0; i < NLIMBS; ++i)
1131 {
1132 const limb tmp = mask & (in[i] ^ out[i]);
1133 out[i] ^= tmp;
1134 }
1135 }
1136
1137/* copy_small_conditional copies in to out iff mask is all ones. */
1138static void
1139copy_small_conditional(felem out, const smallfelem in, limb mask)
1140 {
1141 unsigned i;
1142 const u64 mask64 = mask;
1143 for (i = 0; i < NLIMBS; ++i)
1144 {
1145 out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask);
1146 }
1147 }
1148
1149/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
1150 *
1151 * The method is taken from:
1152 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
1153 * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
1154 *
1155 * This function includes a branch for checking whether the two input points
1156 * are equal, (while not equal to the point at infinity). This case never
1157 * happens during single point multiplication, so there is no timing leak for
1158 * ECDH or ECDSA signing. */
1159static void point_add(felem x3, felem y3, felem z3,
1160 const felem x1, const felem y1, const felem z1,
1161 const int mixed, const smallfelem x2, const smallfelem y2, const smallfelem z2)
1162 {
1163 felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
1164 longfelem tmp, tmp2;
1165 smallfelem small1, small2, small3, small4, small5;
1166 limb x_equal, y_equal, z1_is_zero, z2_is_zero;
1167
1168 felem_shrink(small3, z1);
1169
1170 z1_is_zero = smallfelem_is_zero(small3);
1171 z2_is_zero = smallfelem_is_zero(z2);
1172
1173 /* ftmp = z1z1 = z1**2 */
1174 smallfelem_square(tmp, small3);
1175 felem_reduce(ftmp, tmp);
1176 /* ftmp[i] < 2^101 */
1177 felem_shrink(small1, ftmp);
1178
1179 if(!mixed)
1180 {
1181 /* ftmp2 = z2z2 = z2**2 */
1182 smallfelem_square(tmp, z2);
1183 felem_reduce(ftmp2, tmp);
1184 /* ftmp2[i] < 2^101 */
1185 felem_shrink(small2, ftmp2);
1186
1187 felem_shrink(small5, x1);
1188
1189 /* u1 = ftmp3 = x1*z2z2 */
1190 smallfelem_mul(tmp, small5, small2);
1191 felem_reduce(ftmp3, tmp);
1192 /* ftmp3[i] < 2^101 */
1193
1194 /* ftmp5 = z1 + z2 */
1195 felem_assign(ftmp5, z1);
1196 felem_small_sum(ftmp5, z2);
1197 /* ftmp5[i] < 2^107 */
1198
1199 /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */
1200 felem_square(tmp, ftmp5);
1201 felem_reduce(ftmp5, tmp);
1202 /* ftmp2 = z2z2 + z1z1 */
1203 felem_sum(ftmp2, ftmp);
1204 /* ftmp2[i] < 2^101 + 2^101 = 2^102 */
1205 felem_diff(ftmp5, ftmp2);
1206 /* ftmp5[i] < 2^105 + 2^101 < 2^106 */
1207
1208 /* ftmp2 = z2 * z2z2 */
1209 smallfelem_mul(tmp, small2, z2);
1210 felem_reduce(ftmp2, tmp);
1211
1212 /* s1 = ftmp2 = y1 * z2**3 */
1213 felem_mul(tmp, y1, ftmp2);
1214 felem_reduce(ftmp6, tmp);
1215 /* ftmp6[i] < 2^101 */
1216 }
1217 else
1218 {
1219 /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
1220
1221 /* u1 = ftmp3 = x1*z2z2 */
1222 felem_assign(ftmp3, x1);
1223 /* ftmp3[i] < 2^106 */
1224
1225 /* ftmp5 = 2z1z2 */
1226 felem_assign(ftmp5, z1);
1227 felem_scalar(ftmp5, 2);
1228 /* ftmp5[i] < 2*2^106 = 2^107 */
1229
1230 /* s1 = ftmp2 = y1 * z2**3 */
1231 felem_assign(ftmp6, y1);
1232 /* ftmp6[i] < 2^106 */
1233 }
1234
1235 /* u2 = x2*z1z1 */
1236 smallfelem_mul(tmp, x2, small1);
1237 felem_reduce(ftmp4, tmp);
1238
1239 /* h = ftmp4 = u2 - u1 */
1240 felem_diff_zero107(ftmp4, ftmp3);
1241 /* ftmp4[i] < 2^107 + 2^101 < 2^108 */
1242 felem_shrink(small4, ftmp4);
1243
1244 x_equal = smallfelem_is_zero(small4);
1245
1246 /* z_out = ftmp5 * h */
1247 felem_small_mul(tmp, small4, ftmp5);
1248 felem_reduce(z_out, tmp);
1249 /* z_out[i] < 2^101 */
1250
1251 /* ftmp = z1 * z1z1 */
1252 smallfelem_mul(tmp, small1, small3);
1253 felem_reduce(ftmp, tmp);
1254
1255 /* s2 = tmp = y2 * z1**3 */
1256 felem_small_mul(tmp, y2, ftmp);
1257 felem_reduce(ftmp5, tmp);
1258
1259 /* r = ftmp5 = (s2 - s1)*2 */
1260 felem_diff_zero107(ftmp5, ftmp6);
1261 /* ftmp5[i] < 2^107 + 2^107 = 2^108*/
1262 felem_scalar(ftmp5, 2);
1263 /* ftmp5[i] < 2^109 */
1264 felem_shrink(small1, ftmp5);
1265 y_equal = smallfelem_is_zero(small1);
1266
1267 if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
1268 {
1269 point_double(x3, y3, z3, x1, y1, z1);
1270 return;
1271 }
1272
1273 /* I = ftmp = (2h)**2 */
1274 felem_assign(ftmp, ftmp4);
1275 felem_scalar(ftmp, 2);
1276 /* ftmp[i] < 2*2^108 = 2^109 */
1277 felem_square(tmp, ftmp);
1278 felem_reduce(ftmp, tmp);
1279
1280 /* J = ftmp2 = h * I */
1281 felem_mul(tmp, ftmp4, ftmp);
1282 felem_reduce(ftmp2, tmp);
1283
1284 /* V = ftmp4 = U1 * I */
1285 felem_mul(tmp, ftmp3, ftmp);
1286 felem_reduce(ftmp4, tmp);
1287
1288 /* x_out = r**2 - J - 2V */
1289 smallfelem_square(tmp, small1);
1290 felem_reduce(x_out, tmp);
1291 felem_assign(ftmp3, ftmp4);
1292 felem_scalar(ftmp4, 2);
1293 felem_sum(ftmp4, ftmp2);
1294 /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */
1295 felem_diff(x_out, ftmp4);
1296 /* x_out[i] < 2^105 + 2^101 */
1297
1298 /* y_out = r(V-x_out) - 2 * s1 * J */
1299 felem_diff_zero107(ftmp3, x_out);
1300 /* ftmp3[i] < 2^107 + 2^101 < 2^108 */
1301 felem_small_mul(tmp, small1, ftmp3);
1302 felem_mul(tmp2, ftmp6, ftmp2);
1303 longfelem_scalar(tmp2, 2);
1304 /* tmp2[i] < 2*2^67 = 2^68 */
1305 longfelem_diff(tmp, tmp2);
1306 /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
1307 felem_reduce_zero105(y_out, tmp);
1308 /* y_out[i] < 2^106 */
1309
1310 copy_small_conditional(x_out, x2, z1_is_zero);
1311 copy_conditional(x_out, x1, z2_is_zero);
1312 copy_small_conditional(y_out, y2, z1_is_zero);
1313 copy_conditional(y_out, y1, z2_is_zero);
1314 copy_small_conditional(z_out, z2, z1_is_zero);
1315 copy_conditional(z_out, z1, z2_is_zero);
1316 felem_assign(x3, x_out);
1317 felem_assign(y3, y_out);
1318 felem_assign(z3, z_out);
1319 }
1320
1321/* point_add_small is the same as point_add, except that it operates on
1322 * smallfelems */
1323static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
1324 smallfelem x1, smallfelem y1, smallfelem z1,
1325 smallfelem x2, smallfelem y2, smallfelem z2)
1326 {
1327 felem felem_x3, felem_y3, felem_z3;
1328 felem felem_x1, felem_y1, felem_z1;
1329 smallfelem_expand(felem_x1, x1);
1330 smallfelem_expand(felem_y1, y1);
1331 smallfelem_expand(felem_z1, z1);
1332 point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, x2, y2, z2);
1333 felem_shrink(x3, felem_x3);
1334 felem_shrink(y3, felem_y3);
1335 felem_shrink(z3, felem_z3);
1336 }
1337
1338/* Base point pre computation
1339 * --------------------------
1340 *
1341 * Two different sorts of precomputed tables are used in the following code.
1342 * Each contain various points on the curve, where each point is three field
1343 * elements (x, y, z).
1344 *
1345 * For the base point table, z is usually 1 (0 for the point at infinity).
1346 * This table has 2 * 16 elements, starting with the following:
1347 * index | bits | point
1348 * ------+---------+------------------------------
1349 * 0 | 0 0 0 0 | 0G
1350 * 1 | 0 0 0 1 | 1G
1351 * 2 | 0 0 1 0 | 2^64G
1352 * 3 | 0 0 1 1 | (2^64 + 1)G
1353 * 4 | 0 1 0 0 | 2^128G
1354 * 5 | 0 1 0 1 | (2^128 + 1)G
1355 * 6 | 0 1 1 0 | (2^128 + 2^64)G
1356 * 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
1357 * 8 | 1 0 0 0 | 2^192G
1358 * 9 | 1 0 0 1 | (2^192 + 1)G
1359 * 10 | 1 0 1 0 | (2^192 + 2^64)G
1360 * 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
1361 * 12 | 1 1 0 0 | (2^192 + 2^128)G
1362 * 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
1363 * 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
1364 * 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
1365 * followed by a copy of this with each element multiplied by 2^32.
1366 *
1367 * The reason for this is so that we can clock bits into four different
1368 * locations when doing simple scalar multiplies against the base point,
1369 * and then another four locations using the second 16 elements.
1370 *
1371 * Tables for other points have table[i] = iG for i in 0 .. 16. */
1372
1373/* gmul is the table of precomputed base points */
1374static const smallfelem gmul[2][16][3] =
1375{{{{0, 0, 0, 0},
1376 {0, 0, 0, 0},
1377 {0, 0, 0, 0}},
1378 {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, 0x6b17d1f2e12c4247},
1379 {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, 0x4fe342e2fe1a7f9b},
1380 {1, 0, 0, 0}},
1381 {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, 0x0fa822bc2811aaa5},
1382 {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, 0xbff44ae8f5dba80d},
1383 {1, 0, 0, 0}},
1384 {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, 0x300a4bbc89d6726f},
1385 {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, 0x72aac7e0d09b4644},
1386 {1, 0, 0, 0}},
1387 {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, 0x447d739beedb5e67},
1388 {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, 0x2d4825ab834131ee},
1389 {1, 0, 0, 0}},
1390 {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, 0xef9519328a9c72ff},
1391 {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, 0x611e9fc37dbb2c9b},
1392 {1, 0, 0, 0}},
1393 {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, 0x550663797b51f5d8},
1394 {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, 0x157164848aecb851},
1395 {1, 0, 0, 0}},
1396 {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, 0xeb5d7745b21141ea},
1397 {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, 0xeafd72ebdbecc17b},
1398 {1, 0, 0, 0}},
1399 {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, 0xa6d39677a7849276},
1400 {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, 0x674f84749b0b8816},
1401 {1, 0, 0, 0}},
1402 {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, 0x4e769e7672c9ddad},
1403 {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, 0x42b99082de830663},
1404 {1, 0, 0, 0}},
1405 {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, 0x78878ef61c6ce04d},
1406 {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, 0xb6cb3f5d7b72c321},
1407 {1, 0, 0, 0}},
1408 {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, 0x0c88bc4d716b1287},
1409 {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, 0xdd5ddea3f3901dc6},
1410 {1, 0, 0, 0}},
1411 {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, 0x68f344af6b317466},
1412 {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, 0x31b9c405f8540a20},
1413 {1, 0, 0, 0}},
1414 {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, 0x4052bf4b6f461db9},
1415 {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, 0xfecf4d5190b0fc61},
1416 {1, 0, 0, 0}},
1417 {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, 0x1eddbae2c802e41a},
1418 {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, 0x43104d86560ebcfc},
1419 {1, 0, 0, 0}},
1420 {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, 0xb48e26b484f7a21c},
1421 {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, 0xfac015404d4d3dab},
1422 {1, 0, 0, 0}}},
1423 {{{0, 0, 0, 0},
1424 {0, 0, 0, 0},
1425 {0, 0, 0, 0}},
1426 {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, 0x7fe36b40af22af89},
1427 {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, 0xe697d45825b63624},
1428 {1, 0, 0, 0}},
1429 {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, 0x4a5b506612a677a6},
1430 {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, 0xeb13461ceac089f1},
1431 {1, 0, 0, 0}},
1432 {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, 0x0781b8291c6a220a},
1433 {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, 0x690cde8df0151593},
1434 {1, 0, 0, 0}},
1435 {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, 0x8a535f566ec73617},
1436 {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, 0x0455c08468b08bd7},
1437 {1, 0, 0, 0}},
1438 {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, 0x06bada7ab77f8276},
1439 {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, 0x5b476dfd0e6cb18a},
1440 {1, 0, 0, 0}},
1441 {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, 0x3e29864e8a2ec908},
1442 {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, 0x239b90ea3dc31e7e},
1443 {1, 0, 0, 0}},
1444 {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, 0x820f4dd949f72ff7},
1445 {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, 0x140406ec783a05ec},
1446 {1, 0, 0, 0}},
1447 {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, 0x68f6b8542783dfee},
1448 {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, 0xcbe1feba92e40ce6},
1449 {1, 0, 0, 0}},
1450 {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, 0xd0b2f94d2f420109},
1451 {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, 0x971459828b0719e5},
1452 {1, 0, 0, 0}},
1453 {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, 0x961610004a866aba},
1454 {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, 0x7acb9fadcee75e44},
1455 {1, 0, 0, 0}},
1456 {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, 0x24eb9acca333bf5b},
1457 {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, 0x69f891c5acd079cc},
1458 {1, 0, 0, 0}},
1459 {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, 0xe51f547c5972a107},
1460 {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, 0x1c309a2b25bb1387},
1461 {1, 0, 0, 0}},
1462 {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, 0x20b87b8aa2c4e503},
1463 {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, 0xf5c6fa49919776be},
1464 {1, 0, 0, 0}},
1465 {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, 0x1ed7d1b9332010b9},
1466 {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, 0x3a2b03f03217257a},
1467 {1, 0, 0, 0}},
1468 {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, 0x15fee545c78dd9f6},
1469 {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, 0x4ab5b6b2b8753f81},
1470 {1, 0, 0, 0}}}};
1471
1472/* select_point selects the |idx|th point from a precomputation table and
1473 * copies it to out. */
1474static void select_point(const u64 idx, unsigned int size, const smallfelem pre_comp[16][3], smallfelem out[3])
1475 {
1476 unsigned i, j;
1477 u64 *outlimbs = &out[0][0];
1478 memset(outlimbs, 0, 3 * sizeof(smallfelem));
1479
1480 for (i = 0; i < size; i++)
1481 {
1482 const u64 *inlimbs = (u64*) &pre_comp[i][0][0];
1483 u64 mask = i ^ idx;
1484 mask |= mask >> 4;
1485 mask |= mask >> 2;
1486 mask |= mask >> 1;
1487 mask &= 1;
1488 mask--;
1489 for (j = 0; j < NLIMBS * 3; j++)
1490 outlimbs[j] |= inlimbs[j] & mask;
1491 }
1492 }
1493
1494/* get_bit returns the |i|th bit in |in| */
1495static char get_bit(const felem_bytearray in, int i)
1496 {
1497 if ((i < 0) || (i >= 256))
1498 return 0;
1499 return (in[i >> 3] >> (i & 7)) & 1;
1500 }
1501
1502/* Interleaved point multiplication using precomputed point multiples:
1503 * The small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[],
1504 * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
1505 * of the generator, using certain (large) precomputed multiples in g_pre_comp.
1506 * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
1507static void batch_mul(felem x_out, felem y_out, felem z_out,
1508 const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
1509 const int mixed, const smallfelem pre_comp[][17][3], const smallfelem g_pre_comp[2][16][3])
1510 {
1511 int i, skip;
1512 unsigned num, gen_mul = (g_scalar != NULL);
1513 felem nq[3], ftmp;
1514 smallfelem tmp[3];
1515 u64 bits;
1516 u8 sign, digit;
1517
1518 /* set nq to the point at infinity */
1519 memset(nq, 0, 3 * sizeof(felem));
1520
1521 /* Loop over all scalars msb-to-lsb, interleaving additions
1522 * of multiples of the generator (two in each of the last 32 rounds)
1523 * and additions of other points multiples (every 5th round).
1524 */
1525 skip = 1; /* save two point operations in the first round */
1526 for (i = (num_points ? 255 : 31); i >= 0; --i)
1527 {
1528 /* double */
1529 if (!skip)
1530 point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1531
1532 /* add multiples of the generator */
1533 if (gen_mul && (i <= 31))
1534 {
1535 /* first, look 32 bits upwards */
1536 bits = get_bit(g_scalar, i + 224) << 3;
1537 bits |= get_bit(g_scalar, i + 160) << 2;
1538 bits |= get_bit(g_scalar, i + 96) << 1;
1539 bits |= get_bit(g_scalar, i + 32);
1540 /* select the point to add, in constant time */
1541 select_point(bits, 16, g_pre_comp[1], tmp);
1542
1543 if (!skip)
1544 {
1545 point_add(nq[0], nq[1], nq[2],
1546 nq[0], nq[1], nq[2],
1547 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
1548 }
1549 else
1550 {
1551 smallfelem_expand(nq[0], tmp[0]);
1552 smallfelem_expand(nq[1], tmp[1]);
1553 smallfelem_expand(nq[2], tmp[2]);
1554 skip = 0;
1555 }
1556
1557 /* second, look at the current position */
1558 bits = get_bit(g_scalar, i + 192) << 3;
1559 bits |= get_bit(g_scalar, i + 128) << 2;
1560 bits |= get_bit(g_scalar, i + 64) << 1;
1561 bits |= get_bit(g_scalar, i);
1562 /* select the point to add, in constant time */
1563 select_point(bits, 16, g_pre_comp[0], tmp);
1564 point_add(nq[0], nq[1], nq[2],
1565 nq[0], nq[1], nq[2],
1566 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
1567 }
1568
1569 /* do other additions every 5 doublings */
1570 if (num_points && (i % 5 == 0))
1571 {
1572 /* loop over all scalars */
1573 for (num = 0; num < num_points; ++num)
1574 {
1575 bits = get_bit(scalars[num], i + 4) << 5;
1576 bits |= get_bit(scalars[num], i + 3) << 4;
1577 bits |= get_bit(scalars[num], i + 2) << 3;
1578 bits |= get_bit(scalars[num], i + 1) << 2;
1579 bits |= get_bit(scalars[num], i) << 1;
1580 bits |= get_bit(scalars[num], i - 1);
1581 ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1582
1583 /* select the point to add or subtract, in constant time */
1584 select_point(digit, 17, pre_comp[num], tmp);
1585 smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative point */
1586 copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1));
1587 felem_contract(tmp[1], ftmp);
1588
1589 if (!skip)
1590 {
1591 point_add(nq[0], nq[1], nq[2],
1592 nq[0], nq[1], nq[2],
1593 mixed, tmp[0], tmp[1], tmp[2]);
1594 }
1595 else
1596 {
1597 smallfelem_expand(nq[0], tmp[0]);
1598 smallfelem_expand(nq[1], tmp[1]);
1599 smallfelem_expand(nq[2], tmp[2]);
1600 skip = 0;
1601 }
1602 }
1603 }
1604 }
1605 felem_assign(x_out, nq[0]);
1606 felem_assign(y_out, nq[1]);
1607 felem_assign(z_out, nq[2]);
1608 }
1609
1610/* Precomputation for the group generator. */
1611typedef struct {
1612 smallfelem g_pre_comp[2][16][3];
1613 int references;
1614} NISTP256_PRE_COMP;
1615
1616const EC_METHOD *EC_GFp_nistp256_method(void)
1617 {
1618 static const EC_METHOD ret = {
1619 EC_FLAGS_DEFAULT_OCT,
1620 NID_X9_62_prime_field,
1621 ec_GFp_nistp256_group_init,
1622 ec_GFp_simple_group_finish,
1623 ec_GFp_simple_group_clear_finish,
1624 ec_GFp_nist_group_copy,
1625 ec_GFp_nistp256_group_set_curve,
1626 ec_GFp_simple_group_get_curve,
1627 ec_GFp_simple_group_get_degree,
1628 ec_GFp_simple_group_check_discriminant,
1629 ec_GFp_simple_point_init,
1630 ec_GFp_simple_point_finish,
1631 ec_GFp_simple_point_clear_finish,
1632 ec_GFp_simple_point_copy,
1633 ec_GFp_simple_point_set_to_infinity,
1634 ec_GFp_simple_set_Jprojective_coordinates_GFp,
1635 ec_GFp_simple_get_Jprojective_coordinates_GFp,
1636 ec_GFp_simple_point_set_affine_coordinates,
1637 ec_GFp_nistp256_point_get_affine_coordinates,
1638 0 /* point_set_compressed_coordinates */,
1639 0 /* point2oct */,
1640 0 /* oct2point */,
1641 ec_GFp_simple_add,
1642 ec_GFp_simple_dbl,
1643 ec_GFp_simple_invert,
1644 ec_GFp_simple_is_at_infinity,
1645 ec_GFp_simple_is_on_curve,
1646 ec_GFp_simple_cmp,
1647 ec_GFp_simple_make_affine,
1648 ec_GFp_simple_points_make_affine,
1649 ec_GFp_nistp256_points_mul,
1650 ec_GFp_nistp256_precompute_mult,
1651 ec_GFp_nistp256_have_precompute_mult,
1652 ec_GFp_nist_field_mul,
1653 ec_GFp_nist_field_sqr,
1654 0 /* field_div */,
1655 0 /* field_encode */,
1656 0 /* field_decode */,
1657 0 /* field_set_to_one */ };
1658
1659 return &ret;
1660 }
1661
1662/******************************************************************************/
1663/* FUNCTIONS TO MANAGE PRECOMPUTATION
1664 */
1665
1666static NISTP256_PRE_COMP *nistp256_pre_comp_new()
1667 {
1668 NISTP256_PRE_COMP *ret = NULL;
1669 ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
1670 if (!ret)
1671 {
1672 ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1673 return ret;
1674 }
1675 memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
1676 ret->references = 1;
1677 return ret;
1678 }
1679
1680static void *nistp256_pre_comp_dup(void *src_)
1681 {
1682 NISTP256_PRE_COMP *src = src_;
1683
1684 /* no need to actually copy, these objects never change! */
1685 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
1686
1687 return src_;
1688 }
1689
1690static void nistp256_pre_comp_free(void *pre_)
1691 {
1692 int i;
1693 NISTP256_PRE_COMP *pre = pre_;
1694
1695 if (!pre)
1696 return;
1697
1698 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1699 if (i > 0)
1700 return;
1701
1702 OPENSSL_free(pre);
1703 }
1704
1705static void nistp256_pre_comp_clear_free(void *pre_)
1706 {
1707 int i;
1708 NISTP256_PRE_COMP *pre = pre_;
1709
1710 if (!pre)
1711 return;
1712
1713 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1714 if (i > 0)
1715 return;
1716
1717 OPENSSL_cleanse(pre, sizeof *pre);
1718 OPENSSL_free(pre);
1719 }
1720
1721/******************************************************************************/
1722/* OPENSSL EC_METHOD FUNCTIONS
1723 */
1724
1725int ec_GFp_nistp256_group_init(EC_GROUP *group)
1726 {
1727 int ret;
1728 ret = ec_GFp_simple_group_init(group);
1729 group->a_is_minus3 = 1;
1730 return ret;
1731 }
1732
1733int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
1734 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1735 {
1736 int ret = 0;
1737 BN_CTX *new_ctx = NULL;
1738 BIGNUM *curve_p, *curve_a, *curve_b;
1739
1740 if (ctx == NULL)
1741 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1742 BN_CTX_start(ctx);
1743 if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
1744 ((curve_a = BN_CTX_get(ctx)) == NULL) ||
1745 ((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
1746 BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
1747 BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
1748 BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
1749 if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
1750 (BN_cmp(curve_b, b)))
1751 {
1752 ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
1753 EC_R_WRONG_CURVE_PARAMETERS);
1754 goto err;
1755 }
1756 group->field_mod_func = BN_nist_mod_256;
1757 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
1758err:
1759 BN_CTX_end(ctx);
1760 if (new_ctx != NULL)
1761 BN_CTX_free(new_ctx);
1762 return ret;
1763 }
1764
1765/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
1766 * (X', Y') = (X/Z^2, Y/Z^3) */
1767int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
1768 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
1769 {
1770 felem z1, z2, x_in, y_in;
1771 smallfelem x_out, y_out;
1772 longfelem tmp;
1773
1774 if (EC_POINT_is_at_infinity(group, point))
1775 {
1776 ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
1777 EC_R_POINT_AT_INFINITY);
1778 return 0;
1779 }
1780 if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
1781 (!BN_to_felem(z1, &point->Z))) return 0;
1782 felem_inv(z2, z1);
1783 felem_square(tmp, z2); felem_reduce(z1, tmp);
1784 felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
1785 felem_contract(x_out, x_in);
1786 if (x != NULL)
1787 {
1788 if (!smallfelem_to_BN(x, x_out)) {
1789 ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
1790 ERR_R_BN_LIB);
1791 return 0;
1792 }
1793 }
1794 felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
1795 felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
1796 felem_contract(y_out, y_in);
1797 if (y != NULL)
1798 {
1799 if (!smallfelem_to_BN(y, y_out))
1800 {
1801 ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
1802 ERR_R_BN_LIB);
1803 return 0;
1804 }
1805 }
1806 return 1;
1807 }
1808
1809static void make_points_affine(size_t num, smallfelem points[/* num */][3], smallfelem tmp_smallfelems[/* num+1 */])
1810 {
1811 /* Runs in constant time, unless an input is the point at infinity
1812 * (which normally shouldn't happen). */
1813 ec_GFp_nistp_points_make_affine_internal(
1814 num,
1815 points,
1816 sizeof(smallfelem),
1817 tmp_smallfelems,
1818 (void (*)(void *)) smallfelem_one,
1819 (int (*)(const void *)) smallfelem_is_zero_int,
1820 (void (*)(void *, const void *)) smallfelem_assign,
1821 (void (*)(void *, const void *)) smallfelem_square_contract,
1822 (void (*)(void *, const void *, const void *)) smallfelem_mul_contract,
1823 (void (*)(void *, const void *)) smallfelem_inv_contract,
1824 (void (*)(void *, const void *)) smallfelem_assign /* nothing to contract */);
1825 }
1826
1827/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
1828 * Result is stored in r (r can equal one of the inputs). */
1829int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
1830 const BIGNUM *scalar, size_t num, const EC_POINT *points[],
1831 const BIGNUM *scalars[], BN_CTX *ctx)
1832 {
1833 int ret = 0;
1834 int j;
1835 int mixed = 0;
1836 BN_CTX *new_ctx = NULL;
1837 BIGNUM *x, *y, *z, *tmp_scalar;
1838 felem_bytearray g_secret;
1839 felem_bytearray *secrets = NULL;
1840 smallfelem (*pre_comp)[17][3] = NULL;
1841 smallfelem *tmp_smallfelems = NULL;
1842 felem_bytearray tmp;
1843 unsigned i, num_bytes;
1844 int have_pre_comp = 0;
1845 size_t num_points = num;
1846 smallfelem x_in, y_in, z_in;
1847 felem x_out, y_out, z_out;
1848 NISTP256_PRE_COMP *pre = NULL;
1849 const smallfelem (*g_pre_comp)[16][3] = NULL;
1850 EC_POINT *generator = NULL;
1851 const EC_POINT *p = NULL;
1852 const BIGNUM *p_scalar = NULL;
1853
1854 if (ctx == NULL)
1855 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1856 BN_CTX_start(ctx);
1857 if (((x = BN_CTX_get(ctx)) == NULL) ||
1858 ((y = BN_CTX_get(ctx)) == NULL) ||
1859 ((z = BN_CTX_get(ctx)) == NULL) ||
1860 ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
1861 goto err;
1862
1863 if (scalar != NULL)
1864 {
1865 pre = EC_EX_DATA_get_data(group->extra_data,
1866 nistp256_pre_comp_dup, nistp256_pre_comp_free,
1867 nistp256_pre_comp_clear_free);
1868 if (pre)
1869 /* we have precomputation, try to use it */
1870 g_pre_comp = (const smallfelem (*)[16][3]) pre->g_pre_comp;
1871 else
1872 /* try to use the standard precomputation */
1873 g_pre_comp = &gmul[0];
1874 generator = EC_POINT_new(group);
1875 if (generator == NULL)
1876 goto err;
1877 /* get the generator from precomputation */
1878 if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
1879 !smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
1880 !smallfelem_to_BN(z, g_pre_comp[0][1][2]))
1881 {
1882 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
1883 goto err;
1884 }
1885 if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
1886 generator, x, y, z, ctx))
1887 goto err;
1888 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1889 /* precomputation matches generator */
1890 have_pre_comp = 1;
1891 else
1892 /* we don't have valid precomputation:
1893 * treat the generator as a random point */
1894 num_points++;
1895 }
1896 if (num_points > 0)
1897 {
1898 if (num_points >= 3)
1899 {
1900 /* unless we precompute multiples for just one or two points,
1901 * converting those into affine form is time well spent */
1902 mixed = 1;
1903 }
1904 secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
1905 pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
1906 if (mixed)
1907 tmp_smallfelems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
1908 if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_smallfelems == NULL)))
1909 {
1910 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1911 goto err;
1912 }
1913
1914 /* we treat NULL scalars as 0, and NULL points as points at infinity,
1915 * i.e., they contribute nothing to the linear combination */
1916 memset(secrets, 0, num_points * sizeof(felem_bytearray));
1917 memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
1918 for (i = 0; i < num_points; ++i)
1919 {
1920 if (i == num)
1921 /* we didn't have a valid precomputation, so we pick
1922 * the generator */
1923 {
1924 p = EC_GROUP_get0_generator(group);
1925 p_scalar = scalar;
1926 }
1927 else
1928 /* the i^th point */
1929 {
1930 p = points[i];
1931 p_scalar = scalars[i];
1932 }
1933 if ((p_scalar != NULL) && (p != NULL))
1934 {
1935 /* reduce scalar to 0 <= scalar < 2^256 */
1936 if ((BN_num_bits(p_scalar) > 256) || (BN_is_negative(p_scalar)))
1937 {
1938 /* this is an unusual input, and we don't guarantee
1939 * constant-timeness */
1940 if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
1941 {
1942 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
1943 goto err;
1944 }
1945 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1946 }
1947 else
1948 num_bytes = BN_bn2bin(p_scalar, tmp);
1949 flip_endian(secrets[i], tmp, num_bytes);
1950 /* precompute multiples */
1951 if ((!BN_to_felem(x_out, &p->X)) ||
1952 (!BN_to_felem(y_out, &p->Y)) ||
1953 (!BN_to_felem(z_out, &p->Z))) goto err;
1954 felem_shrink(pre_comp[i][1][0], x_out);
1955 felem_shrink(pre_comp[i][1][1], y_out);
1956 felem_shrink(pre_comp[i][1][2], z_out);
1957 for (j = 2; j <= 16; ++j)
1958 {
1959 if (j & 1)
1960 {
1961 point_add_small(
1962 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1963 pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
1964 pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
1965 }
1966 else
1967 {
1968 point_double_small(
1969 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1970 pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
1971 }
1972 }
1973 }
1974 }
1975 if (mixed)
1976 make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
1977 }
1978
1979 /* the scalar for the generator */
1980 if ((scalar != NULL) && (have_pre_comp))
1981 {
1982 memset(g_secret, 0, sizeof(g_secret));
1983 /* reduce scalar to 0 <= scalar < 2^256 */
1984 if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar)))
1985 {
1986 /* this is an unusual input, and we don't guarantee
1987 * constant-timeness */
1988 if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
1989 {
1990 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
1991 goto err;
1992 }
1993 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1994 }
1995 else
1996 num_bytes = BN_bn2bin(scalar, tmp);
1997 flip_endian(g_secret, tmp, num_bytes);
1998 /* do the multiplication with generator precomputation*/
1999 batch_mul(x_out, y_out, z_out,
2000 (const felem_bytearray (*)) secrets, num_points,
2001 g_secret,
2002 mixed, (const smallfelem (*)[17][3]) pre_comp,
2003 g_pre_comp);
2004 }
2005 else
2006 /* do the multiplication without generator precomputation */
2007 batch_mul(x_out, y_out, z_out,
2008 (const felem_bytearray (*)) secrets, num_points,
2009 NULL, mixed, (const smallfelem (*)[17][3]) pre_comp, NULL);
2010 /* reduce the output to its unique minimal representation */
2011 felem_contract(x_in, x_out);
2012 felem_contract(y_in, y_out);
2013 felem_contract(z_in, z_out);
2014 if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
2015 (!smallfelem_to_BN(z, z_in)))
2016 {
2017 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
2018 goto err;
2019 }
2020 ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
2021
2022err:
2023 BN_CTX_end(ctx);
2024 if (generator != NULL)
2025 EC_POINT_free(generator);
2026 if (new_ctx != NULL)
2027 BN_CTX_free(new_ctx);
2028 if (secrets != NULL)
2029 OPENSSL_free(secrets);
2030 if (pre_comp != NULL)
2031 OPENSSL_free(pre_comp);
2032 if (tmp_smallfelems != NULL)
2033 OPENSSL_free(tmp_smallfelems);
2034 return ret;
2035 }
2036
2037int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
2038 {
2039 int ret = 0;
2040 NISTP256_PRE_COMP *pre = NULL;
2041 int i, j;
2042 BN_CTX *new_ctx = NULL;
2043 BIGNUM *x, *y;
2044 EC_POINT *generator = NULL;
2045 smallfelem tmp_smallfelems[32];
2046 felem x_tmp, y_tmp, z_tmp;
2047
2048 /* throw away old precomputation */
2049 EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup,
2050 nistp256_pre_comp_free, nistp256_pre_comp_clear_free);
2051 if (ctx == NULL)
2052 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
2053 BN_CTX_start(ctx);
2054 if (((x = BN_CTX_get(ctx)) == NULL) ||
2055 ((y = BN_CTX_get(ctx)) == NULL))
2056 goto err;
2057 /* get the generator */
2058 if (group->generator == NULL) goto err;
2059 generator = EC_POINT_new(group);
2060 if (generator == NULL)
2061 goto err;
2062 BN_bin2bn(nistp256_curve_params[3], sizeof (felem_bytearray), x);
2063 BN_bin2bn(nistp256_curve_params[4], sizeof (felem_bytearray), y);
2064 if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
2065 goto err;
2066 if ((pre = nistp256_pre_comp_new()) == NULL)
2067 goto err;
2068 /* if the generator is the standard one, use built-in precomputation */
2069 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
2070 {
2071 memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
2072 ret = 1;
2073 goto err;
2074 }
2075 if ((!BN_to_felem(x_tmp, &group->generator->X)) ||
2076 (!BN_to_felem(y_tmp, &group->generator->Y)) ||
2077 (!BN_to_felem(z_tmp, &group->generator->Z)))
2078 goto err;
2079 felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
2080 felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
2081 felem_shrink(pre->g_pre_comp[0][1][2], z_tmp);
2082 /* compute 2^64*G, 2^128*G, 2^192*G for the first table,
2083 * 2^32*G, 2^96*G, 2^160*G, 2^224*G for the second one
2084 */
2085 for (i = 1; i <= 8; i <<= 1)
2086 {
2087 point_double_small(
2088 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
2089 pre->g_pre_comp[0][i][0], pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
2090 for (j = 0; j < 31; ++j)
2091 {
2092 point_double_small(
2093 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2],
2094 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
2095 }
2096 if (i == 8)
2097 break;
2098 point_double_small(
2099 pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
2100 pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
2101 for (j = 0; j < 31; ++j)
2102 {
2103 point_double_small(
2104 pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2],
2105 pre->g_pre_comp[0][2*i][0], pre->g_pre_comp[0][2*i][1], pre->g_pre_comp[0][2*i][2]);
2106 }
2107 }
2108 for (i = 0; i < 2; i++)
2109 {
2110 /* g_pre_comp[i][0] is the point at infinity */
2111 memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
2112 /* the remaining multiples */
2113 /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */
2114 point_add_small(
2115 pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], pre->g_pre_comp[i][6][2],
2116 pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
2117 pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
2118 /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */
2119 point_add_small(
2120 pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], pre->g_pre_comp[i][10][2],
2121 pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
2122 pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
2123 /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */
2124 point_add_small(
2125 pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
2126 pre->g_pre_comp[i][8][0], pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
2127 pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2]);
2128 /* 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G */
2129 point_add_small(
2130 pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], pre->g_pre_comp[i][14][2],
2131 pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
2132 pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], pre->g_pre_comp[i][2][2]);
2133 for (j = 1; j < 8; ++j)
2134 {
2135 /* odd multiples: add G resp. 2^32*G */
2136 point_add_small(
2137 pre->g_pre_comp[i][2*j+1][0], pre->g_pre_comp[i][2*j+1][1], pre->g_pre_comp[i][2*j+1][2],
2138 pre->g_pre_comp[i][2*j][0], pre->g_pre_comp[i][2*j][1], pre->g_pre_comp[i][2*j][2],
2139 pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1], pre->g_pre_comp[i][1][2]);
2140 }
2141 }
2142 make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
2143
2144 if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup,
2145 nistp256_pre_comp_free, nistp256_pre_comp_clear_free))
2146 goto err;
2147 ret = 1;
2148 pre = NULL;
2149 err:
2150 BN_CTX_end(ctx);
2151 if (generator != NULL)
2152 EC_POINT_free(generator);
2153 if (new_ctx != NULL)
2154 BN_CTX_free(new_ctx);
2155 if (pre)
2156 nistp256_pre_comp_free(pre);
2157 return ret;
2158 }
2159
2160int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
2161 {
2162 if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup,
2163 nistp256_pre_comp_free, nistp256_pre_comp_clear_free)
2164 != NULL)
2165 return 1;
2166 else
2167 return 0;
2168 }
2169#else
2170static void *dummy=&dummy;
2171#endif
diff --git a/src/lib/libcrypto/ec/ecp_nistp521.c b/src/lib/libcrypto/ec/ecp_nistp521.c
deleted file mode 100644
index 178b655f7f..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistp521.c
+++ /dev/null
@@ -1,2025 +0,0 @@
1/* crypto/ec/ecp_nistp521.c */
2/*
3 * Written by Adam Langley (Google) for the OpenSSL project
4 */
5/* Copyright 2011 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 *
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21/*
22 * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
23 *
24 * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
25 * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
26 * work which got its smarts from Daniel J. Bernstein's work on the same.
27 */
28
29#include <openssl/opensslconf.h>
30#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
31
32#ifndef OPENSSL_SYS_VMS
33#include <stdint.h>
34#else
35#include <inttypes.h>
36#endif
37
38#include <string.h>
39#include <openssl/err.h>
40#include "ec_lcl.h"
41
42#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
43 /* even with gcc, the typedef won't work for 32-bit platforms */
44 typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit platforms */
45#else
46 #error "Need GCC 3.1 or later to define type uint128_t"
47#endif
48
49typedef uint8_t u8;
50typedef uint64_t u64;
51typedef int64_t s64;
52
53/* The underlying field.
54 *
55 * P521 operates over GF(2^521-1). We can serialise an element of this field
56 * into 66 bytes where the most significant byte contains only a single bit. We
57 * call this an felem_bytearray. */
58
59typedef u8 felem_bytearray[66];
60
61/* These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5.
62 * These values are big-endian. */
63static const felem_bytearray nistp521_curve_params[5] =
64 {
65 {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
68 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
69 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
70 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
71 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
72 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73 0xff, 0xff},
74 {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */
75 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
77 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
80 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
81 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
82 0xff, 0xfc},
83 {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */
84 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
85 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
86 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
87 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
88 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
89 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
90 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
91 0x3f, 0x00},
92 {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */
93 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
94 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
95 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
96 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
97 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
98 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
99 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
100 0xbd, 0x66},
101 {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */
102 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
103 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
104 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
105 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
106 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
107 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
108 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
109 0x66, 0x50}
110 };
111
112/* The representation of field elements.
113 * ------------------------------------
114 *
115 * We represent field elements with nine values. These values are either 64 or
116 * 128 bits and the field element represented is:
117 * v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464 (mod p)
118 * Each of the nine values is called a 'limb'. Since the limbs are spaced only
119 * 58 bits apart, but are greater than 58 bits in length, the most significant
120 * bits of each limb overlap with the least significant bits of the next.
121 *
122 * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
123 * 'largefelem' */
124
125#define NLIMBS 9
126
127typedef uint64_t limb;
128typedef limb felem[NLIMBS];
129typedef uint128_t largefelem[NLIMBS];
130
131static const limb bottom57bits = 0x1ffffffffffffff;
132static const limb bottom58bits = 0x3ffffffffffffff;
133
134/* bin66_to_felem takes a little-endian byte array and converts it into felem
135 * form. This assumes that the CPU is little-endian. */
136static void bin66_to_felem(felem out, const u8 in[66])
137 {
138 out[0] = (*((limb*) &in[0])) & bottom58bits;
139 out[1] = (*((limb*) &in[7]) >> 2) & bottom58bits;
140 out[2] = (*((limb*) &in[14]) >> 4) & bottom58bits;
141 out[3] = (*((limb*) &in[21]) >> 6) & bottom58bits;
142 out[4] = (*((limb*) &in[29])) & bottom58bits;
143 out[5] = (*((limb*) &in[36]) >> 2) & bottom58bits;
144 out[6] = (*((limb*) &in[43]) >> 4) & bottom58bits;
145 out[7] = (*((limb*) &in[50]) >> 6) & bottom58bits;
146 out[8] = (*((limb*) &in[58])) & bottom57bits;
147 }
148
149/* felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
150 * array. This assumes that the CPU is little-endian. */
151static void felem_to_bin66(u8 out[66], const felem in)
152 {
153 memset(out, 0, 66);
154 (*((limb*) &out[0])) = in[0];
155 (*((limb*) &out[7])) |= in[1] << 2;
156 (*((limb*) &out[14])) |= in[2] << 4;
157 (*((limb*) &out[21])) |= in[3] << 6;
158 (*((limb*) &out[29])) = in[4];
159 (*((limb*) &out[36])) |= in[5] << 2;
160 (*((limb*) &out[43])) |= in[6] << 4;
161 (*((limb*) &out[50])) |= in[7] << 6;
162 (*((limb*) &out[58])) = in[8];
163 }
164
165/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
166static void flip_endian(u8 *out, const u8 *in, unsigned len)
167 {
168 unsigned i;
169 for (i = 0; i < len; ++i)
170 out[i] = in[len-1-i];
171 }
172
173/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
174static int BN_to_felem(felem out, const BIGNUM *bn)
175 {
176 felem_bytearray b_in;
177 felem_bytearray b_out;
178 unsigned num_bytes;
179
180 /* BN_bn2bin eats leading zeroes */
181 memset(b_out, 0, sizeof b_out);
182 num_bytes = BN_num_bytes(bn);
183 if (num_bytes > sizeof b_out)
184 {
185 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
186 return 0;
187 }
188 if (BN_is_negative(bn))
189 {
190 ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
191 return 0;
192 }
193 num_bytes = BN_bn2bin(bn, b_in);
194 flip_endian(b_out, b_in, num_bytes);
195 bin66_to_felem(out, b_out);
196 return 1;
197 }
198
199/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
200static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
201 {
202 felem_bytearray b_in, b_out;
203 felem_to_bin66(b_in, in);
204 flip_endian(b_out, b_in, sizeof b_out);
205 return BN_bin2bn(b_out, sizeof b_out, out);
206 }
207
208
209/* Field operations
210 * ---------------- */
211
212static void felem_one(felem out)
213 {
214 out[0] = 1;
215 out[1] = 0;
216 out[2] = 0;
217 out[3] = 0;
218 out[4] = 0;
219 out[5] = 0;
220 out[6] = 0;
221 out[7] = 0;
222 out[8] = 0;
223 }
224
225static void felem_assign(felem out, const felem in)
226 {
227 out[0] = in[0];
228 out[1] = in[1];
229 out[2] = in[2];
230 out[3] = in[3];
231 out[4] = in[4];
232 out[5] = in[5];
233 out[6] = in[6];
234 out[7] = in[7];
235 out[8] = in[8];
236 }
237
238/* felem_sum64 sets out = out + in. */
239static void felem_sum64(felem out, const felem in)
240 {
241 out[0] += in[0];
242 out[1] += in[1];
243 out[2] += in[2];
244 out[3] += in[3];
245 out[4] += in[4];
246 out[5] += in[5];
247 out[6] += in[6];
248 out[7] += in[7];
249 out[8] += in[8];
250 }
251
252/* felem_scalar sets out = in * scalar */
253static void felem_scalar(felem out, const felem in, limb scalar)
254 {
255 out[0] = in[0] * scalar;
256 out[1] = in[1] * scalar;
257 out[2] = in[2] * scalar;
258 out[3] = in[3] * scalar;
259 out[4] = in[4] * scalar;
260 out[5] = in[5] * scalar;
261 out[6] = in[6] * scalar;
262 out[7] = in[7] * scalar;
263 out[8] = in[8] * scalar;
264 }
265
266/* felem_scalar64 sets out = out * scalar */
267static void felem_scalar64(felem out, limb scalar)
268 {
269 out[0] *= scalar;
270 out[1] *= scalar;
271 out[2] *= scalar;
272 out[3] *= scalar;
273 out[4] *= scalar;
274 out[5] *= scalar;
275 out[6] *= scalar;
276 out[7] *= scalar;
277 out[8] *= scalar;
278 }
279
280/* felem_scalar128 sets out = out * scalar */
281static void felem_scalar128(largefelem out, limb scalar)
282 {
283 out[0] *= scalar;
284 out[1] *= scalar;
285 out[2] *= scalar;
286 out[3] *= scalar;
287 out[4] *= scalar;
288 out[5] *= scalar;
289 out[6] *= scalar;
290 out[7] *= scalar;
291 out[8] *= scalar;
292 }
293
294/* felem_neg sets |out| to |-in|
295 * On entry:
296 * in[i] < 2^59 + 2^14
297 * On exit:
298 * out[i] < 2^62
299 */
300static void felem_neg(felem out, const felem in)
301 {
302 /* In order to prevent underflow, we subtract from 0 mod p. */
303 static const limb two62m3 = (((limb)1) << 62) - (((limb)1) << 5);
304 static const limb two62m2 = (((limb)1) << 62) - (((limb)1) << 4);
305
306 out[0] = two62m3 - in[0];
307 out[1] = two62m2 - in[1];
308 out[2] = two62m2 - in[2];
309 out[3] = two62m2 - in[3];
310 out[4] = two62m2 - in[4];
311 out[5] = two62m2 - in[5];
312 out[6] = two62m2 - in[6];
313 out[7] = two62m2 - in[7];
314 out[8] = two62m2 - in[8];
315 }
316
317/* felem_diff64 subtracts |in| from |out|
318 * On entry:
319 * in[i] < 2^59 + 2^14
320 * On exit:
321 * out[i] < out[i] + 2^62
322 */
323static void felem_diff64(felem out, const felem in)
324 {
325 /* In order to prevent underflow, we add 0 mod p before subtracting. */
326 static const limb two62m3 = (((limb)1) << 62) - (((limb)1) << 5);
327 static const limb two62m2 = (((limb)1) << 62) - (((limb)1) << 4);
328
329 out[0] += two62m3 - in[0];
330 out[1] += two62m2 - in[1];
331 out[2] += two62m2 - in[2];
332 out[3] += two62m2 - in[3];
333 out[4] += two62m2 - in[4];
334 out[5] += two62m2 - in[5];
335 out[6] += two62m2 - in[6];
336 out[7] += two62m2 - in[7];
337 out[8] += two62m2 - in[8];
338 }
339
340/* felem_diff_128_64 subtracts |in| from |out|
341 * On entry:
342 * in[i] < 2^62 + 2^17
343 * On exit:
344 * out[i] < out[i] + 2^63
345 */
346static void felem_diff_128_64(largefelem out, const felem in)
347 {
348 /* In order to prevent underflow, we add 0 mod p before subtracting. */
349 static const limb two63m6 = (((limb)1) << 62) - (((limb)1) << 5);
350 static const limb two63m5 = (((limb)1) << 62) - (((limb)1) << 4);
351
352 out[0] += two63m6 - in[0];
353 out[1] += two63m5 - in[1];
354 out[2] += two63m5 - in[2];
355 out[3] += two63m5 - in[3];
356 out[4] += two63m5 - in[4];
357 out[5] += two63m5 - in[5];
358 out[6] += two63m5 - in[6];
359 out[7] += two63m5 - in[7];
360 out[8] += two63m5 - in[8];
361 }
362
363/* felem_diff_128_64 subtracts |in| from |out|
364 * On entry:
365 * in[i] < 2^126
366 * On exit:
367 * out[i] < out[i] + 2^127 - 2^69
368 */
369static void felem_diff128(largefelem out, const largefelem in)
370 {
371 /* In order to prevent underflow, we add 0 mod p before subtracting. */
372 static const uint128_t two127m70 = (((uint128_t)1) << 127) - (((uint128_t)1) << 70);
373 static const uint128_t two127m69 = (((uint128_t)1) << 127) - (((uint128_t)1) << 69);
374
375 out[0] += (two127m70 - in[0]);
376 out[1] += (two127m69 - in[1]);
377 out[2] += (two127m69 - in[2]);
378 out[3] += (two127m69 - in[3]);
379 out[4] += (two127m69 - in[4]);
380 out[5] += (two127m69 - in[5]);
381 out[6] += (two127m69 - in[6]);
382 out[7] += (two127m69 - in[7]);
383 out[8] += (two127m69 - in[8]);
384 }
385
386/* felem_square sets |out| = |in|^2
387 * On entry:
388 * in[i] < 2^62
389 * On exit:
390 * out[i] < 17 * max(in[i]) * max(in[i])
391 */
392static void felem_square(largefelem out, const felem in)
393 {
394 felem inx2, inx4;
395 felem_scalar(inx2, in, 2);
396 felem_scalar(inx4, in, 4);
397
398 /* We have many cases were we want to do
399 * in[x] * in[y] +
400 * in[y] * in[x]
401 * This is obviously just
402 * 2 * in[x] * in[y]
403 * However, rather than do the doubling on the 128 bit result, we
404 * double one of the inputs to the multiplication by reading from
405 * |inx2| */
406
407 out[0] = ((uint128_t) in[0]) * in[0];
408 out[1] = ((uint128_t) in[0]) * inx2[1];
409 out[2] = ((uint128_t) in[0]) * inx2[2] +
410 ((uint128_t) in[1]) * in[1];
411 out[3] = ((uint128_t) in[0]) * inx2[3] +
412 ((uint128_t) in[1]) * inx2[2];
413 out[4] = ((uint128_t) in[0]) * inx2[4] +
414 ((uint128_t) in[1]) * inx2[3] +
415 ((uint128_t) in[2]) * in[2];
416 out[5] = ((uint128_t) in[0]) * inx2[5] +
417 ((uint128_t) in[1]) * inx2[4] +
418 ((uint128_t) in[2]) * inx2[3];
419 out[6] = ((uint128_t) in[0]) * inx2[6] +
420 ((uint128_t) in[1]) * inx2[5] +
421 ((uint128_t) in[2]) * inx2[4] +
422 ((uint128_t) in[3]) * in[3];
423 out[7] = ((uint128_t) in[0]) * inx2[7] +
424 ((uint128_t) in[1]) * inx2[6] +
425 ((uint128_t) in[2]) * inx2[5] +
426 ((uint128_t) in[3]) * inx2[4];
427 out[8] = ((uint128_t) in[0]) * inx2[8] +
428 ((uint128_t) in[1]) * inx2[7] +
429 ((uint128_t) in[2]) * inx2[6] +
430 ((uint128_t) in[3]) * inx2[5] +
431 ((uint128_t) in[4]) * in[4];
432
433 /* The remaining limbs fall above 2^521, with the first falling at
434 * 2^522. They correspond to locations one bit up from the limbs
435 * produced above so we would have to multiply by two to align them.
436 * Again, rather than operate on the 128-bit result, we double one of
437 * the inputs to the multiplication. If we want to double for both this
438 * reason, and the reason above, then we end up multiplying by four. */
439
440 /* 9 */
441 out[0] += ((uint128_t) in[1]) * inx4[8] +
442 ((uint128_t) in[2]) * inx4[7] +
443 ((uint128_t) in[3]) * inx4[6] +
444 ((uint128_t) in[4]) * inx4[5];
445
446 /* 10 */
447 out[1] += ((uint128_t) in[2]) * inx4[8] +
448 ((uint128_t) in[3]) * inx4[7] +
449 ((uint128_t) in[4]) * inx4[6] +
450 ((uint128_t) in[5]) * inx2[5];
451
452 /* 11 */
453 out[2] += ((uint128_t) in[3]) * inx4[8] +
454 ((uint128_t) in[4]) * inx4[7] +
455 ((uint128_t) in[5]) * inx4[6];
456
457 /* 12 */
458 out[3] += ((uint128_t) in[4]) * inx4[8] +
459 ((uint128_t) in[5]) * inx4[7] +
460 ((uint128_t) in[6]) * inx2[6];
461
462 /* 13 */
463 out[4] += ((uint128_t) in[5]) * inx4[8] +
464 ((uint128_t) in[6]) * inx4[7];
465
466 /* 14 */
467 out[5] += ((uint128_t) in[6]) * inx4[8] +
468 ((uint128_t) in[7]) * inx2[7];
469
470 /* 15 */
471 out[6] += ((uint128_t) in[7]) * inx4[8];
472
473 /* 16 */
474 out[7] += ((uint128_t) in[8]) * inx2[8];
475 }
476
477/* felem_mul sets |out| = |in1| * |in2|
478 * On entry:
479 * in1[i] < 2^64
480 * in2[i] < 2^63
481 * On exit:
482 * out[i] < 17 * max(in1[i]) * max(in2[i])
483 */
484static void felem_mul(largefelem out, const felem in1, const felem in2)
485 {
486 felem in2x2;
487 felem_scalar(in2x2, in2, 2);
488
489 out[0] = ((uint128_t) in1[0]) * in2[0];
490
491 out[1] = ((uint128_t) in1[0]) * in2[1] +
492 ((uint128_t) in1[1]) * in2[0];
493
494 out[2] = ((uint128_t) in1[0]) * in2[2] +
495 ((uint128_t) in1[1]) * in2[1] +
496 ((uint128_t) in1[2]) * in2[0];
497
498 out[3] = ((uint128_t) in1[0]) * in2[3] +
499 ((uint128_t) in1[1]) * in2[2] +
500 ((uint128_t) in1[2]) * in2[1] +
501 ((uint128_t) in1[3]) * in2[0];
502
503 out[4] = ((uint128_t) in1[0]) * in2[4] +
504 ((uint128_t) in1[1]) * in2[3] +
505 ((uint128_t) in1[2]) * in2[2] +
506 ((uint128_t) in1[3]) * in2[1] +
507 ((uint128_t) in1[4]) * in2[0];
508
509 out[5] = ((uint128_t) in1[0]) * in2[5] +
510 ((uint128_t) in1[1]) * in2[4] +
511 ((uint128_t) in1[2]) * in2[3] +
512 ((uint128_t) in1[3]) * in2[2] +
513 ((uint128_t) in1[4]) * in2[1] +
514 ((uint128_t) in1[5]) * in2[0];
515
516 out[6] = ((uint128_t) in1[0]) * in2[6] +
517 ((uint128_t) in1[1]) * in2[5] +
518 ((uint128_t) in1[2]) * in2[4] +
519 ((uint128_t) in1[3]) * in2[3] +
520 ((uint128_t) in1[4]) * in2[2] +
521 ((uint128_t) in1[5]) * in2[1] +
522 ((uint128_t) in1[6]) * in2[0];
523
524 out[7] = ((uint128_t) in1[0]) * in2[7] +
525 ((uint128_t) in1[1]) * in2[6] +
526 ((uint128_t) in1[2]) * in2[5] +
527 ((uint128_t) in1[3]) * in2[4] +
528 ((uint128_t) in1[4]) * in2[3] +
529 ((uint128_t) in1[5]) * in2[2] +
530 ((uint128_t) in1[6]) * in2[1] +
531 ((uint128_t) in1[7]) * in2[0];
532
533 out[8] = ((uint128_t) in1[0]) * in2[8] +
534 ((uint128_t) in1[1]) * in2[7] +
535 ((uint128_t) in1[2]) * in2[6] +
536 ((uint128_t) in1[3]) * in2[5] +
537 ((uint128_t) in1[4]) * in2[4] +
538 ((uint128_t) in1[5]) * in2[3] +
539 ((uint128_t) in1[6]) * in2[2] +
540 ((uint128_t) in1[7]) * in2[1] +
541 ((uint128_t) in1[8]) * in2[0];
542
543 /* See comment in felem_square about the use of in2x2 here */
544
545 out[0] += ((uint128_t) in1[1]) * in2x2[8] +
546 ((uint128_t) in1[2]) * in2x2[7] +
547 ((uint128_t) in1[3]) * in2x2[6] +
548 ((uint128_t) in1[4]) * in2x2[5] +
549 ((uint128_t) in1[5]) * in2x2[4] +
550 ((uint128_t) in1[6]) * in2x2[3] +
551 ((uint128_t) in1[7]) * in2x2[2] +
552 ((uint128_t) in1[8]) * in2x2[1];
553
554 out[1] += ((uint128_t) in1[2]) * in2x2[8] +
555 ((uint128_t) in1[3]) * in2x2[7] +
556 ((uint128_t) in1[4]) * in2x2[6] +
557 ((uint128_t) in1[5]) * in2x2[5] +
558 ((uint128_t) in1[6]) * in2x2[4] +
559 ((uint128_t) in1[7]) * in2x2[3] +
560 ((uint128_t) in1[8]) * in2x2[2];
561
562 out[2] += ((uint128_t) in1[3]) * in2x2[8] +
563 ((uint128_t) in1[4]) * in2x2[7] +
564 ((uint128_t) in1[5]) * in2x2[6] +
565 ((uint128_t) in1[6]) * in2x2[5] +
566 ((uint128_t) in1[7]) * in2x2[4] +
567 ((uint128_t) in1[8]) * in2x2[3];
568
569 out[3] += ((uint128_t) in1[4]) * in2x2[8] +
570 ((uint128_t) in1[5]) * in2x2[7] +
571 ((uint128_t) in1[6]) * in2x2[6] +
572 ((uint128_t) in1[7]) * in2x2[5] +
573 ((uint128_t) in1[8]) * in2x2[4];
574
575 out[4] += ((uint128_t) in1[5]) * in2x2[8] +
576 ((uint128_t) in1[6]) * in2x2[7] +
577 ((uint128_t) in1[7]) * in2x2[6] +
578 ((uint128_t) in1[8]) * in2x2[5];
579
580 out[5] += ((uint128_t) in1[6]) * in2x2[8] +
581 ((uint128_t) in1[7]) * in2x2[7] +
582 ((uint128_t) in1[8]) * in2x2[6];
583
584 out[6] += ((uint128_t) in1[7]) * in2x2[8] +
585 ((uint128_t) in1[8]) * in2x2[7];
586
587 out[7] += ((uint128_t) in1[8]) * in2x2[8];
588 }
589
590static const limb bottom52bits = 0xfffffffffffff;
591
592/* felem_reduce converts a largefelem to an felem.
593 * On entry:
594 * in[i] < 2^128
595 * On exit:
596 * out[i] < 2^59 + 2^14
597 */
598static void felem_reduce(felem out, const largefelem in)
599 {
600 u64 overflow1, overflow2;
601
602 out[0] = ((limb) in[0]) & bottom58bits;
603 out[1] = ((limb) in[1]) & bottom58bits;
604 out[2] = ((limb) in[2]) & bottom58bits;
605 out[3] = ((limb) in[3]) & bottom58bits;
606 out[4] = ((limb) in[4]) & bottom58bits;
607 out[5] = ((limb) in[5]) & bottom58bits;
608 out[6] = ((limb) in[6]) & bottom58bits;
609 out[7] = ((limb) in[7]) & bottom58bits;
610 out[8] = ((limb) in[8]) & bottom58bits;
611
612 /* out[i] < 2^58 */
613
614 out[1] += ((limb) in[0]) >> 58;
615 out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6;
616 /* out[1] < 2^58 + 2^6 + 2^58
617 * = 2^59 + 2^6 */
618 out[2] += ((limb) (in[0] >> 64)) >> 52;
619
620 out[2] += ((limb) in[1]) >> 58;
621 out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6;
622 out[3] += ((limb) (in[1] >> 64)) >> 52;
623
624 out[3] += ((limb) in[2]) >> 58;
625 out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6;
626 out[4] += ((limb) (in[2] >> 64)) >> 52;
627
628 out[4] += ((limb) in[3]) >> 58;
629 out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6;
630 out[5] += ((limb) (in[3] >> 64)) >> 52;
631
632 out[5] += ((limb) in[4]) >> 58;
633 out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6;
634 out[6] += ((limb) (in[4] >> 64)) >> 52;
635
636 out[6] += ((limb) in[5]) >> 58;
637 out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6;
638 out[7] += ((limb) (in[5] >> 64)) >> 52;
639
640 out[7] += ((limb) in[6]) >> 58;
641 out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6;
642 out[8] += ((limb) (in[6] >> 64)) >> 52;
643
644 out[8] += ((limb) in[7]) >> 58;
645 out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
646 /* out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12
647 * < 2^59 + 2^13 */
648 overflow1 = ((limb) (in[7] >> 64)) >> 52;
649
650 overflow1 += ((limb) in[8]) >> 58;
651 overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
652 overflow2 = ((limb) (in[8] >> 64)) >> 52;
653
654 overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */
655 overflow2 <<= 1; /* overflow2 < 2^13 */
656
657 out[0] += overflow1; /* out[0] < 2^60 */
658 out[1] += overflow2; /* out[1] < 2^59 + 2^6 + 2^13 */
659
660 out[1] += out[0] >> 58; out[0] &= bottom58bits;
661 /* out[0] < 2^58
662 * out[1] < 2^59 + 2^6 + 2^13 + 2^2
663 * < 2^59 + 2^14 */
664 }
665
666static void felem_square_reduce(felem out, const felem in)
667 {
668 largefelem tmp;
669 felem_square(tmp, in);
670 felem_reduce(out, tmp);
671 }
672
673static void felem_mul_reduce(felem out, const felem in1, const felem in2)
674 {
675 largefelem tmp;
676 felem_mul(tmp, in1, in2);
677 felem_reduce(out, tmp);
678 }
679
680/* felem_inv calculates |out| = |in|^{-1}
681 *
682 * Based on Fermat's Little Theorem:
683 * a^p = a (mod p)
684 * a^{p-1} = 1 (mod p)
685 * a^{p-2} = a^{-1} (mod p)
686 */
687static void felem_inv(felem out, const felem in)
688 {
689 felem ftmp, ftmp2, ftmp3, ftmp4;
690 largefelem tmp;
691 unsigned i;
692
693 felem_square(tmp, in); felem_reduce(ftmp, tmp); /* 2^1 */
694 felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */
695 felem_assign(ftmp2, ftmp);
696 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */
697 felem_mul(tmp, in, ftmp); felem_reduce(ftmp, tmp); /* 2^3 - 2^0 */
698 felem_square(tmp, ftmp); felem_reduce(ftmp, tmp); /* 2^4 - 2^1 */
699
700 felem_square(tmp, ftmp2); felem_reduce(ftmp3, tmp); /* 2^3 - 2^1 */
701 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^4 - 2^2 */
702 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^4 - 2^0 */
703
704 felem_assign(ftmp2, ftmp3);
705 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^5 - 2^1 */
706 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^6 - 2^2 */
707 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^7 - 2^3 */
708 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^8 - 2^4 */
709 felem_assign(ftmp4, ftmp3);
710 felem_mul(tmp, ftmp3, ftmp); felem_reduce(ftmp4, tmp); /* 2^8 - 2^1 */
711 felem_square(tmp, ftmp4); felem_reduce(ftmp4, tmp); /* 2^9 - 2^2 */
712 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^8 - 2^0 */
713 felem_assign(ftmp2, ftmp3);
714
715 for (i = 0; i < 8; i++)
716 {
717 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */
718 }
719 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^16 - 2^0 */
720 felem_assign(ftmp2, ftmp3);
721
722 for (i = 0; i < 16; i++)
723 {
724 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */
725 }
726 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^32 - 2^0 */
727 felem_assign(ftmp2, ftmp3);
728
729 for (i = 0; i < 32; i++)
730 {
731 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */
732 }
733 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^64 - 2^0 */
734 felem_assign(ftmp2, ftmp3);
735
736 for (i = 0; i < 64; i++)
737 {
738 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */
739 }
740 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^128 - 2^0 */
741 felem_assign(ftmp2, ftmp3);
742
743 for (i = 0; i < 128; i++)
744 {
745 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */
746 }
747 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^256 - 2^0 */
748 felem_assign(ftmp2, ftmp3);
749
750 for (i = 0; i < 256; i++)
751 {
752 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */
753 }
754 felem_mul(tmp, ftmp3, ftmp2); felem_reduce(ftmp3, tmp); /* 2^512 - 2^0 */
755
756 for (i = 0; i < 9; i++)
757 {
758 felem_square(tmp, ftmp3); felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */
759 }
760 felem_mul(tmp, ftmp3, ftmp4); felem_reduce(ftmp3, tmp); /* 2^512 - 2^2 */
761 felem_mul(tmp, ftmp3, in); felem_reduce(out, tmp); /* 2^512 - 3 */
762}
763
764/* This is 2^521-1, expressed as an felem */
765static const felem kPrime =
766 {
767 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
768 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
769 0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff
770 };
771
772/* felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
773 * otherwise.
774 * On entry:
775 * in[i] < 2^59 + 2^14
776 */
777static limb felem_is_zero(const felem in)
778 {
779 felem ftmp;
780 limb is_zero, is_p;
781 felem_assign(ftmp, in);
782
783 ftmp[0] += ftmp[8] >> 57; ftmp[8] &= bottom57bits;
784 /* ftmp[8] < 2^57 */
785 ftmp[1] += ftmp[0] >> 58; ftmp[0] &= bottom58bits;
786 ftmp[2] += ftmp[1] >> 58; ftmp[1] &= bottom58bits;
787 ftmp[3] += ftmp[2] >> 58; ftmp[2] &= bottom58bits;
788 ftmp[4] += ftmp[3] >> 58; ftmp[3] &= bottom58bits;
789 ftmp[5] += ftmp[4] >> 58; ftmp[4] &= bottom58bits;
790 ftmp[6] += ftmp[5] >> 58; ftmp[5] &= bottom58bits;
791 ftmp[7] += ftmp[6] >> 58; ftmp[6] &= bottom58bits;
792 ftmp[8] += ftmp[7] >> 58; ftmp[7] &= bottom58bits;
793 /* ftmp[8] < 2^57 + 4 */
794
795 /* The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is
796 * greater than our bound for ftmp[8]. Therefore we only have to check
797 * if the zero is zero or 2^521-1. */
798
799 is_zero = 0;
800 is_zero |= ftmp[0];
801 is_zero |= ftmp[1];
802 is_zero |= ftmp[2];
803 is_zero |= ftmp[3];
804 is_zero |= ftmp[4];
805 is_zero |= ftmp[5];
806 is_zero |= ftmp[6];
807 is_zero |= ftmp[7];
808 is_zero |= ftmp[8];
809
810 is_zero--;
811 /* We know that ftmp[i] < 2^63, therefore the only way that the top bit
812 * can be set is if is_zero was 0 before the decrement. */
813 is_zero = ((s64) is_zero) >> 63;
814
815 is_p = ftmp[0] ^ kPrime[0];
816 is_p |= ftmp[1] ^ kPrime[1];
817 is_p |= ftmp[2] ^ kPrime[2];
818 is_p |= ftmp[3] ^ kPrime[3];
819 is_p |= ftmp[4] ^ kPrime[4];
820 is_p |= ftmp[5] ^ kPrime[5];
821 is_p |= ftmp[6] ^ kPrime[6];
822 is_p |= ftmp[7] ^ kPrime[7];
823 is_p |= ftmp[8] ^ kPrime[8];
824
825 is_p--;
826 is_p = ((s64) is_p) >> 63;
827
828 is_zero |= is_p;
829 return is_zero;
830 }
831
832static int felem_is_zero_int(const felem in)
833 {
834 return (int) (felem_is_zero(in) & ((limb)1));
835 }
836
837/* felem_contract converts |in| to its unique, minimal representation.
838 * On entry:
839 * in[i] < 2^59 + 2^14
840 */
841static void felem_contract(felem out, const felem in)
842 {
843 limb is_p, is_greater, sign;
844 static const limb two58 = ((limb)1) << 58;
845
846 felem_assign(out, in);
847
848 out[0] += out[8] >> 57; out[8] &= bottom57bits;
849 /* out[8] < 2^57 */
850 out[1] += out[0] >> 58; out[0] &= bottom58bits;
851 out[2] += out[1] >> 58; out[1] &= bottom58bits;
852 out[3] += out[2] >> 58; out[2] &= bottom58bits;
853 out[4] += out[3] >> 58; out[3] &= bottom58bits;
854 out[5] += out[4] >> 58; out[4] &= bottom58bits;
855 out[6] += out[5] >> 58; out[5] &= bottom58bits;
856 out[7] += out[6] >> 58; out[6] &= bottom58bits;
857 out[8] += out[7] >> 58; out[7] &= bottom58bits;
858 /* out[8] < 2^57 + 4 */
859
860 /* If the value is greater than 2^521-1 then we have to subtract
861 * 2^521-1 out. See the comments in felem_is_zero regarding why we
862 * don't test for other multiples of the prime. */
863
864 /* First, if |out| is equal to 2^521-1, we subtract it out to get zero. */
865
866 is_p = out[0] ^ kPrime[0];
867 is_p |= out[1] ^ kPrime[1];
868 is_p |= out[2] ^ kPrime[2];
869 is_p |= out[3] ^ kPrime[3];
870 is_p |= out[4] ^ kPrime[4];
871 is_p |= out[5] ^ kPrime[5];
872 is_p |= out[6] ^ kPrime[6];
873 is_p |= out[7] ^ kPrime[7];
874 is_p |= out[8] ^ kPrime[8];
875
876 is_p--;
877 is_p &= is_p << 32;
878 is_p &= is_p << 16;
879 is_p &= is_p << 8;
880 is_p &= is_p << 4;
881 is_p &= is_p << 2;
882 is_p &= is_p << 1;
883 is_p = ((s64) is_p) >> 63;
884 is_p = ~is_p;
885
886 /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */
887
888 out[0] &= is_p;
889 out[1] &= is_p;
890 out[2] &= is_p;
891 out[3] &= is_p;
892 out[4] &= is_p;
893 out[5] &= is_p;
894 out[6] &= is_p;
895 out[7] &= is_p;
896 out[8] &= is_p;
897
898 /* In order to test that |out| >= 2^521-1 we need only test if out[8]
899 * >> 57 is greater than zero as (2^521-1) + x >= 2^522 */
900 is_greater = out[8] >> 57;
901 is_greater |= is_greater << 32;
902 is_greater |= is_greater << 16;
903 is_greater |= is_greater << 8;
904 is_greater |= is_greater << 4;
905 is_greater |= is_greater << 2;
906 is_greater |= is_greater << 1;
907 is_greater = ((s64) is_greater) >> 63;
908
909 out[0] -= kPrime[0] & is_greater;
910 out[1] -= kPrime[1] & is_greater;
911 out[2] -= kPrime[2] & is_greater;
912 out[3] -= kPrime[3] & is_greater;
913 out[4] -= kPrime[4] & is_greater;
914 out[5] -= kPrime[5] & is_greater;
915 out[6] -= kPrime[6] & is_greater;
916 out[7] -= kPrime[7] & is_greater;
917 out[8] -= kPrime[8] & is_greater;
918
919 /* Eliminate negative coefficients */
920 sign = -(out[0] >> 63); out[0] += (two58 & sign); out[1] -= (1 & sign);
921 sign = -(out[1] >> 63); out[1] += (two58 & sign); out[2] -= (1 & sign);
922 sign = -(out[2] >> 63); out[2] += (two58 & sign); out[3] -= (1 & sign);
923 sign = -(out[3] >> 63); out[3] += (two58 & sign); out[4] -= (1 & sign);
924 sign = -(out[4] >> 63); out[4] += (two58 & sign); out[5] -= (1 & sign);
925 sign = -(out[0] >> 63); out[5] += (two58 & sign); out[6] -= (1 & sign);
926 sign = -(out[6] >> 63); out[6] += (two58 & sign); out[7] -= (1 & sign);
927 sign = -(out[7] >> 63); out[7] += (two58 & sign); out[8] -= (1 & sign);
928 sign = -(out[5] >> 63); out[5] += (two58 & sign); out[6] -= (1 & sign);
929 sign = -(out[6] >> 63); out[6] += (two58 & sign); out[7] -= (1 & sign);
930 sign = -(out[7] >> 63); out[7] += (two58 & sign); out[8] -= (1 & sign);
931 }
932
933/* Group operations
934 * ----------------
935 *
936 * Building on top of the field operations we have the operations on the
937 * elliptic curve group itself. Points on the curve are represented in Jacobian
938 * coordinates */
939
940/* point_double calcuates 2*(x_in, y_in, z_in)
941 *
942 * The method is taken from:
943 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
944 *
945 * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
946 * while x_out == y_in is not (maybe this works, but it's not tested). */
947static void
948point_double(felem x_out, felem y_out, felem z_out,
949 const felem x_in, const felem y_in, const felem z_in)
950 {
951 largefelem tmp, tmp2;
952 felem delta, gamma, beta, alpha, ftmp, ftmp2;
953
954 felem_assign(ftmp, x_in);
955 felem_assign(ftmp2, x_in);
956
957 /* delta = z^2 */
958 felem_square(tmp, z_in);
959 felem_reduce(delta, tmp); /* delta[i] < 2^59 + 2^14 */
960
961 /* gamma = y^2 */
962 felem_square(tmp, y_in);
963 felem_reduce(gamma, tmp); /* gamma[i] < 2^59 + 2^14 */
964
965 /* beta = x*gamma */
966 felem_mul(tmp, x_in, gamma);
967 felem_reduce(beta, tmp); /* beta[i] < 2^59 + 2^14 */
968
969 /* alpha = 3*(x-delta)*(x+delta) */
970 felem_diff64(ftmp, delta);
971 /* ftmp[i] < 2^61 */
972 felem_sum64(ftmp2, delta);
973 /* ftmp2[i] < 2^60 + 2^15 */
974 felem_scalar64(ftmp2, 3);
975 /* ftmp2[i] < 3*2^60 + 3*2^15 */
976 felem_mul(tmp, ftmp, ftmp2);
977 /* tmp[i] < 17(3*2^121 + 3*2^76)
978 * = 61*2^121 + 61*2^76
979 * < 64*2^121 + 64*2^76
980 * = 2^127 + 2^82
981 * < 2^128 */
982 felem_reduce(alpha, tmp);
983
984 /* x' = alpha^2 - 8*beta */
985 felem_square(tmp, alpha);
986 /* tmp[i] < 17*2^120
987 * < 2^125 */
988 felem_assign(ftmp, beta);
989 felem_scalar64(ftmp, 8);
990 /* ftmp[i] < 2^62 + 2^17 */
991 felem_diff_128_64(tmp, ftmp);
992 /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */
993 felem_reduce(x_out, tmp);
994
995 /* z' = (y + z)^2 - gamma - delta */
996 felem_sum64(delta, gamma);
997 /* delta[i] < 2^60 + 2^15 */
998 felem_assign(ftmp, y_in);
999 felem_sum64(ftmp, z_in);
1000 /* ftmp[i] < 2^60 + 2^15 */
1001 felem_square(tmp, ftmp);
1002 /* tmp[i] < 17(2^122)
1003 * < 2^127 */
1004 felem_diff_128_64(tmp, delta);
1005 /* tmp[i] < 2^127 + 2^63 */
1006 felem_reduce(z_out, tmp);
1007
1008 /* y' = alpha*(4*beta - x') - 8*gamma^2 */
1009 felem_scalar64(beta, 4);
1010 /* beta[i] < 2^61 + 2^16 */
1011 felem_diff64(beta, x_out);
1012 /* beta[i] < 2^61 + 2^60 + 2^16 */
1013 felem_mul(tmp, alpha, beta);
1014 /* tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16))
1015 * = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30)
1016 * = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
1017 * < 2^128 */
1018 felem_square(tmp2, gamma);
1019 /* tmp2[i] < 17*(2^59 + 2^14)^2
1020 * = 17*(2^118 + 2^74 + 2^28) */
1021 felem_scalar128(tmp2, 8);
1022 /* tmp2[i] < 8*17*(2^118 + 2^74 + 2^28)
1023 * = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31
1024 * < 2^126 */
1025 felem_diff128(tmp, tmp2);
1026 /* tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
1027 * = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 +
1028 * 2^74 + 2^69 + 2^34 + 2^30
1029 * < 2^128 */
1030 felem_reduce(y_out, tmp);
1031 }
1032
1033/* copy_conditional copies in to out iff mask is all ones. */
1034static void
1035copy_conditional(felem out, const felem in, limb mask)
1036 {
1037 unsigned i;
1038 for (i = 0; i < NLIMBS; ++i)
1039 {
1040 const limb tmp = mask & (in[i] ^ out[i]);
1041 out[i] ^= tmp;
1042 }
1043 }
1044
1045/* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
1046 *
1047 * The method is taken from
1048 * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
1049 * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
1050 *
1051 * This function includes a branch for checking whether the two input points
1052 * are equal (while not equal to the point at infinity). This case never
1053 * happens during single point multiplication, so there is no timing leak for
1054 * ECDH or ECDSA signing. */
1055static void point_add(felem x3, felem y3, felem z3,
1056 const felem x1, const felem y1, const felem z1,
1057 const int mixed, const felem x2, const felem y2, const felem z2)
1058 {
1059 felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
1060 largefelem tmp, tmp2;
1061 limb x_equal, y_equal, z1_is_zero, z2_is_zero;
1062
1063 z1_is_zero = felem_is_zero(z1);
1064 z2_is_zero = felem_is_zero(z2);
1065
1066 /* ftmp = z1z1 = z1**2 */
1067 felem_square(tmp, z1);
1068 felem_reduce(ftmp, tmp);
1069
1070 if (!mixed)
1071 {
1072 /* ftmp2 = z2z2 = z2**2 */
1073 felem_square(tmp, z2);
1074 felem_reduce(ftmp2, tmp);
1075
1076 /* u1 = ftmp3 = x1*z2z2 */
1077 felem_mul(tmp, x1, ftmp2);
1078 felem_reduce(ftmp3, tmp);
1079
1080 /* ftmp5 = z1 + z2 */
1081 felem_assign(ftmp5, z1);
1082 felem_sum64(ftmp5, z2);
1083 /* ftmp5[i] < 2^61 */
1084
1085 /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
1086 felem_square(tmp, ftmp5);
1087 /* tmp[i] < 17*2^122 */
1088 felem_diff_128_64(tmp, ftmp);
1089 /* tmp[i] < 17*2^122 + 2^63 */
1090 felem_diff_128_64(tmp, ftmp2);
1091 /* tmp[i] < 17*2^122 + 2^64 */
1092 felem_reduce(ftmp5, tmp);
1093
1094 /* ftmp2 = z2 * z2z2 */
1095 felem_mul(tmp, ftmp2, z2);
1096 felem_reduce(ftmp2, tmp);
1097
1098 /* s1 = ftmp6 = y1 * z2**3 */
1099 felem_mul(tmp, y1, ftmp2);
1100 felem_reduce(ftmp6, tmp);
1101 }
1102 else
1103 {
1104 /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
1105
1106 /* u1 = ftmp3 = x1*z2z2 */
1107 felem_assign(ftmp3, x1);
1108
1109 /* ftmp5 = 2*z1z2 */
1110 felem_scalar(ftmp5, z1, 2);
1111
1112 /* s1 = ftmp6 = y1 * z2**3 */
1113 felem_assign(ftmp6, y1);
1114 }
1115
1116 /* u2 = x2*z1z1 */
1117 felem_mul(tmp, x2, ftmp);
1118 /* tmp[i] < 17*2^120 */
1119
1120 /* h = ftmp4 = u2 - u1 */
1121 felem_diff_128_64(tmp, ftmp3);
1122 /* tmp[i] < 17*2^120 + 2^63 */
1123 felem_reduce(ftmp4, tmp);
1124
1125 x_equal = felem_is_zero(ftmp4);
1126
1127 /* z_out = ftmp5 * h */
1128 felem_mul(tmp, ftmp5, ftmp4);
1129 felem_reduce(z_out, tmp);
1130
1131 /* ftmp = z1 * z1z1 */
1132 felem_mul(tmp, ftmp, z1);
1133 felem_reduce(ftmp, tmp);
1134
1135 /* s2 = tmp = y2 * z1**3 */
1136 felem_mul(tmp, y2, ftmp);
1137 /* tmp[i] < 17*2^120 */
1138
1139 /* r = ftmp5 = (s2 - s1)*2 */
1140 felem_diff_128_64(tmp, ftmp6);
1141 /* tmp[i] < 17*2^120 + 2^63 */
1142 felem_reduce(ftmp5, tmp);
1143 y_equal = felem_is_zero(ftmp5);
1144 felem_scalar64(ftmp5, 2);
1145 /* ftmp5[i] < 2^61 */
1146
1147 if (x_equal && y_equal && !z1_is_zero && !z2_is_zero)
1148 {
1149 point_double(x3, y3, z3, x1, y1, z1);
1150 return;
1151 }
1152
1153 /* I = ftmp = (2h)**2 */
1154 felem_assign(ftmp, ftmp4);
1155 felem_scalar64(ftmp, 2);
1156 /* ftmp[i] < 2^61 */
1157 felem_square(tmp, ftmp);
1158 /* tmp[i] < 17*2^122 */
1159 felem_reduce(ftmp, tmp);
1160
1161 /* J = ftmp2 = h * I */
1162 felem_mul(tmp, ftmp4, ftmp);
1163 felem_reduce(ftmp2, tmp);
1164
1165 /* V = ftmp4 = U1 * I */
1166 felem_mul(tmp, ftmp3, ftmp);
1167 felem_reduce(ftmp4, tmp);
1168
1169 /* x_out = r**2 - J - 2V */
1170 felem_square(tmp, ftmp5);
1171 /* tmp[i] < 17*2^122 */
1172 felem_diff_128_64(tmp, ftmp2);
1173 /* tmp[i] < 17*2^122 + 2^63 */
1174 felem_assign(ftmp3, ftmp4);
1175 felem_scalar64(ftmp4, 2);
1176 /* ftmp4[i] < 2^61 */
1177 felem_diff_128_64(tmp, ftmp4);
1178 /* tmp[i] < 17*2^122 + 2^64 */
1179 felem_reduce(x_out, tmp);
1180
1181 /* y_out = r(V-x_out) - 2 * s1 * J */
1182 felem_diff64(ftmp3, x_out);
1183 /* ftmp3[i] < 2^60 + 2^60
1184 * = 2^61 */
1185 felem_mul(tmp, ftmp5, ftmp3);
1186 /* tmp[i] < 17*2^122 */
1187 felem_mul(tmp2, ftmp6, ftmp2);
1188 /* tmp2[i] < 17*2^120 */
1189 felem_scalar128(tmp2, 2);
1190 /* tmp2[i] < 17*2^121 */
1191 felem_diff128(tmp, tmp2);
1192 /* tmp[i] < 2^127 - 2^69 + 17*2^122
1193 * = 2^126 - 2^122 - 2^6 - 2^2 - 1
1194 * < 2^127 */
1195 felem_reduce(y_out, tmp);
1196
1197 copy_conditional(x_out, x2, z1_is_zero);
1198 copy_conditional(x_out, x1, z2_is_zero);
1199 copy_conditional(y_out, y2, z1_is_zero);
1200 copy_conditional(y_out, y1, z2_is_zero);
1201 copy_conditional(z_out, z2, z1_is_zero);
1202 copy_conditional(z_out, z1, z2_is_zero);
1203 felem_assign(x3, x_out);
1204 felem_assign(y3, y_out);
1205 felem_assign(z3, z_out);
1206 }
1207
1208/* Base point pre computation
1209 * --------------------------
1210 *
1211 * Two different sorts of precomputed tables are used in the following code.
1212 * Each contain various points on the curve, where each point is three field
1213 * elements (x, y, z).
1214 *
1215 * For the base point table, z is usually 1 (0 for the point at infinity).
1216 * This table has 16 elements:
1217 * index | bits | point
1218 * ------+---------+------------------------------
1219 * 0 | 0 0 0 0 | 0G
1220 * 1 | 0 0 0 1 | 1G
1221 * 2 | 0 0 1 0 | 2^130G
1222 * 3 | 0 0 1 1 | (2^130 + 1)G
1223 * 4 | 0 1 0 0 | 2^260G
1224 * 5 | 0 1 0 1 | (2^260 + 1)G
1225 * 6 | 0 1 1 0 | (2^260 + 2^130)G
1226 * 7 | 0 1 1 1 | (2^260 + 2^130 + 1)G
1227 * 8 | 1 0 0 0 | 2^390G
1228 * 9 | 1 0 0 1 | (2^390 + 1)G
1229 * 10 | 1 0 1 0 | (2^390 + 2^130)G
1230 * 11 | 1 0 1 1 | (2^390 + 2^130 + 1)G
1231 * 12 | 1 1 0 0 | (2^390 + 2^260)G
1232 * 13 | 1 1 0 1 | (2^390 + 2^260 + 1)G
1233 * 14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G
1234 * 15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G
1235 *
1236 * The reason for this is so that we can clock bits into four different
1237 * locations when doing simple scalar multiplies against the base point.
1238 *
1239 * Tables for other points have table[i] = iG for i in 0 .. 16. */
1240
1241/* gmul is the table of precomputed base points */
1242static const felem gmul[16][3] =
1243 {{{0, 0, 0, 0, 0, 0, 0, 0, 0},
1244 {0, 0, 0, 0, 0, 0, 0, 0, 0},
1245 {0, 0, 0, 0, 0, 0, 0, 0, 0}},
1246 {{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
1247 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
1248 0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
1249 {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353,
1250 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45,
1251 0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b},
1252 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1253 {{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad,
1254 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e,
1255 0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5},
1256 {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58,
1257 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c,
1258 0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7},
1259 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1260 {{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873,
1261 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c,
1262 0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9},
1263 {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52,
1264 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e,
1265 0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe},
1266 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1267 {{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2,
1268 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561,
1269 0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065},
1270 {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a,
1271 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e,
1272 0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524},
1273 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1274 {{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6,
1275 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51,
1276 0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe},
1277 {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d,
1278 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c,
1279 0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7},
1280 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1281 {{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27,
1282 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f,
1283 0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256},
1284 {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa,
1285 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2,
1286 0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd},
1287 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1288 {{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890,
1289 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74,
1290 0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23},
1291 {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516,
1292 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1,
1293 0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e},
1294 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1295 {{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce,
1296 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7,
1297 0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5},
1298 {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318,
1299 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83,
1300 0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242},
1301 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1302 {{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae,
1303 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef,
1304 0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203},
1305 {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447,
1306 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283,
1307 0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f},
1308 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1309 {{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5,
1310 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c,
1311 0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a},
1312 {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df,
1313 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645,
1314 0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a},
1315 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1316 {{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292,
1317 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422,
1318 0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b},
1319 {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30,
1320 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb,
1321 0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f},
1322 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1323 {{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767,
1324 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3,
1325 0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf},
1326 {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2,
1327 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692,
1328 0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d},
1329 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1330 {{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3,
1331 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade,
1332 0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684},
1333 {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8,
1334 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a,
1335 0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81},
1336 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1337 {{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608,
1338 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610,
1339 0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d},
1340 {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006,
1341 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86,
1342 0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42},
1343 {1, 0, 0, 0, 0, 0, 0, 0, 0}},
1344 {{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c,
1345 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9,
1346 0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f},
1347 {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7,
1348 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c,
1349 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
1350 {1, 0, 0, 0, 0, 0, 0, 0, 0}}};
1351
1352/* select_point selects the |idx|th point from a precomputation table and
1353 * copies it to out. */
1354static void select_point(const limb idx, unsigned int size, const felem pre_comp[/* size */][3],
1355 felem out[3])
1356 {
1357 unsigned i, j;
1358 limb *outlimbs = &out[0][0];
1359 memset(outlimbs, 0, 3 * sizeof(felem));
1360
1361 for (i = 0; i < size; i++)
1362 {
1363 const limb *inlimbs = &pre_comp[i][0][0];
1364 limb mask = i ^ idx;
1365 mask |= mask >> 4;
1366 mask |= mask >> 2;
1367 mask |= mask >> 1;
1368 mask &= 1;
1369 mask--;
1370 for (j = 0; j < NLIMBS * 3; j++)
1371 outlimbs[j] |= inlimbs[j] & mask;
1372 }
1373 }
1374
1375/* get_bit returns the |i|th bit in |in| */
1376static char get_bit(const felem_bytearray in, int i)
1377 {
1378 if (i < 0)
1379 return 0;
1380 return (in[i >> 3] >> (i & 7)) & 1;
1381 }
1382
1383/* Interleaved point multiplication using precomputed point multiples:
1384 * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
1385 * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
1386 * of the generator, using certain (large) precomputed multiples in g_pre_comp.
1387 * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
1388static void batch_mul(felem x_out, felem y_out, felem z_out,
1389 const felem_bytearray scalars[], const unsigned num_points, const u8 *g_scalar,
1390 const int mixed, const felem pre_comp[][17][3], const felem g_pre_comp[16][3])
1391 {
1392 int i, skip;
1393 unsigned num, gen_mul = (g_scalar != NULL);
1394 felem nq[3], tmp[4];
1395 limb bits;
1396 u8 sign, digit;
1397
1398 /* set nq to the point at infinity */
1399 memset(nq, 0, 3 * sizeof(felem));
1400
1401 /* Loop over all scalars msb-to-lsb, interleaving additions
1402 * of multiples of the generator (last quarter of rounds)
1403 * and additions of other points multiples (every 5th round).
1404 */
1405 skip = 1; /* save two point operations in the first round */
1406 for (i = (num_points ? 520 : 130); i >= 0; --i)
1407 {
1408 /* double */
1409 if (!skip)
1410 point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1411
1412 /* add multiples of the generator */
1413 if (gen_mul && (i <= 130))
1414 {
1415 bits = get_bit(g_scalar, i + 390) << 3;
1416 if (i < 130)
1417 {
1418 bits |= get_bit(g_scalar, i + 260) << 2;
1419 bits |= get_bit(g_scalar, i + 130) << 1;
1420 bits |= get_bit(g_scalar, i);
1421 }
1422 /* select the point to add, in constant time */
1423 select_point(bits, 16, g_pre_comp, tmp);
1424 if (!skip)
1425 {
1426 point_add(nq[0], nq[1], nq[2],
1427 nq[0], nq[1], nq[2],
1428 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
1429 }
1430 else
1431 {
1432 memcpy(nq, tmp, 3 * sizeof(felem));
1433 skip = 0;
1434 }
1435 }
1436
1437 /* do other additions every 5 doublings */
1438 if (num_points && (i % 5 == 0))
1439 {
1440 /* loop over all scalars */
1441 for (num = 0; num < num_points; ++num)
1442 {
1443 bits = get_bit(scalars[num], i + 4) << 5;
1444 bits |= get_bit(scalars[num], i + 3) << 4;
1445 bits |= get_bit(scalars[num], i + 2) << 3;
1446 bits |= get_bit(scalars[num], i + 1) << 2;
1447 bits |= get_bit(scalars[num], i) << 1;
1448 bits |= get_bit(scalars[num], i - 1);
1449 ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1450
1451 /* select the point to add or subtract, in constant time */
1452 select_point(digit, 17, pre_comp[num], tmp);
1453 felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
1454 copy_conditional(tmp[1], tmp[3], (-(limb) sign));
1455
1456 if (!skip)
1457 {
1458 point_add(nq[0], nq[1], nq[2],
1459 nq[0], nq[1], nq[2],
1460 mixed, tmp[0], tmp[1], tmp[2]);
1461 }
1462 else
1463 {
1464 memcpy(nq, tmp, 3 * sizeof(felem));
1465 skip = 0;
1466 }
1467 }
1468 }
1469 }
1470 felem_assign(x_out, nq[0]);
1471 felem_assign(y_out, nq[1]);
1472 felem_assign(z_out, nq[2]);
1473 }
1474
1475
1476/* Precomputation for the group generator. */
1477typedef struct {
1478 felem g_pre_comp[16][3];
1479 int references;
1480} NISTP521_PRE_COMP;
1481
1482const EC_METHOD *EC_GFp_nistp521_method(void)
1483 {
1484 static const EC_METHOD ret = {
1485 EC_FLAGS_DEFAULT_OCT,
1486 NID_X9_62_prime_field,
1487 ec_GFp_nistp521_group_init,
1488 ec_GFp_simple_group_finish,
1489 ec_GFp_simple_group_clear_finish,
1490 ec_GFp_nist_group_copy,
1491 ec_GFp_nistp521_group_set_curve,
1492 ec_GFp_simple_group_get_curve,
1493 ec_GFp_simple_group_get_degree,
1494 ec_GFp_simple_group_check_discriminant,
1495 ec_GFp_simple_point_init,
1496 ec_GFp_simple_point_finish,
1497 ec_GFp_simple_point_clear_finish,
1498 ec_GFp_simple_point_copy,
1499 ec_GFp_simple_point_set_to_infinity,
1500 ec_GFp_simple_set_Jprojective_coordinates_GFp,
1501 ec_GFp_simple_get_Jprojective_coordinates_GFp,
1502 ec_GFp_simple_point_set_affine_coordinates,
1503 ec_GFp_nistp521_point_get_affine_coordinates,
1504 0 /* point_set_compressed_coordinates */,
1505 0 /* point2oct */,
1506 0 /* oct2point */,
1507 ec_GFp_simple_add,
1508 ec_GFp_simple_dbl,
1509 ec_GFp_simple_invert,
1510 ec_GFp_simple_is_at_infinity,
1511 ec_GFp_simple_is_on_curve,
1512 ec_GFp_simple_cmp,
1513 ec_GFp_simple_make_affine,
1514 ec_GFp_simple_points_make_affine,
1515 ec_GFp_nistp521_points_mul,
1516 ec_GFp_nistp521_precompute_mult,
1517 ec_GFp_nistp521_have_precompute_mult,
1518 ec_GFp_nist_field_mul,
1519 ec_GFp_nist_field_sqr,
1520 0 /* field_div */,
1521 0 /* field_encode */,
1522 0 /* field_decode */,
1523 0 /* field_set_to_one */ };
1524
1525 return &ret;
1526 }
1527
1528
1529/******************************************************************************/
1530/* FUNCTIONS TO MANAGE PRECOMPUTATION
1531 */
1532
1533static NISTP521_PRE_COMP *nistp521_pre_comp_new()
1534 {
1535 NISTP521_PRE_COMP *ret = NULL;
1536 ret = (NISTP521_PRE_COMP *)OPENSSL_malloc(sizeof(NISTP521_PRE_COMP));
1537 if (!ret)
1538 {
1539 ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1540 return ret;
1541 }
1542 memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
1543 ret->references = 1;
1544 return ret;
1545 }
1546
1547static void *nistp521_pre_comp_dup(void *src_)
1548 {
1549 NISTP521_PRE_COMP *src = src_;
1550
1551 /* no need to actually copy, these objects never change! */
1552 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
1553
1554 return src_;
1555 }
1556
1557static void nistp521_pre_comp_free(void *pre_)
1558 {
1559 int i;
1560 NISTP521_PRE_COMP *pre = pre_;
1561
1562 if (!pre)
1563 return;
1564
1565 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1566 if (i > 0)
1567 return;
1568
1569 OPENSSL_free(pre);
1570 }
1571
1572static void nistp521_pre_comp_clear_free(void *pre_)
1573 {
1574 int i;
1575 NISTP521_PRE_COMP *pre = pre_;
1576
1577 if (!pre)
1578 return;
1579
1580 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
1581 if (i > 0)
1582 return;
1583
1584 OPENSSL_cleanse(pre, sizeof(*pre));
1585 OPENSSL_free(pre);
1586 }
1587
1588/******************************************************************************/
1589/* OPENSSL EC_METHOD FUNCTIONS
1590 */
1591
1592int ec_GFp_nistp521_group_init(EC_GROUP *group)
1593 {
1594 int ret;
1595 ret = ec_GFp_simple_group_init(group);
1596 group->a_is_minus3 = 1;
1597 return ret;
1598 }
1599
1600int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
1601 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1602 {
1603 int ret = 0;
1604 BN_CTX *new_ctx = NULL;
1605 BIGNUM *curve_p, *curve_a, *curve_b;
1606
1607 if (ctx == NULL)
1608 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1609 BN_CTX_start(ctx);
1610 if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
1611 ((curve_a = BN_CTX_get(ctx)) == NULL) ||
1612 ((curve_b = BN_CTX_get(ctx)) == NULL)) goto err;
1613 BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
1614 BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
1615 BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
1616 if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) ||
1617 (BN_cmp(curve_b, b)))
1618 {
1619 ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
1620 EC_R_WRONG_CURVE_PARAMETERS);
1621 goto err;
1622 }
1623 group->field_mod_func = BN_nist_mod_521;
1624 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
1625err:
1626 BN_CTX_end(ctx);
1627 if (new_ctx != NULL)
1628 BN_CTX_free(new_ctx);
1629 return ret;
1630 }
1631
1632/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
1633 * (X', Y') = (X/Z^2, Y/Z^3) */
1634int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
1635 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
1636 {
1637 felem z1, z2, x_in, y_in, x_out, y_out;
1638 largefelem tmp;
1639
1640 if (EC_POINT_is_at_infinity(group, point))
1641 {
1642 ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
1643 EC_R_POINT_AT_INFINITY);
1644 return 0;
1645 }
1646 if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
1647 (!BN_to_felem(z1, &point->Z))) return 0;
1648 felem_inv(z2, z1);
1649 felem_square(tmp, z2); felem_reduce(z1, tmp);
1650 felem_mul(tmp, x_in, z1); felem_reduce(x_in, tmp);
1651 felem_contract(x_out, x_in);
1652 if (x != NULL)
1653 {
1654 if (!felem_to_BN(x, x_out))
1655 {
1656 ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
1657 return 0;
1658 }
1659 }
1660 felem_mul(tmp, z1, z2); felem_reduce(z1, tmp);
1661 felem_mul(tmp, y_in, z1); felem_reduce(y_in, tmp);
1662 felem_contract(y_out, y_in);
1663 if (y != NULL)
1664 {
1665 if (!felem_to_BN(y, y_out))
1666 {
1667 ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
1668 return 0;
1669 }
1670 }
1671 return 1;
1672 }
1673
1674static void make_points_affine(size_t num, felem points[/* num */][3], felem tmp_felems[/* num+1 */])
1675 {
1676 /* Runs in constant time, unless an input is the point at infinity
1677 * (which normally shouldn't happen). */
1678 ec_GFp_nistp_points_make_affine_internal(
1679 num,
1680 points,
1681 sizeof(felem),
1682 tmp_felems,
1683 (void (*)(void *)) felem_one,
1684 (int (*)(const void *)) felem_is_zero_int,
1685 (void (*)(void *, const void *)) felem_assign,
1686 (void (*)(void *, const void *)) felem_square_reduce,
1687 (void (*)(void *, const void *, const void *)) felem_mul_reduce,
1688 (void (*)(void *, const void *)) felem_inv,
1689 (void (*)(void *, const void *)) felem_contract);
1690 }
1691
1692/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
1693 * Result is stored in r (r can equal one of the inputs). */
1694int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
1695 const BIGNUM *scalar, size_t num, const EC_POINT *points[],
1696 const BIGNUM *scalars[], BN_CTX *ctx)
1697 {
1698 int ret = 0;
1699 int j;
1700 int mixed = 0;
1701 BN_CTX *new_ctx = NULL;
1702 BIGNUM *x, *y, *z, *tmp_scalar;
1703 felem_bytearray g_secret;
1704 felem_bytearray *secrets = NULL;
1705 felem (*pre_comp)[17][3] = NULL;
1706 felem *tmp_felems = NULL;
1707 felem_bytearray tmp;
1708 unsigned i, num_bytes;
1709 int have_pre_comp = 0;
1710 size_t num_points = num;
1711 felem x_in, y_in, z_in, x_out, y_out, z_out;
1712 NISTP521_PRE_COMP *pre = NULL;
1713 felem (*g_pre_comp)[3] = NULL;
1714 EC_POINT *generator = NULL;
1715 const EC_POINT *p = NULL;
1716 const BIGNUM *p_scalar = NULL;
1717
1718 if (ctx == NULL)
1719 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1720 BN_CTX_start(ctx);
1721 if (((x = BN_CTX_get(ctx)) == NULL) ||
1722 ((y = BN_CTX_get(ctx)) == NULL) ||
1723 ((z = BN_CTX_get(ctx)) == NULL) ||
1724 ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
1725 goto err;
1726
1727 if (scalar != NULL)
1728 {
1729 pre = EC_EX_DATA_get_data(group->extra_data,
1730 nistp521_pre_comp_dup, nistp521_pre_comp_free,
1731 nistp521_pre_comp_clear_free);
1732 if (pre)
1733 /* we have precomputation, try to use it */
1734 g_pre_comp = &pre->g_pre_comp[0];
1735 else
1736 /* try to use the standard precomputation */
1737 g_pre_comp = (felem (*)[3]) gmul;
1738 generator = EC_POINT_new(group);
1739 if (generator == NULL)
1740 goto err;
1741 /* get the generator from precomputation */
1742 if (!felem_to_BN(x, g_pre_comp[1][0]) ||
1743 !felem_to_BN(y, g_pre_comp[1][1]) ||
1744 !felem_to_BN(z, g_pre_comp[1][2]))
1745 {
1746 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1747 goto err;
1748 }
1749 if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
1750 generator, x, y, z, ctx))
1751 goto err;
1752 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1753 /* precomputation matches generator */
1754 have_pre_comp = 1;
1755 else
1756 /* we don't have valid precomputation:
1757 * treat the generator as a random point */
1758 num_points++;
1759 }
1760
1761 if (num_points > 0)
1762 {
1763 if (num_points >= 2)
1764 {
1765 /* unless we precompute multiples for just one point,
1766 * converting those into affine form is time well spent */
1767 mixed = 1;
1768 }
1769 secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
1770 pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
1771 if (mixed)
1772 tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
1773 if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL)))
1774 {
1775 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1776 goto err;
1777 }
1778
1779 /* we treat NULL scalars as 0, and NULL points as points at infinity,
1780 * i.e., they contribute nothing to the linear combination */
1781 memset(secrets, 0, num_points * sizeof(felem_bytearray));
1782 memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
1783 for (i = 0; i < num_points; ++i)
1784 {
1785 if (i == num)
1786 /* we didn't have a valid precomputation, so we pick
1787 * the generator */
1788 {
1789 p = EC_GROUP_get0_generator(group);
1790 p_scalar = scalar;
1791 }
1792 else
1793 /* the i^th point */
1794 {
1795 p = points[i];
1796 p_scalar = scalars[i];
1797 }
1798 if ((p_scalar != NULL) && (p != NULL))
1799 {
1800 /* reduce scalar to 0 <= scalar < 2^521 */
1801 if ((BN_num_bits(p_scalar) > 521) || (BN_is_negative(p_scalar)))
1802 {
1803 /* this is an unusual input, and we don't guarantee
1804 * constant-timeness */
1805 if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx))
1806 {
1807 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1808 goto err;
1809 }
1810 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1811 }
1812 else
1813 num_bytes = BN_bn2bin(p_scalar, tmp);
1814 flip_endian(secrets[i], tmp, num_bytes);
1815 /* precompute multiples */
1816 if ((!BN_to_felem(x_out, &p->X)) ||
1817 (!BN_to_felem(y_out, &p->Y)) ||
1818 (!BN_to_felem(z_out, &p->Z))) goto err;
1819 memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
1820 memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
1821 memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
1822 for (j = 2; j <= 16; ++j)
1823 {
1824 if (j & 1)
1825 {
1826 point_add(
1827 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1828 pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
1829 0, pre_comp[i][j-1][0], pre_comp[i][j-1][1], pre_comp[i][j-1][2]);
1830 }
1831 else
1832 {
1833 point_double(
1834 pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
1835 pre_comp[i][j/2][0], pre_comp[i][j/2][1], pre_comp[i][j/2][2]);
1836 }
1837 }
1838 }
1839 }
1840 if (mixed)
1841 make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
1842 }
1843
1844 /* the scalar for the generator */
1845 if ((scalar != NULL) && (have_pre_comp))
1846 {
1847 memset(g_secret, 0, sizeof(g_secret));
1848 /* reduce scalar to 0 <= scalar < 2^521 */
1849 if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar)))
1850 {
1851 /* this is an unusual input, and we don't guarantee
1852 * constant-timeness */
1853 if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx))
1854 {
1855 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1856 goto err;
1857 }
1858 num_bytes = BN_bn2bin(tmp_scalar, tmp);
1859 }
1860 else
1861 num_bytes = BN_bn2bin(scalar, tmp);
1862 flip_endian(g_secret, tmp, num_bytes);
1863 /* do the multiplication with generator precomputation*/
1864 batch_mul(x_out, y_out, z_out,
1865 (const felem_bytearray (*)) secrets, num_points,
1866 g_secret,
1867 mixed, (const felem (*)[17][3]) pre_comp,
1868 (const felem (*)[3]) g_pre_comp);
1869 }
1870 else
1871 /* do the multiplication without generator precomputation */
1872 batch_mul(x_out, y_out, z_out,
1873 (const felem_bytearray (*)) secrets, num_points,
1874 NULL, mixed, (const felem (*)[17][3]) pre_comp, NULL);
1875 /* reduce the output to its unique minimal representation */
1876 felem_contract(x_in, x_out);
1877 felem_contract(y_in, y_out);
1878 felem_contract(z_in, z_out);
1879 if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
1880 (!felem_to_BN(z, z_in)))
1881 {
1882 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
1883 goto err;
1884 }
1885 ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
1886
1887err:
1888 BN_CTX_end(ctx);
1889 if (generator != NULL)
1890 EC_POINT_free(generator);
1891 if (new_ctx != NULL)
1892 BN_CTX_free(new_ctx);
1893 if (secrets != NULL)
1894 OPENSSL_free(secrets);
1895 if (pre_comp != NULL)
1896 OPENSSL_free(pre_comp);
1897 if (tmp_felems != NULL)
1898 OPENSSL_free(tmp_felems);
1899 return ret;
1900 }
1901
1902int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
1903 {
1904 int ret = 0;
1905 NISTP521_PRE_COMP *pre = NULL;
1906 int i, j;
1907 BN_CTX *new_ctx = NULL;
1908 BIGNUM *x, *y;
1909 EC_POINT *generator = NULL;
1910 felem tmp_felems[16];
1911
1912 /* throw away old precomputation */
1913 EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup,
1914 nistp521_pre_comp_free, nistp521_pre_comp_clear_free);
1915 if (ctx == NULL)
1916 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
1917 BN_CTX_start(ctx);
1918 if (((x = BN_CTX_get(ctx)) == NULL) ||
1919 ((y = BN_CTX_get(ctx)) == NULL))
1920 goto err;
1921 /* get the generator */
1922 if (group->generator == NULL) goto err;
1923 generator = EC_POINT_new(group);
1924 if (generator == NULL)
1925 goto err;
1926 BN_bin2bn(nistp521_curve_params[3], sizeof (felem_bytearray), x);
1927 BN_bin2bn(nistp521_curve_params[4], sizeof (felem_bytearray), y);
1928 if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
1929 goto err;
1930 if ((pre = nistp521_pre_comp_new()) == NULL)
1931 goto err;
1932 /* if the generator is the standard one, use built-in precomputation */
1933 if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
1934 {
1935 memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
1936 ret = 1;
1937 goto err;
1938 }
1939 if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) ||
1940 (!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) ||
1941 (!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z)))
1942 goto err;
1943 /* compute 2^130*G, 2^260*G, 2^390*G */
1944 for (i = 1; i <= 4; i <<= 1)
1945 {
1946 point_double(pre->g_pre_comp[2*i][0], pre->g_pre_comp[2*i][1],
1947 pre->g_pre_comp[2*i][2], pre->g_pre_comp[i][0],
1948 pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]);
1949 for (j = 0; j < 129; ++j)
1950 {
1951 point_double(pre->g_pre_comp[2*i][0],
1952 pre->g_pre_comp[2*i][1],
1953 pre->g_pre_comp[2*i][2],
1954 pre->g_pre_comp[2*i][0],
1955 pre->g_pre_comp[2*i][1],
1956 pre->g_pre_comp[2*i][2]);
1957 }
1958 }
1959 /* g_pre_comp[0] is the point at infinity */
1960 memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
1961 /* the remaining multiples */
1962 /* 2^130*G + 2^260*G */
1963 point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1],
1964 pre->g_pre_comp[6][2], pre->g_pre_comp[4][0],
1965 pre->g_pre_comp[4][1], pre->g_pre_comp[4][2],
1966 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
1967 pre->g_pre_comp[2][2]);
1968 /* 2^130*G + 2^390*G */
1969 point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1],
1970 pre->g_pre_comp[10][2], pre->g_pre_comp[8][0],
1971 pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
1972 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
1973 pre->g_pre_comp[2][2]);
1974 /* 2^260*G + 2^390*G */
1975 point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1],
1976 pre->g_pre_comp[12][2], pre->g_pre_comp[8][0],
1977 pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
1978 0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1],
1979 pre->g_pre_comp[4][2]);
1980 /* 2^130*G + 2^260*G + 2^390*G */
1981 point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1],
1982 pre->g_pre_comp[14][2], pre->g_pre_comp[12][0],
1983 pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
1984 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
1985 pre->g_pre_comp[2][2]);
1986 for (i = 1; i < 8; ++i)
1987 {
1988 /* odd multiples: add G */
1989 point_add(pre->g_pre_comp[2*i+1][0], pre->g_pre_comp[2*i+1][1],
1990 pre->g_pre_comp[2*i+1][2], pre->g_pre_comp[2*i][0],
1991 pre->g_pre_comp[2*i][1], pre->g_pre_comp[2*i][2],
1992 0, pre->g_pre_comp[1][0], pre->g_pre_comp[1][1],
1993 pre->g_pre_comp[1][2]);
1994 }
1995 make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
1996
1997 if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup,
1998 nistp521_pre_comp_free, nistp521_pre_comp_clear_free))
1999 goto err;
2000 ret = 1;
2001 pre = NULL;
2002 err:
2003 BN_CTX_end(ctx);
2004 if (generator != NULL)
2005 EC_POINT_free(generator);
2006 if (new_ctx != NULL)
2007 BN_CTX_free(new_ctx);
2008 if (pre)
2009 nistp521_pre_comp_free(pre);
2010 return ret;
2011 }
2012
2013int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
2014 {
2015 if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup,
2016 nistp521_pre_comp_free, nistp521_pre_comp_clear_free)
2017 != NULL)
2018 return 1;
2019 else
2020 return 0;
2021 }
2022
2023#else
2024static void *dummy=&dummy;
2025#endif
diff --git a/src/lib/libcrypto/ec/ecp_nistputil.c b/src/lib/libcrypto/ec/ecp_nistputil.c
deleted file mode 100644
index c8140c807f..0000000000
--- a/src/lib/libcrypto/ec/ecp_nistputil.c
+++ /dev/null
@@ -1,197 +0,0 @@
1/* crypto/ec/ecp_nistputil.c */
2/*
3 * Written by Bodo Moeller for the OpenSSL project.
4 */
5/* Copyright 2011 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 *
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include <openssl/opensslconf.h>
22#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
23
24/*
25 * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
26 */
27
28#include <stddef.h>
29#include "ec_lcl.h"
30
31/* Convert an array of points into affine coordinates.
32 * (If the point at infinity is found (Z = 0), it remains unchanged.)
33 * This function is essentially an equivalent to EC_POINTs_make_affine(), but
34 * works with the internal representation of points as used by ecp_nistp###.c
35 * rather than with (BIGNUM-based) EC_POINT data structures.
36 *
37 * point_array is the input/output buffer ('num' points in projective form,
38 * i.e. three coordinates each), based on an internal representation of
39 * field elements of size 'felem_size'.
40 *
41 * tmp_felems needs to point to a temporary array of 'num'+1 field elements
42 * for storage of intermediate values.
43 */
44void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
45 size_t felem_size, void *tmp_felems,
46 void (*felem_one)(void *out),
47 int (*felem_is_zero)(const void *in),
48 void (*felem_assign)(void *out, const void *in),
49 void (*felem_square)(void *out, const void *in),
50 void (*felem_mul)(void *out, const void *in1, const void *in2),
51 void (*felem_inv)(void *out, const void *in),
52 void (*felem_contract)(void *out, const void *in))
53 {
54 int i = 0;
55
56#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
57#define X(I) (&((char *)point_array)[3*(I) * felem_size])
58#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
59#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
60
61 if (!felem_is_zero(Z(0)))
62 felem_assign(tmp_felem(0), Z(0));
63 else
64 felem_one(tmp_felem(0));
65 for (i = 1; i < (int)num; i++)
66 {
67 if (!felem_is_zero(Z(i)))
68 felem_mul(tmp_felem(i), tmp_felem(i-1), Z(i));
69 else
70 felem_assign(tmp_felem(i), tmp_felem(i-1));
71 }
72 /* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any zero-valued factors:
73 * if Z(i) = 0, we essentially pretend that Z(i) = 1 */
74
75 felem_inv(tmp_felem(num-1), tmp_felem(num-1));
76 for (i = num - 1; i >= 0; i--)
77 {
78 if (i > 0)
79 /* tmp_felem(i-1) is the product of Z(0) .. Z(i-1),
80 * tmp_felem(i) is the inverse of the product of Z(0) .. Z(i)
81 */
82 felem_mul(tmp_felem(num), tmp_felem(i-1), tmp_felem(i)); /* 1/Z(i) */
83 else
84 felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
85
86 if (!felem_is_zero(Z(i)))
87 {
88 if (i > 0)
89 /* For next iteration, replace tmp_felem(i-1) by its inverse */
90 felem_mul(tmp_felem(i-1), tmp_felem(i), Z(i));
91
92 /* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) */
93 felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
94 felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
95 felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
96 felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
97 felem_contract(X(i), X(i));
98 felem_contract(Y(i), Y(i));
99 felem_one(Z(i));
100 }
101 else
102 {
103 if (i > 0)
104 /* For next iteration, replace tmp_felem(i-1) by its inverse */
105 felem_assign(tmp_felem(i-1), tmp_felem(i));
106 }
107 }
108 }
109
110/*
111 * This function looks at 5+1 scalar bits (5 current, 1 adjacent less
112 * significant bit), and recodes them into a signed digit for use in fast point
113 * multiplication: the use of signed rather than unsigned digits means that
114 * fewer points need to be precomputed, given that point inversion is easy
115 * (a precomputed point dP makes -dP available as well).
116 *
117 * BACKGROUND:
118 *
119 * Signed digits for multiplication were introduced by Booth ("A signed binary
120 * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
121 * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
122 * Booth's original encoding did not generally improve the density of nonzero
123 * digits over the binary representation, and was merely meant to simplify the
124 * handling of signed factors given in two's complement; but it has since been
125 * shown to be the basis of various signed-digit representations that do have
126 * further advantages, including the wNAF, using the following general approach:
127 *
128 * (1) Given a binary representation
129 *
130 * b_k ... b_2 b_1 b_0,
131 *
132 * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
133 * by using bit-wise subtraction as follows:
134 *
135 * b_k b_(k-1) ... b_2 b_1 b_0
136 * - b_k ... b_3 b_2 b_1 b_0
137 * -------------------------------------
138 * s_k b_(k-1) ... s_3 s_2 s_1 s_0
139 *
140 * A left-shift followed by subtraction of the original value yields a new
141 * representation of the same value, using signed bits s_i = b_(i+1) - b_i.
142 * This representation from Booth's paper has since appeared in the
143 * literature under a variety of different names including "reversed binary
144 * form", "alternating greedy expansion", "mutual opposite form", and
145 * "sign-alternating {+-1}-representation".
146 *
147 * An interesting property is that among the nonzero bits, values 1 and -1
148 * strictly alternate.
149 *
150 * (2) Various window schemes can be applied to the Booth representation of
151 * integers: for example, right-to-left sliding windows yield the wNAF
152 * (a signed-digit encoding independently discovered by various researchers
153 * in the 1990s), and left-to-right sliding windows yield a left-to-right
154 * equivalent of the wNAF (independently discovered by various researchers
155 * around 2004).
156 *
157 * To prevent leaking information through side channels in point multiplication,
158 * we need to recode the given integer into a regular pattern: sliding windows
159 * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
160 * decades older: we'll be using the so-called "modified Booth encoding" due to
161 * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
162 * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
163 * signed bits into a signed digit:
164 *
165 * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
166 *
167 * The sign-alternating property implies that the resulting digit values are
168 * integers from -16 to 16.
169 *
170 * Of course, we don't actually need to compute the signed digits s_i as an
171 * intermediate step (that's just a nice way to see how this scheme relates
172 * to the wNAF): a direct computation obtains the recoded digit from the
173 * six bits b_(4j + 4) ... b_(4j - 1).
174 *
175 * This function takes those five bits as an integer (0 .. 63), writing the
176 * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
177 * value, in the range 0 .. 8). Note that this integer essentially provides the
178 * input bits "shifted to the left" by one position: for example, the input to
179 * compute the least significant recoded digit, given that there's no bit b_-1,
180 * has to be b_4 b_3 b_2 b_1 b_0 0.
181 *
182 */
183void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in)
184 {
185 unsigned char s, d;
186
187 s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as 6-bit value */
188 d = (1 << 6) - in - 1;
189 d = (d & s) | (in & ~s);
190 d = (d >> 1) + (d & 1);
191
192 *sign = s & 1;
193 *digit = d;
194 }
195#else
196static void *dummy=&dummy;
197#endif
diff --git a/src/lib/libcrypto/ec/ecp_oct.c b/src/lib/libcrypto/ec/ecp_oct.c
deleted file mode 100644
index 374a0ee731..0000000000
--- a/src/lib/libcrypto/ec/ecp_oct.c
+++ /dev/null
@@ -1,433 +0,0 @@
1/* crypto/ec/ecp_oct.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
70int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
71 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
72 {
73 BN_CTX *new_ctx = NULL;
74 BIGNUM *tmp1, *tmp2, *x, *y;
75 int ret = 0;
76
77 /* clear error queue*/
78 ERR_clear_error();
79
80 if (ctx == NULL)
81 {
82 ctx = new_ctx = BN_CTX_new();
83 if (ctx == NULL)
84 return 0;
85 }
86
87 y_bit = (y_bit != 0);
88
89 BN_CTX_start(ctx);
90 tmp1 = BN_CTX_get(ctx);
91 tmp2 = BN_CTX_get(ctx);
92 x = BN_CTX_get(ctx);
93 y = BN_CTX_get(ctx);
94 if (y == NULL) goto err;
95
96 /* Recover y. We have a Weierstrass equation
97 * y^2 = x^3 + a*x + b,
98 * so y is one of the square roots of x^3 + a*x + b.
99 */
100
101 /* tmp1 := x^3 */
102 if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
103 if (group->meth->field_decode == 0)
104 {
105 /* field_{sqr,mul} work on standard representation */
106 if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
107 if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
108 }
109 else
110 {
111 if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
112 if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
113 }
114
115 /* tmp1 := tmp1 + a*x */
116 if (group->a_is_minus3)
117 {
118 if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
119 if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
120 if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
121 }
122 else
123 {
124 if (group->meth->field_decode)
125 {
126 if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
127 if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
128 }
129 else
130 {
131 /* field_mul works on standard representation */
132 if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
133 }
134
135 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
136 }
137
138 /* tmp1 := tmp1 + b */
139 if (group->meth->field_decode)
140 {
141 if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
142 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
143 }
144 else
145 {
146 if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
147 }
148
149 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
150 {
151 unsigned long err = ERR_peek_last_error();
152
153 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
154 {
155 ERR_clear_error();
156 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
157 }
158 else
159 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
160 goto err;
161 }
162
163 if (y_bit != BN_is_odd(y))
164 {
165 if (BN_is_zero(y))
166 {
167 int kron;
168
169 kron = BN_kronecker(x, &group->field, ctx);
170 if (kron == -2) goto err;
171
172 if (kron == 1)
173 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
174 else
175 /* BN_mod_sqrt() should have cought this error (not a square) */
176 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
177 goto err;
178 }
179 if (!BN_usub(y, &group->field, y)) goto err;
180 }
181 if (y_bit != BN_is_odd(y))
182 {
183 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
184 goto err;
185 }
186
187 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
188
189 ret = 1;
190
191 err:
192 BN_CTX_end(ctx);
193 if (new_ctx != NULL)
194 BN_CTX_free(new_ctx);
195 return ret;
196 }
197
198
199size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
200 unsigned char *buf, size_t len, BN_CTX *ctx)
201 {
202 size_t ret;
203 BN_CTX *new_ctx = NULL;
204 int used_ctx = 0;
205 BIGNUM *x, *y;
206 size_t field_len, i, skip;
207
208 if ((form != POINT_CONVERSION_COMPRESSED)
209 && (form != POINT_CONVERSION_UNCOMPRESSED)
210 && (form != POINT_CONVERSION_HYBRID))
211 {
212 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
213 goto err;
214 }
215
216 if (EC_POINT_is_at_infinity(group, point))
217 {
218 /* encodes to a single 0 octet */
219 if (buf != NULL)
220 {
221 if (len < 1)
222 {
223 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
224 return 0;
225 }
226 buf[0] = 0;
227 }
228 return 1;
229 }
230
231
232 /* ret := required output buffer length */
233 field_len = BN_num_bytes(&group->field);
234 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
235
236 /* if 'buf' is NULL, just return required length */
237 if (buf != NULL)
238 {
239 if (len < ret)
240 {
241 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
242 goto err;
243 }
244
245 if (ctx == NULL)
246 {
247 ctx = new_ctx = BN_CTX_new();
248 if (ctx == NULL)
249 return 0;
250 }
251
252 BN_CTX_start(ctx);
253 used_ctx = 1;
254 x = BN_CTX_get(ctx);
255 y = BN_CTX_get(ctx);
256 if (y == NULL) goto err;
257
258 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
259
260 if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
261 buf[0] = form + 1;
262 else
263 buf[0] = form;
264
265 i = 1;
266
267 skip = field_len - BN_num_bytes(x);
268 if (skip > field_len)
269 {
270 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
271 goto err;
272 }
273 while (skip > 0)
274 {
275 buf[i++] = 0;
276 skip--;
277 }
278 skip = BN_bn2bin(x, buf + i);
279 i += skip;
280 if (i != 1 + field_len)
281 {
282 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
283 goto err;
284 }
285
286 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
287 {
288 skip = field_len - BN_num_bytes(y);
289 if (skip > field_len)
290 {
291 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
292 goto err;
293 }
294 while (skip > 0)
295 {
296 buf[i++] = 0;
297 skip--;
298 }
299 skip = BN_bn2bin(y, buf + i);
300 i += skip;
301 }
302
303 if (i != ret)
304 {
305 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
306 goto err;
307 }
308 }
309
310 if (used_ctx)
311 BN_CTX_end(ctx);
312 if (new_ctx != NULL)
313 BN_CTX_free(new_ctx);
314 return ret;
315
316 err:
317 if (used_ctx)
318 BN_CTX_end(ctx);
319 if (new_ctx != NULL)
320 BN_CTX_free(new_ctx);
321 return 0;
322 }
323
324
325int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
326 const unsigned char *buf, size_t len, BN_CTX *ctx)
327 {
328 point_conversion_form_t form;
329 int y_bit;
330 BN_CTX *new_ctx = NULL;
331 BIGNUM *x, *y;
332 size_t field_len, enc_len;
333 int ret = 0;
334
335 if (len == 0)
336 {
337 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
338 return 0;
339 }
340 form = buf[0];
341 y_bit = form & 1;
342 form = form & ~1U;
343 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
344 && (form != POINT_CONVERSION_UNCOMPRESSED)
345 && (form != POINT_CONVERSION_HYBRID))
346 {
347 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
348 return 0;
349 }
350 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
351 {
352 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
353 return 0;
354 }
355
356 if (form == 0)
357 {
358 if (len != 1)
359 {
360 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
361 return 0;
362 }
363
364 return EC_POINT_set_to_infinity(group, point);
365 }
366
367 field_len = BN_num_bytes(&group->field);
368 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
369
370 if (len != enc_len)
371 {
372 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
373 return 0;
374 }
375
376 if (ctx == NULL)
377 {
378 ctx = new_ctx = BN_CTX_new();
379 if (ctx == NULL)
380 return 0;
381 }
382
383 BN_CTX_start(ctx);
384 x = BN_CTX_get(ctx);
385 y = BN_CTX_get(ctx);
386 if (y == NULL) goto err;
387
388 if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
389 if (BN_ucmp(x, &group->field) >= 0)
390 {
391 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
392 goto err;
393 }
394
395 if (form == POINT_CONVERSION_COMPRESSED)
396 {
397 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
398 }
399 else
400 {
401 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
402 if (BN_ucmp(y, &group->field) >= 0)
403 {
404 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
405 goto err;
406 }
407 if (form == POINT_CONVERSION_HYBRID)
408 {
409 if (y_bit != BN_is_odd(y))
410 {
411 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
412 goto err;
413 }
414 }
415
416 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
417 }
418
419 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
420 {
421 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
422 goto err;
423 }
424
425 ret = 1;
426
427 err:
428 BN_CTX_end(ctx);
429 if (new_ctx != NULL)
430 BN_CTX_free(new_ctx);
431 return ret;
432 }
433
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c
deleted file mode 100644
index 7cbb321f9a..0000000000
--- a/src/lib/libcrypto/ec/ecp_smpl.c
+++ /dev/null
@@ -1,1360 +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#ifdef OPENSSL_FIPS
69#include <openssl/fips.h>
70#endif
71
72#include "ec_lcl.h"
73
74const EC_METHOD *EC_GFp_simple_method(void)
75 {
76#ifdef OPENSSL_FIPS
77 return fips_ec_gfp_simple_method();
78#else
79 static const EC_METHOD ret = {
80 EC_FLAGS_DEFAULT_OCT,
81 NID_X9_62_prime_field,
82 ec_GFp_simple_group_init,
83 ec_GFp_simple_group_finish,
84 ec_GFp_simple_group_clear_finish,
85 ec_GFp_simple_group_copy,
86 ec_GFp_simple_group_set_curve,
87 ec_GFp_simple_group_get_curve,
88 ec_GFp_simple_group_get_degree,
89 ec_GFp_simple_group_check_discriminant,
90 ec_GFp_simple_point_init,
91 ec_GFp_simple_point_finish,
92 ec_GFp_simple_point_clear_finish,
93 ec_GFp_simple_point_copy,
94 ec_GFp_simple_point_set_to_infinity,
95 ec_GFp_simple_set_Jprojective_coordinates_GFp,
96 ec_GFp_simple_get_Jprojective_coordinates_GFp,
97 ec_GFp_simple_point_set_affine_coordinates,
98 ec_GFp_simple_point_get_affine_coordinates,
99 0,0,0,
100 ec_GFp_simple_add,
101 ec_GFp_simple_dbl,
102 ec_GFp_simple_invert,
103 ec_GFp_simple_is_at_infinity,
104 ec_GFp_simple_is_on_curve,
105 ec_GFp_simple_cmp,
106 ec_GFp_simple_make_affine,
107 ec_GFp_simple_points_make_affine,
108 0 /* mul */,
109 0 /* precompute_mult */,
110 0 /* have_precompute_mult */,
111 ec_GFp_simple_field_mul,
112 ec_GFp_simple_field_sqr,
113 0 /* field_div */,
114 0 /* field_encode */,
115 0 /* field_decode */,
116 0 /* field_set_to_one */ };
117
118 return &ret;
119#endif
120 }
121
122
123/* Most method functions in this file are designed to work with
124 * non-trivial representations of field elements if necessary
125 * (see ecp_mont.c): while standard modular addition and subtraction
126 * are used, the field_mul and field_sqr methods will be used for
127 * multiplication, and field_encode and field_decode (if defined)
128 * will be used for converting between representations.
129
130 * Functions ec_GFp_simple_points_make_affine() and
131 * ec_GFp_simple_point_get_affine_coordinates() specifically assume
132 * that if a non-trivial representation is used, it is a Montgomery
133 * representation (i.e. 'encoding' means multiplying by some factor R).
134 */
135
136
137int ec_GFp_simple_group_init(EC_GROUP *group)
138 {
139 BN_init(&group->field);
140 BN_init(&group->a);
141 BN_init(&group->b);
142 group->a_is_minus3 = 0;
143 return 1;
144 }
145
146
147void ec_GFp_simple_group_finish(EC_GROUP *group)
148 {
149 BN_free(&group->field);
150 BN_free(&group->a);
151 BN_free(&group->b);
152 }
153
154
155void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
156 {
157 BN_clear_free(&group->field);
158 BN_clear_free(&group->a);
159 BN_clear_free(&group->b);
160 }
161
162
163int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
164 {
165 if (!BN_copy(&dest->field, &src->field)) return 0;
166 if (!BN_copy(&dest->a, &src->a)) return 0;
167 if (!BN_copy(&dest->b, &src->b)) return 0;
168
169 dest->a_is_minus3 = src->a_is_minus3;
170
171 return 1;
172 }
173
174
175int ec_GFp_simple_group_set_curve(EC_GROUP *group,
176 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
177 {
178 int ret = 0;
179 BN_CTX *new_ctx = NULL;
180 BIGNUM *tmp_a;
181
182 /* p must be a prime > 3 */
183 if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
184 {
185 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
186 return 0;
187 }
188
189 if (ctx == NULL)
190 {
191 ctx = new_ctx = BN_CTX_new();
192 if (ctx == NULL)
193 return 0;
194 }
195
196 BN_CTX_start(ctx);
197 tmp_a = BN_CTX_get(ctx);
198 if (tmp_a == NULL) goto err;
199
200 /* group->field */
201 if (!BN_copy(&group->field, p)) goto err;
202 BN_set_negative(&group->field, 0);
203
204 /* group->a */
205 if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
206 if (group->meth->field_encode)
207 { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; }
208 else
209 if (!BN_copy(&group->a, tmp_a)) goto err;
210
211 /* group->b */
212 if (!BN_nnmod(&group->b, b, p, ctx)) goto err;
213 if (group->meth->field_encode)
214 if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err;
215
216 /* group->a_is_minus3 */
217 if (!BN_add_word(tmp_a, 3)) goto err;
218 group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
219
220 ret = 1;
221
222 err:
223 BN_CTX_end(ctx);
224 if (new_ctx != NULL)
225 BN_CTX_free(new_ctx);
226 return ret;
227 }
228
229
230int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
231 {
232 int ret = 0;
233 BN_CTX *new_ctx = NULL;
234
235 if (p != NULL)
236 {
237 if (!BN_copy(p, &group->field)) return 0;
238 }
239
240 if (a != NULL || b != NULL)
241 {
242 if (group->meth->field_decode)
243 {
244 if (ctx == NULL)
245 {
246 ctx = new_ctx = BN_CTX_new();
247 if (ctx == NULL)
248 return 0;
249 }
250 if (a != NULL)
251 {
252 if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
253 }
254 if (b != NULL)
255 {
256 if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
257 }
258 }
259 else
260 {
261 if (a != NULL)
262 {
263 if (!BN_copy(a, &group->a)) goto err;
264 }
265 if (b != NULL)
266 {
267 if (!BN_copy(b, &group->b)) goto err;
268 }
269 }
270 }
271
272 ret = 1;
273
274 err:
275 if (new_ctx)
276 BN_CTX_free(new_ctx);
277 return ret;
278 }
279
280
281int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
282 {
283 return BN_num_bits(&group->field);
284 }
285
286
287int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
288 {
289 int ret = 0;
290 BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
291 const BIGNUM *p = &group->field;
292 BN_CTX *new_ctx = NULL;
293
294 if (ctx == NULL)
295 {
296 ctx = new_ctx = BN_CTX_new();
297 if (ctx == NULL)
298 {
299 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
300 goto err;
301 }
302 }
303 BN_CTX_start(ctx);
304 a = BN_CTX_get(ctx);
305 b = BN_CTX_get(ctx);
306 tmp_1 = BN_CTX_get(ctx);
307 tmp_2 = BN_CTX_get(ctx);
308 order = BN_CTX_get(ctx);
309 if (order == NULL) goto err;
310
311 if (group->meth->field_decode)
312 {
313 if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
314 if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
315 }
316 else
317 {
318 if (!BN_copy(a, &group->a)) goto err;
319 if (!BN_copy(b, &group->b)) goto err;
320 }
321
322 /* check the discriminant:
323 * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
324 * 0 =< a, b < p */
325 if (BN_is_zero(a))
326 {
327 if (BN_is_zero(b)) goto err;
328 }
329 else if (!BN_is_zero(b))
330 {
331 if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
332 if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
333 if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
334 /* tmp_1 = 4*a^3 */
335
336 if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
337 if (!BN_mul_word(tmp_2, 27)) goto err;
338 /* tmp_2 = 27*b^2 */
339
340 if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
341 if (BN_is_zero(a)) goto err;
342 }
343 ret = 1;
344
345err:
346 if (ctx != NULL)
347 BN_CTX_end(ctx);
348 if (new_ctx != NULL)
349 BN_CTX_free(new_ctx);
350 return ret;
351 }
352
353
354int ec_GFp_simple_point_init(EC_POINT *point)
355 {
356 BN_init(&point->X);
357 BN_init(&point->Y);
358 BN_init(&point->Z);
359 point->Z_is_one = 0;
360
361 return 1;
362 }
363
364
365void ec_GFp_simple_point_finish(EC_POINT *point)
366 {
367 BN_free(&point->X);
368 BN_free(&point->Y);
369 BN_free(&point->Z);
370 }
371
372
373void ec_GFp_simple_point_clear_finish(EC_POINT *point)
374 {
375 BN_clear_free(&point->X);
376 BN_clear_free(&point->Y);
377 BN_clear_free(&point->Z);
378 point->Z_is_one = 0;
379 }
380
381
382int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
383 {
384 if (!BN_copy(&dest->X, &src->X)) return 0;
385 if (!BN_copy(&dest->Y, &src->Y)) return 0;
386 if (!BN_copy(&dest->Z, &src->Z)) return 0;
387 dest->Z_is_one = src->Z_is_one;
388
389 return 1;
390 }
391
392
393int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
394 {
395 point->Z_is_one = 0;
396 BN_zero(&point->Z);
397 return 1;
398 }
399
400
401int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
402 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
403 {
404 BN_CTX *new_ctx = NULL;
405 int ret = 0;
406
407 if (ctx == NULL)
408 {
409 ctx = new_ctx = BN_CTX_new();
410 if (ctx == NULL)
411 return 0;
412 }
413
414 if (x != NULL)
415 {
416 if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err;
417 if (group->meth->field_encode)
418 {
419 if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err;
420 }
421 }
422
423 if (y != NULL)
424 {
425 if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err;
426 if (group->meth->field_encode)
427 {
428 if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err;
429 }
430 }
431
432 if (z != NULL)
433 {
434 int Z_is_one;
435
436 if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err;
437 Z_is_one = BN_is_one(&point->Z);
438 if (group->meth->field_encode)
439 {
440 if (Z_is_one && (group->meth->field_set_to_one != 0))
441 {
442 if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err;
443 }
444 else
445 {
446 if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err;
447 }
448 }
449 point->Z_is_one = Z_is_one;
450 }
451
452 ret = 1;
453
454 err:
455 if (new_ctx != NULL)
456 BN_CTX_free(new_ctx);
457 return ret;
458 }
459
460
461int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
462 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
463 {
464 BN_CTX *new_ctx = NULL;
465 int ret = 0;
466
467 if (group->meth->field_decode != 0)
468 {
469 if (ctx == NULL)
470 {
471 ctx = new_ctx = BN_CTX_new();
472 if (ctx == NULL)
473 return 0;
474 }
475
476 if (x != NULL)
477 {
478 if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
479 }
480 if (y != NULL)
481 {
482 if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
483 }
484 if (z != NULL)
485 {
486 if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err;
487 }
488 }
489 else
490 {
491 if (x != NULL)
492 {
493 if (!BN_copy(x, &point->X)) goto err;
494 }
495 if (y != NULL)
496 {
497 if (!BN_copy(y, &point->Y)) goto err;
498 }
499 if (z != NULL)
500 {
501 if (!BN_copy(z, &point->Z)) goto err;
502 }
503 }
504
505 ret = 1;
506
507 err:
508 if (new_ctx != NULL)
509 BN_CTX_free(new_ctx);
510 return ret;
511 }
512
513
514int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
515 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
516 {
517 if (x == NULL || y == NULL)
518 {
519 /* unlike for projective coordinates, we do not tolerate this */
520 ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
521 return 0;
522 }
523
524 return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
525 }
526
527
528int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
529 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
530 {
531 BN_CTX *new_ctx = NULL;
532 BIGNUM *Z, *Z_1, *Z_2, *Z_3;
533 const BIGNUM *Z_;
534 int ret = 0;
535
536 if (EC_POINT_is_at_infinity(group, point))
537 {
538 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
539 return 0;
540 }
541
542 if (ctx == NULL)
543 {
544 ctx = new_ctx = BN_CTX_new();
545 if (ctx == NULL)
546 return 0;
547 }
548
549 BN_CTX_start(ctx);
550 Z = BN_CTX_get(ctx);
551 Z_1 = BN_CTX_get(ctx);
552 Z_2 = BN_CTX_get(ctx);
553 Z_3 = BN_CTX_get(ctx);
554 if (Z_3 == NULL) goto err;
555
556 /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
557
558 if (group->meth->field_decode)
559 {
560 if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
561 Z_ = Z;
562 }
563 else
564 {
565 Z_ = &point->Z;
566 }
567
568 if (BN_is_one(Z_))
569 {
570 if (group->meth->field_decode)
571 {
572 if (x != NULL)
573 {
574 if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
575 }
576 if (y != NULL)
577 {
578 if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
579 }
580 }
581 else
582 {
583 if (x != NULL)
584 {
585 if (!BN_copy(x, &point->X)) goto err;
586 }
587 if (y != NULL)
588 {
589 if (!BN_copy(y, &point->Y)) goto err;
590 }
591 }
592 }
593 else
594 {
595 if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
596 {
597 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
598 goto err;
599 }
600
601 if (group->meth->field_encode == 0)
602 {
603 /* field_sqr works on standard representation */
604 if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;
605 }
606 else
607 {
608 if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;
609 }
610
611 if (x != NULL)
612 {
613 /* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */
614 if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;
615 }
616
617 if (y != NULL)
618 {
619 if (group->meth->field_encode == 0)
620 {
621 /* field_mul works on standard representation */
622 if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
623 }
624 else
625 {
626 if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
627 }
628
629 /* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
630 if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
631 }
632 }
633
634 ret = 1;
635
636 err:
637 BN_CTX_end(ctx);
638 if (new_ctx != NULL)
639 BN_CTX_free(new_ctx);
640 return ret;
641 }
642
643int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
644 {
645 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
646 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
647 const BIGNUM *p;
648 BN_CTX *new_ctx = NULL;
649 BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
650 int ret = 0;
651
652 if (a == b)
653 return EC_POINT_dbl(group, r, a, ctx);
654 if (EC_POINT_is_at_infinity(group, a))
655 return EC_POINT_copy(r, b);
656 if (EC_POINT_is_at_infinity(group, b))
657 return EC_POINT_copy(r, a);
658
659 field_mul = group->meth->field_mul;
660 field_sqr = group->meth->field_sqr;
661 p = &group->field;
662
663 if (ctx == NULL)
664 {
665 ctx = new_ctx = BN_CTX_new();
666 if (ctx == NULL)
667 return 0;
668 }
669
670 BN_CTX_start(ctx);
671 n0 = BN_CTX_get(ctx);
672 n1 = BN_CTX_get(ctx);
673 n2 = BN_CTX_get(ctx);
674 n3 = BN_CTX_get(ctx);
675 n4 = BN_CTX_get(ctx);
676 n5 = BN_CTX_get(ctx);
677 n6 = BN_CTX_get(ctx);
678 if (n6 == NULL) goto end;
679
680 /* Note that in this function we must not read components of 'a' or 'b'
681 * once we have written the corresponding components of 'r'.
682 * ('r' might be one of 'a' or 'b'.)
683 */
684
685 /* n1, n2 */
686 if (b->Z_is_one)
687 {
688 if (!BN_copy(n1, &a->X)) goto end;
689 if (!BN_copy(n2, &a->Y)) goto end;
690 /* n1 = X_a */
691 /* n2 = Y_a */
692 }
693 else
694 {
695 if (!field_sqr(group, n0, &b->Z, ctx)) goto end;
696 if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;
697 /* n1 = X_a * Z_b^2 */
698
699 if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;
700 if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;
701 /* n2 = Y_a * Z_b^3 */
702 }
703
704 /* n3, n4 */
705 if (a->Z_is_one)
706 {
707 if (!BN_copy(n3, &b->X)) goto end;
708 if (!BN_copy(n4, &b->Y)) goto end;
709 /* n3 = X_b */
710 /* n4 = Y_b */
711 }
712 else
713 {
714 if (!field_sqr(group, n0, &a->Z, ctx)) goto end;
715 if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;
716 /* n3 = X_b * Z_a^2 */
717
718 if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;
719 if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;
720 /* n4 = Y_b * Z_a^3 */
721 }
722
723 /* n5, n6 */
724 if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;
725 if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;
726 /* n5 = n1 - n3 */
727 /* n6 = n2 - n4 */
728
729 if (BN_is_zero(n5))
730 {
731 if (BN_is_zero(n6))
732 {
733 /* a is the same point as b */
734 BN_CTX_end(ctx);
735 ret = EC_POINT_dbl(group, r, a, ctx);
736 ctx = NULL;
737 goto end;
738 }
739 else
740 {
741 /* a is the inverse of b */
742 BN_zero(&r->Z);
743 r->Z_is_one = 0;
744 ret = 1;
745 goto end;
746 }
747 }
748
749 /* 'n7', 'n8' */
750 if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;
751 if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;
752 /* 'n7' = n1 + n3 */
753 /* 'n8' = n2 + n4 */
754
755 /* Z_r */
756 if (a->Z_is_one && b->Z_is_one)
757 {
758 if (!BN_copy(&r->Z, n5)) goto end;
759 }
760 else
761 {
762 if (a->Z_is_one)
763 { if (!BN_copy(n0, &b->Z)) goto end; }
764 else if (b->Z_is_one)
765 { if (!BN_copy(n0, &a->Z)) goto end; }
766 else
767 { if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }
768 if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;
769 }
770 r->Z_is_one = 0;
771 /* Z_r = Z_a * Z_b * n5 */
772
773 /* X_r */
774 if (!field_sqr(group, n0, n6, ctx)) goto end;
775 if (!field_sqr(group, n4, n5, ctx)) goto end;
776 if (!field_mul(group, n3, n1, n4, ctx)) goto end;
777 if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;
778 /* X_r = n6^2 - n5^2 * 'n7' */
779
780 /* 'n9' */
781 if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;
782 if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;
783 /* n9 = n5^2 * 'n7' - 2 * X_r */
784
785 /* Y_r */
786 if (!field_mul(group, n0, n0, n6, ctx)) goto end;
787 if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */
788 if (!field_mul(group, n1, n2, n5, ctx)) goto end;
789 if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;
790 if (BN_is_odd(n0))
791 if (!BN_add(n0, n0, p)) goto end;
792 /* now 0 <= n0 < 2*p, and n0 is even */
793 if (!BN_rshift1(&r->Y, n0)) goto end;
794 /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
795
796 ret = 1;
797
798 end:
799 if (ctx) /* otherwise we already called BN_CTX_end */
800 BN_CTX_end(ctx);
801 if (new_ctx != NULL)
802 BN_CTX_free(new_ctx);
803 return ret;
804 }
805
806
807int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
808 {
809 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
810 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
811 const BIGNUM *p;
812 BN_CTX *new_ctx = NULL;
813 BIGNUM *n0, *n1, *n2, *n3;
814 int ret = 0;
815
816 if (EC_POINT_is_at_infinity(group, a))
817 {
818 BN_zero(&r->Z);
819 r->Z_is_one = 0;
820 return 1;
821 }
822
823 field_mul = group->meth->field_mul;
824 field_sqr = group->meth->field_sqr;
825 p = &group->field;
826
827 if (ctx == NULL)
828 {
829 ctx = new_ctx = BN_CTX_new();
830 if (ctx == NULL)
831 return 0;
832 }
833
834 BN_CTX_start(ctx);
835 n0 = BN_CTX_get(ctx);
836 n1 = BN_CTX_get(ctx);
837 n2 = BN_CTX_get(ctx);
838 n3 = BN_CTX_get(ctx);
839 if (n3 == NULL) goto err;
840
841 /* Note that in this function we must not read components of 'a'
842 * once we have written the corresponding components of 'r'.
843 * ('r' might the same as 'a'.)
844 */
845
846 /* n1 */
847 if (a->Z_is_one)
848 {
849 if (!field_sqr(group, n0, &a->X, ctx)) goto err;
850 if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
851 if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
852 if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;
853 /* n1 = 3 * X_a^2 + a_curve */
854 }
855 else if (group->a_is_minus3)
856 {
857 if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
858 if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;
859 if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;
860 if (!field_mul(group, n1, n0, n2, ctx)) goto err;
861 if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;
862 if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;
863 /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
864 * = 3 * X_a^2 - 3 * Z_a^4 */
865 }
866 else
867 {
868 if (!field_sqr(group, n0, &a->X, ctx)) goto err;
869 if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
870 if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
871 if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
872 if (!field_sqr(group, n1, n1, ctx)) goto err;
873 if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;
874 if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;
875 /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
876 }
877
878 /* Z_r */
879 if (a->Z_is_one)
880 {
881 if (!BN_copy(n0, &a->Y)) goto err;
882 }
883 else
884 {
885 if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;
886 }
887 if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;
888 r->Z_is_one = 0;
889 /* Z_r = 2 * Y_a * Z_a */
890
891 /* n2 */
892 if (!field_sqr(group, n3, &a->Y, ctx)) goto err;
893 if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;
894 if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;
895 /* n2 = 4 * X_a * Y_a^2 */
896
897 /* X_r */
898 if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;
899 if (!field_sqr(group, &r->X, n1, ctx)) goto err;
900 if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;
901 /* X_r = n1^2 - 2 * n2 */
902
903 /* n3 */
904 if (!field_sqr(group, n0, n3, ctx)) goto err;
905 if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;
906 /* n3 = 8 * Y_a^4 */
907
908 /* Y_r */
909 if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;
910 if (!field_mul(group, n0, n1, n0, ctx)) goto err;
911 if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;
912 /* Y_r = n1 * (n2 - X_r) - n3 */
913
914 ret = 1;
915
916 err:
917 BN_CTX_end(ctx);
918 if (new_ctx != NULL)
919 BN_CTX_free(new_ctx);
920 return ret;
921 }
922
923
924int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
925 {
926 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
927 /* point is its own inverse */
928 return 1;
929
930 return BN_usub(&point->Y, &group->field, &point->Y);
931 }
932
933
934int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
935 {
936 return BN_is_zero(&point->Z);
937 }
938
939
940int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
941 {
942 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
943 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
944 const BIGNUM *p;
945 BN_CTX *new_ctx = NULL;
946 BIGNUM *rh, *tmp, *Z4, *Z6;
947 int ret = -1;
948
949 if (EC_POINT_is_at_infinity(group, point))
950 return 1;
951
952 field_mul = group->meth->field_mul;
953 field_sqr = group->meth->field_sqr;
954 p = &group->field;
955
956 if (ctx == NULL)
957 {
958 ctx = new_ctx = BN_CTX_new();
959 if (ctx == NULL)
960 return -1;
961 }
962
963 BN_CTX_start(ctx);
964 rh = BN_CTX_get(ctx);
965 tmp = BN_CTX_get(ctx);
966 Z4 = BN_CTX_get(ctx);
967 Z6 = BN_CTX_get(ctx);
968 if (Z6 == NULL) goto err;
969
970 /* We have a curve defined by a Weierstrass equation
971 * y^2 = x^3 + a*x + b.
972 * The point to consider is given in Jacobian projective coordinates
973 * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
974 * Substituting this and multiplying by Z^6 transforms the above equation into
975 * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
976 * To test this, we add up the right-hand side in 'rh'.
977 */
978
979 /* rh := X^2 */
980 if (!field_sqr(group, rh, &point->X, ctx)) goto err;
981
982 if (!point->Z_is_one)
983 {
984 if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
985 if (!field_sqr(group, Z4, tmp, ctx)) goto err;
986 if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
987
988 /* rh := (rh + a*Z^4)*X */
989 if (group->a_is_minus3)
990 {
991 if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
992 if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
993 if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
994 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
995 }
996 else
997 {
998 if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
999 if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
1000 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1001 }
1002
1003 /* rh := rh + b*Z^6 */
1004 if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
1005 if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
1006 }
1007 else
1008 {
1009 /* point->Z_is_one */
1010
1011 /* rh := (rh + a)*X */
1012 if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
1013 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1014 /* rh := rh + b */
1015 if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
1016 }
1017
1018 /* 'lh' := Y^2 */
1019 if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
1020
1021 ret = (0 == BN_ucmp(tmp, rh));
1022
1023 err:
1024 BN_CTX_end(ctx);
1025 if (new_ctx != NULL)
1026 BN_CTX_free(new_ctx);
1027 return ret;
1028 }
1029
1030
1031int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
1032 {
1033 /* return values:
1034 * -1 error
1035 * 0 equal (in affine coordinates)
1036 * 1 not equal
1037 */
1038
1039 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1040 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1041 BN_CTX *new_ctx = NULL;
1042 BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
1043 const BIGNUM *tmp1_, *tmp2_;
1044 int ret = -1;
1045
1046 if (EC_POINT_is_at_infinity(group, a))
1047 {
1048 return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
1049 }
1050
1051 if (EC_POINT_is_at_infinity(group, b))
1052 return 1;
1053
1054 if (a->Z_is_one && b->Z_is_one)
1055 {
1056 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
1057 }
1058
1059 field_mul = group->meth->field_mul;
1060 field_sqr = group->meth->field_sqr;
1061
1062 if (ctx == NULL)
1063 {
1064 ctx = new_ctx = BN_CTX_new();
1065 if (ctx == NULL)
1066 return -1;
1067 }
1068
1069 BN_CTX_start(ctx);
1070 tmp1 = BN_CTX_get(ctx);
1071 tmp2 = BN_CTX_get(ctx);
1072 Za23 = BN_CTX_get(ctx);
1073 Zb23 = BN_CTX_get(ctx);
1074 if (Zb23 == NULL) goto end;
1075
1076 /* We have to decide whether
1077 * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
1078 * or equivalently, whether
1079 * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
1080 */
1081
1082 if (!b->Z_is_one)
1083 {
1084 if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;
1085 if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;
1086 tmp1_ = tmp1;
1087 }
1088 else
1089 tmp1_ = &a->X;
1090 if (!a->Z_is_one)
1091 {
1092 if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;
1093 if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;
1094 tmp2_ = tmp2;
1095 }
1096 else
1097 tmp2_ = &b->X;
1098
1099 /* compare X_a*Z_b^2 with X_b*Z_a^2 */
1100 if (BN_cmp(tmp1_, tmp2_) != 0)
1101 {
1102 ret = 1; /* points differ */
1103 goto end;
1104 }
1105
1106
1107 if (!b->Z_is_one)
1108 {
1109 if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;
1110 if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;
1111 /* tmp1_ = tmp1 */
1112 }
1113 else
1114 tmp1_ = &a->Y;
1115 if (!a->Z_is_one)
1116 {
1117 if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;
1118 if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;
1119 /* tmp2_ = tmp2 */
1120 }
1121 else
1122 tmp2_ = &b->Y;
1123
1124 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
1125 if (BN_cmp(tmp1_, tmp2_) != 0)
1126 {
1127 ret = 1; /* points differ */
1128 goto end;
1129 }
1130
1131 /* points are equal */
1132 ret = 0;
1133
1134 end:
1135 BN_CTX_end(ctx);
1136 if (new_ctx != NULL)
1137 BN_CTX_free(new_ctx);
1138 return ret;
1139 }
1140
1141
1142int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1143 {
1144 BN_CTX *new_ctx = NULL;
1145 BIGNUM *x, *y;
1146 int ret = 0;
1147
1148 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
1149 return 1;
1150
1151 if (ctx == NULL)
1152 {
1153 ctx = new_ctx = BN_CTX_new();
1154 if (ctx == NULL)
1155 return 0;
1156 }
1157
1158 BN_CTX_start(ctx);
1159 x = BN_CTX_get(ctx);
1160 y = BN_CTX_get(ctx);
1161 if (y == NULL) goto err;
1162
1163 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
1164 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
1165 if (!point->Z_is_one)
1166 {
1167 ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
1168 goto err;
1169 }
1170
1171 ret = 1;
1172
1173 err:
1174 BN_CTX_end(ctx);
1175 if (new_ctx != NULL)
1176 BN_CTX_free(new_ctx);
1177 return ret;
1178 }
1179
1180
1181int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1182 {
1183 BN_CTX *new_ctx = NULL;
1184 BIGNUM *tmp0, *tmp1;
1185 size_t pow2 = 0;
1186 BIGNUM **heap = NULL;
1187 size_t i;
1188 int ret = 0;
1189
1190 if (num == 0)
1191 return 1;
1192
1193 if (ctx == NULL)
1194 {
1195 ctx = new_ctx = BN_CTX_new();
1196 if (ctx == NULL)
1197 return 0;
1198 }
1199
1200 BN_CTX_start(ctx);
1201 tmp0 = BN_CTX_get(ctx);
1202 tmp1 = BN_CTX_get(ctx);
1203 if (tmp0 == NULL || tmp1 == NULL) goto err;
1204
1205 /* Before converting the individual points, compute inverses of all Z values.
1206 * Modular inversion is rather slow, but luckily we can do with a single
1207 * explicit inversion, plus about 3 multiplications per input value.
1208 */
1209
1210 pow2 = 1;
1211 while (num > pow2)
1212 pow2 <<= 1;
1213 /* Now pow2 is the smallest power of 2 satifsying pow2 >= num.
1214 * We need twice that. */
1215 pow2 <<= 1;
1216
1217 heap = OPENSSL_malloc(pow2 * sizeof heap[0]);
1218 if (heap == NULL) goto err;
1219
1220 /* The array is used as a binary tree, exactly as in heapsort:
1221 *
1222 * heap[1]
1223 * heap[2] heap[3]
1224 * heap[4] heap[5] heap[6] heap[7]
1225 * heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]
1226 *
1227 * We put the Z's in the last line;
1228 * then we set each other node to the product of its two child-nodes (where
1229 * empty or 0 entries are treated as ones);
1230 * then we invert heap[1];
1231 * then we invert each other node by replacing it by the product of its
1232 * parent (after inversion) and its sibling (before inversion).
1233 */
1234 heap[0] = NULL;
1235 for (i = pow2/2 - 1; i > 0; i--)
1236 heap[i] = NULL;
1237 for (i = 0; i < num; i++)
1238 heap[pow2/2 + i] = &points[i]->Z;
1239 for (i = pow2/2 + num; i < pow2; i++)
1240 heap[i] = NULL;
1241
1242 /* set each node to the product of its children */
1243 for (i = pow2/2 - 1; i > 0; i--)
1244 {
1245 heap[i] = BN_new();
1246 if (heap[i] == NULL) goto err;
1247
1248 if (heap[2*i] != NULL)
1249 {
1250 if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))
1251 {
1252 if (!BN_copy(heap[i], heap[2*i])) goto err;
1253 }
1254 else
1255 {
1256 if (BN_is_zero(heap[2*i]))
1257 {
1258 if (!BN_copy(heap[i], heap[2*i + 1])) goto err;
1259 }
1260 else
1261 {
1262 if (!group->meth->field_mul(group, heap[i],
1263 heap[2*i], heap[2*i + 1], ctx)) goto err;
1264 }
1265 }
1266 }
1267 }
1268
1269 /* invert heap[1] */
1270 if (!BN_is_zero(heap[1]))
1271 {
1272 if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))
1273 {
1274 ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
1275 goto err;
1276 }
1277 }
1278 if (group->meth->field_encode != 0)
1279 {
1280 /* in the Montgomery case, we just turned R*H (representing H)
1281 * into 1/(R*H), but we need R*(1/H) (representing 1/H);
1282 * i.e. we have need to multiply by the Montgomery factor twice */
1283 if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
1284 if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
1285 }
1286
1287 /* set other heap[i]'s to their inverses */
1288 for (i = 2; i < pow2/2 + num; i += 2)
1289 {
1290 /* i is even */
1291 if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))
1292 {
1293 if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;
1294 if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;
1295 if (!BN_copy(heap[i], tmp0)) goto err;
1296 if (!BN_copy(heap[i + 1], tmp1)) goto err;
1297 }
1298 else
1299 {
1300 if (!BN_copy(heap[i], heap[i/2])) goto err;
1301 }
1302 }
1303
1304 /* we have replaced all non-zero Z's by their inverses, now fix up all the points */
1305 for (i = 0; i < num; i++)
1306 {
1307 EC_POINT *p = points[i];
1308
1309 if (!BN_is_zero(&p->Z))
1310 {
1311 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
1312
1313 if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;
1314 if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;
1315
1316 if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;
1317 if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;
1318
1319 if (group->meth->field_set_to_one != 0)
1320 {
1321 if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;
1322 }
1323 else
1324 {
1325 if (!BN_one(&p->Z)) goto err;
1326 }
1327 p->Z_is_one = 1;
1328 }
1329 }
1330
1331 ret = 1;
1332
1333 err:
1334 BN_CTX_end(ctx);
1335 if (new_ctx != NULL)
1336 BN_CTX_free(new_ctx);
1337 if (heap != NULL)
1338 {
1339 /* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
1340 for (i = pow2/2 - 1; i > 0; i--)
1341 {
1342 if (heap[i] != NULL)
1343 BN_clear_free(heap[i]);
1344 }
1345 OPENSSL_free(heap);
1346 }
1347 return ret;
1348 }
1349
1350
1351int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1352 {
1353 return BN_mod_mul(r, a, b, &group->field, ctx);
1354 }
1355
1356
1357int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
1358 {
1359 return BN_mod_sqr(r, a, &group->field, ctx);
1360 }
diff --git a/src/lib/libcrypto/ecdh/ecdh.h b/src/lib/libcrypto/ecdh/ecdh.h
deleted file mode 100644
index 8887102c0b..0000000000
--- a/src/lib/libcrypto/ecdh/ecdh.h
+++ /dev/null
@@ -1,125 +0,0 @@
1/* crypto/ecdh/ecdh.h */
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 ECDH software is originally written by Douglas Stebila of
13 * Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 2000-2002 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 * licensing@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#ifndef HEADER_ECDH_H
70#define HEADER_ECDH_H
71
72#include <openssl/opensslconf.h>
73
74#ifdef OPENSSL_NO_ECDH
75#error ECDH is disabled.
76#endif
77
78#include <openssl/ec.h>
79#include <openssl/ossl_typ.h>
80#ifndef OPENSSL_NO_DEPRECATED
81#include <openssl/bn.h>
82#endif
83
84#ifdef __cplusplus
85extern "C" {
86#endif
87
88const ECDH_METHOD *ECDH_OpenSSL(void);
89
90void ECDH_set_default_method(const ECDH_METHOD *);
91const ECDH_METHOD *ECDH_get_default_method(void);
92int ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
93
94int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
95 void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
96
97int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
98 *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
99int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
100void *ECDH_get_ex_data(EC_KEY *d, int idx);
101
102
103/* BEGIN ERROR CODES */
104/* The following lines are auto generated by the script mkerr.pl. Any changes
105 * made after this point may be overwritten when the script is next run.
106 */
107void ERR_load_ECDH_strings(void);
108
109/* Error codes for the ECDH functions. */
110
111/* Function codes. */
112#define ECDH_F_ECDH_CHECK 102
113#define ECDH_F_ECDH_COMPUTE_KEY 100
114#define ECDH_F_ECDH_DATA_NEW_METHOD 101
115
116/* Reason codes. */
117#define ECDH_R_KDF_FAILED 102
118#define ECDH_R_NON_FIPS_METHOD 103
119#define ECDH_R_NO_PRIVATE_VALUE 100
120#define ECDH_R_POINT_ARITHMETIC_FAILURE 101
121
122#ifdef __cplusplus
123}
124#endif
125#endif
diff --git a/src/lib/libcrypto/ecdh/ech_err.c b/src/lib/libcrypto/ecdh/ech_err.c
deleted file mode 100644
index 3bd247398d..0000000000
--- a/src/lib/libcrypto/ecdh/ech_err.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/* crypto/ecdh/ech_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2011 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/ecdh.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason)
70
71static ERR_STRING_DATA ECDH_str_functs[]=
72 {
73{ERR_FUNC(ECDH_F_ECDH_CHECK), "ECDH_CHECK"},
74{ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
75{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"},
76{0,NULL}
77 };
78
79static ERR_STRING_DATA ECDH_str_reasons[]=
80 {
81{ERR_REASON(ECDH_R_KDF_FAILED) ,"KDF failed"},
82{ERR_REASON(ECDH_R_NON_FIPS_METHOD) ,"non fips method"},
83{ERR_REASON(ECDH_R_NO_PRIVATE_VALUE) ,"no private value"},
84{ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE),"point arithmetic failure"},
85{0,NULL}
86 };
87
88#endif
89
90void ERR_load_ECDH_strings(void)
91 {
92#ifndef OPENSSL_NO_ERR
93
94 if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL)
95 {
96 ERR_load_strings(0,ECDH_str_functs);
97 ERR_load_strings(0,ECDH_str_reasons);
98 }
99#endif
100 }
diff --git a/src/lib/libcrypto/ecdh/ech_key.c b/src/lib/libcrypto/ecdh/ech_key.c
deleted file mode 100644
index f44da9298b..0000000000
--- a/src/lib/libcrypto/ecdh/ech_key.c
+++ /dev/null
@@ -1,83 +0,0 @@
1/* crypto/ecdh/ecdh_key.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 ECDH software is originally written by Douglas Stebila of
13 * 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 "ech_locl.h"
71#ifndef OPENSSL_NO_ENGINE
72#include <openssl/engine.h>
73#endif
74
75int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
76 EC_KEY *eckey,
77 void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
78{
79 ECDH_DATA *ecdh = ecdh_check(eckey);
80 if (ecdh == NULL)
81 return 0;
82 return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF);
83}
diff --git a/src/lib/libcrypto/ecdh/ech_lib.c b/src/lib/libcrypto/ecdh/ech_lib.c
deleted file mode 100644
index dadbfd3c49..0000000000
--- a/src/lib/libcrypto/ecdh/ech_lib.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/* crypto/ecdh/ech_lib.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 ECDH software is originally written by Douglas Stebila of
13 * 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 "ech_locl.h"
71#include <string.h>
72#ifndef OPENSSL_NO_ENGINE
73#include <openssl/engine.h>
74#endif
75#include <openssl/err.h>
76#ifdef OPENSSL_FIPS
77#include <openssl/fips.h>
78#endif
79
80const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT;
81
82static const ECDH_METHOD *default_ECDH_method = NULL;
83
84static void *ecdh_data_new(void);
85static void *ecdh_data_dup(void *);
86static void ecdh_data_free(void *);
87
88void ECDH_set_default_method(const ECDH_METHOD *meth)
89 {
90 default_ECDH_method = meth;
91 }
92
93const ECDH_METHOD *ECDH_get_default_method(void)
94 {
95 if(!default_ECDH_method)
96 {
97#ifdef OPENSSL_FIPS
98 if (FIPS_mode())
99 return FIPS_ecdh_openssl();
100 else
101 return ECDH_OpenSSL();
102#else
103 default_ECDH_method = ECDH_OpenSSL();
104#endif
105 }
106 return default_ECDH_method;
107 }
108
109int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
110 {
111 ECDH_DATA *ecdh;
112
113 ecdh = ecdh_check(eckey);
114
115 if (ecdh == NULL)
116 return 0;
117
118#if 0
119 mtmp = ecdh->meth;
120 if (mtmp->finish)
121 mtmp->finish(eckey);
122#endif
123#ifndef OPENSSL_NO_ENGINE
124 if (ecdh->engine)
125 {
126 ENGINE_finish(ecdh->engine);
127 ecdh->engine = NULL;
128 }
129#endif
130 ecdh->meth = meth;
131#if 0
132 if (meth->init)
133 meth->init(eckey);
134#endif
135 return 1;
136 }
137
138static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
139 {
140 ECDH_DATA *ret;
141
142 ret=(ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA));
143 if (ret == NULL)
144 {
145 ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
146 return(NULL);
147 }
148
149 ret->init = NULL;
150
151 ret->meth = ECDH_get_default_method();
152 ret->engine = engine;
153#ifndef OPENSSL_NO_ENGINE
154 if (!ret->engine)
155 ret->engine = ENGINE_get_default_ECDH();
156 if (ret->engine)
157 {
158 ret->meth = ENGINE_get_ECDH(ret->engine);
159 if (!ret->meth)
160 {
161 ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
162 ENGINE_finish(ret->engine);
163 OPENSSL_free(ret);
164 return NULL;
165 }
166 }
167#endif
168
169 ret->flags = ret->meth->flags;
170 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
171#if 0
172 if ((ret->meth->init != NULL) && !ret->meth->init(ret))
173 {
174 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
175 OPENSSL_free(ret);
176 ret=NULL;
177 }
178#endif
179 return(ret);
180 }
181
182static void *ecdh_data_new(void)
183 {
184 return (void *)ECDH_DATA_new_method(NULL);
185 }
186
187static void *ecdh_data_dup(void *data)
188{
189 ECDH_DATA *r = (ECDH_DATA *)data;
190
191 /* XXX: dummy operation */
192 if (r == NULL)
193 return NULL;
194
195 return (void *)ecdh_data_new();
196}
197
198void ecdh_data_free(void *data)
199 {
200 ECDH_DATA *r = (ECDH_DATA *)data;
201
202#ifndef OPENSSL_NO_ENGINE
203 if (r->engine)
204 ENGINE_finish(r->engine);
205#endif
206
207 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data);
208
209 OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA));
210
211 OPENSSL_free(r);
212 }
213
214ECDH_DATA *ecdh_check(EC_KEY *key)
215 {
216 ECDH_DATA *ecdh_data;
217
218 void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
219 ecdh_data_free, ecdh_data_free);
220 if (data == NULL)
221 {
222 ecdh_data = (ECDH_DATA *)ecdh_data_new();
223 if (ecdh_data == NULL)
224 return NULL;
225 EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
226 ecdh_data_dup, ecdh_data_free, ecdh_data_free);
227 }
228 else
229 ecdh_data = (ECDH_DATA *)data;
230#ifdef OPENSSL_FIPS
231 if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD)
232 && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW))
233 {
234 ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD);
235 return NULL;
236 }
237#endif
238
239
240 return ecdh_data;
241 }
242
243int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
244 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
245 {
246 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp,
247 new_func, dup_func, free_func);
248 }
249
250int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg)
251 {
252 ECDH_DATA *ecdh;
253 ecdh = ecdh_check(d);
254 if (ecdh == NULL)
255 return 0;
256 return(CRYPTO_set_ex_data(&ecdh->ex_data,idx,arg));
257 }
258
259void *ECDH_get_ex_data(EC_KEY *d, int idx)
260 {
261 ECDH_DATA *ecdh;
262 ecdh = ecdh_check(d);
263 if (ecdh == NULL)
264 return NULL;
265 return(CRYPTO_get_ex_data(&ecdh->ex_data,idx));
266 }
diff --git a/src/lib/libcrypto/ecdh/ech_locl.h b/src/lib/libcrypto/ecdh/ech_locl.h
deleted file mode 100644
index f6cad6a894..0000000000
--- a/src/lib/libcrypto/ecdh/ech_locl.h
+++ /dev/null
@@ -1,102 +0,0 @@
1/* crypto/ecdh/ech_locl.h */
2/* ====================================================================
3 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@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#ifndef HEADER_ECH_LOCL_H
57#define HEADER_ECH_LOCL_H
58
59#include <openssl/ecdh.h>
60
61#ifdef __cplusplus
62extern "C" {
63#endif
64
65struct ecdh_method
66 {
67 const char *name;
68 int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
69 void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
70#if 0
71 int (*init)(EC_KEY *eckey);
72 int (*finish)(EC_KEY *eckey);
73#endif
74 int flags;
75 char *app_data;
76 };
77
78/* If this flag is set the ECDH method is FIPS compliant and can be used
79 * in FIPS mode. This is set in the validated module method. If an
80 * application sets this flag in its own methods it is its responsibility
81 * to ensure the result is compliant.
82 */
83
84#define ECDH_FLAG_FIPS_METHOD 0x1
85
86typedef struct ecdh_data_st {
87 /* EC_KEY_METH_DATA part */
88 int (*init)(EC_KEY *);
89 /* method specific part */
90 ENGINE *engine;
91 int flags;
92 const ECDH_METHOD *meth;
93 CRYPTO_EX_DATA ex_data;
94} ECDH_DATA;
95
96ECDH_DATA *ecdh_check(EC_KEY *);
97
98#ifdef __cplusplus
99}
100#endif
101
102#endif /* HEADER_ECH_LOCL_H */
diff --git a/src/lib/libcrypto/ecdsa/ecdsa.h b/src/lib/libcrypto/ecdsa/ecdsa.h
deleted file mode 100644
index 7fb5254b62..0000000000
--- a/src/lib/libcrypto/ecdsa/ecdsa.h
+++ /dev/null
@@ -1,260 +0,0 @@
1/* crypto/ecdsa/ecdsa.h */
2/**
3 * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
4 * \author Written by Nils Larsch for the OpenSSL project
5 */
6/* ====================================================================
7 * Copyright (c) 2000-2005 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 * licensing@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#ifndef HEADER_ECDSA_H
60#define HEADER_ECDSA_H
61
62#include <openssl/opensslconf.h>
63
64#ifdef OPENSSL_NO_ECDSA
65#error ECDSA is disabled.
66#endif
67
68#include <openssl/ec.h>
69#include <openssl/ossl_typ.h>
70#ifndef OPENSSL_NO_DEPRECATED
71#include <openssl/bn.h>
72#endif
73
74#ifdef __cplusplus
75extern "C" {
76#endif
77
78typedef struct ECDSA_SIG_st
79 {
80 BIGNUM *r;
81 BIGNUM *s;
82 } ECDSA_SIG;
83
84/** Allocates and initialize a ECDSA_SIG structure
85 * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
86 */
87ECDSA_SIG *ECDSA_SIG_new(void);
88
89/** frees a ECDSA_SIG structure
90 * \param sig pointer to the ECDSA_SIG structure
91 */
92void ECDSA_SIG_free(ECDSA_SIG *sig);
93
94/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
95 * (*pp += length of the DER encoded signature)).
96 * \param sig pointer to the ECDSA_SIG object
97 * \param pp pointer to a unsigned char pointer for the output or NULL
98 * \return the length of the DER encoded ECDSA_SIG object or 0
99 */
100int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
101
102/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
103 * (*pp += len)).
104 * \param sig pointer to ECDSA_SIG pointer (may be NULL)
105 * \param pp memory buffer with the DER encoded signature
106 * \param len length of the buffer
107 * \return pointer to the decoded ECDSA_SIG structure (or NULL)
108 */
109ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
110
111/** Computes the ECDSA signature of the given hash value using
112 * the supplied private key and returns the created signature.
113 * \param dgst pointer to the hash value
114 * \param dgst_len length of the hash value
115 * \param eckey EC_KEY object containing a private EC key
116 * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
117 */
118ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
119
120/** Computes ECDSA signature of a given hash value using the supplied
121 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
122 * \param dgst pointer to the hash value to sign
123 * \param dgstlen length of the hash value
124 * \param kinv BIGNUM with a pre-computed inverse k (optional)
125 * \param rp BIGNUM with a pre-computed rp value (optioanl),
126 * see ECDSA_sign_setup
127 * \param eckey EC_KEY object containing a private EC key
128 * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
129 */
130ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
131 const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
132
133/** Verifies that the supplied signature is a valid ECDSA
134 * signature of the supplied hash value using the supplied public key.
135 * \param dgst pointer to the hash value
136 * \param dgst_len length of the hash value
137 * \param sig ECDSA_SIG structure
138 * \param eckey EC_KEY object containing a public EC key
139 * \return 1 if the signature is valid, 0 if the signature is invalid
140 * and -1 on error
141 */
142int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
143 const ECDSA_SIG *sig, EC_KEY* eckey);
144
145const ECDSA_METHOD *ECDSA_OpenSSL(void);
146
147/** Sets the default ECDSA method
148 * \param meth new default ECDSA_METHOD
149 */
150void ECDSA_set_default_method(const ECDSA_METHOD *meth);
151
152/** Returns the default ECDSA method
153 * \return pointer to ECDSA_METHOD structure containing the default method
154 */
155const ECDSA_METHOD *ECDSA_get_default_method(void);
156
157/** Sets method to be used for the ECDSA operations
158 * \param eckey EC_KEY object
159 * \param meth new method
160 * \return 1 on success and 0 otherwise
161 */
162int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
163
164/** Returns the maximum length of the DER encoded signature
165 * \param eckey EC_KEY object
166 * \return numbers of bytes required for the DER encoded signature
167 */
168int ECDSA_size(const EC_KEY *eckey);
169
170/** Precompute parts of the signing operation
171 * \param eckey EC_KEY object containing a private EC key
172 * \param ctx BN_CTX object (optional)
173 * \param kinv BIGNUM pointer for the inverse of k
174 * \param rp BIGNUM pointer for x coordinate of k * generator
175 * \return 1 on success and 0 otherwise
176 */
177int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
178 BIGNUM **rp);
179
180/** Computes ECDSA signature of a given hash value using the supplied
181 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
182 * \param type this parameter is ignored
183 * \param dgst pointer to the hash value to sign
184 * \param dgstlen length of the hash value
185 * \param sig memory for the DER encoded created signature
186 * \param siglen pointer to the length of the returned signature
187 * \param eckey EC_KEY object containing a private EC key
188 * \return 1 on success and 0 otherwise
189 */
190int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
191 unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
192
193
194/** Computes ECDSA signature of a given hash value using the supplied
195 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
196 * \param type this parameter is ignored
197 * \param dgst pointer to the hash value to sign
198 * \param dgstlen length of the hash value
199 * \param sig buffer to hold the DER encoded signature
200 * \param siglen pointer to the length of the returned signature
201 * \param kinv BIGNUM with a pre-computed inverse k (optional)
202 * \param rp BIGNUM with a pre-computed rp value (optioanl),
203 * see ECDSA_sign_setup
204 * \param eckey EC_KEY object containing a private EC key
205 * \return 1 on success and 0 otherwise
206 */
207int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
208 unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
209 const BIGNUM *rp, EC_KEY *eckey);
210
211/** Verifies that the given signature is valid ECDSA signature
212 * of the supplied hash value using the specified public key.
213 * \param type this parameter is ignored
214 * \param dgst pointer to the hash value
215 * \param dgstlen length of the hash value
216 * \param sig pointer to the DER encoded signature
217 * \param siglen length of the DER encoded signature
218 * \param eckey EC_KEY object containing a public EC key
219 * \return 1 if the signature is valid, 0 if the signature is invalid
220 * and -1 on error
221 */
222int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
223 const unsigned char *sig, int siglen, EC_KEY *eckey);
224
225/* the standard ex_data functions */
226int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
227 *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
228int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
229void *ECDSA_get_ex_data(EC_KEY *d, int idx);
230
231
232/* BEGIN ERROR CODES */
233/* The following lines are auto generated by the script mkerr.pl. Any changes
234 * made after this point may be overwritten when the script is next run.
235 */
236void ERR_load_ECDSA_strings(void);
237
238/* Error codes for the ECDSA functions. */
239
240/* Function codes. */
241#define ECDSA_F_ECDSA_CHECK 104
242#define ECDSA_F_ECDSA_DATA_NEW_METHOD 100
243#define ECDSA_F_ECDSA_DO_SIGN 101
244#define ECDSA_F_ECDSA_DO_VERIFY 102
245#define ECDSA_F_ECDSA_SIGN_SETUP 103
246
247/* Reason codes. */
248#define ECDSA_R_BAD_SIGNATURE 100
249#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101
250#define ECDSA_R_ERR_EC_LIB 102
251#define ECDSA_R_MISSING_PARAMETERS 103
252#define ECDSA_R_NEED_NEW_SETUP_VALUES 106
253#define ECDSA_R_NON_FIPS_METHOD 107
254#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104
255#define ECDSA_R_SIGNATURE_MALLOC_FAILED 105
256
257#ifdef __cplusplus
258}
259#endif
260#endif
diff --git a/src/lib/libcrypto/ecdsa/ecs_asn1.c b/src/lib/libcrypto/ecdsa/ecs_asn1.c
deleted file mode 100644
index b295489400..0000000000
--- a/src/lib/libcrypto/ecdsa/ecs_asn1.c
+++ /dev/null
@@ -1,67 +0,0 @@
1/* crypto/ecdsa/ecs_asn1.c */
2/* ====================================================================
3 * Copyright (c) 2000-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 * licensing@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 "ecs_locl.h"
57#include <openssl/err.h>
58#include <openssl/asn1t.h>
59
60ASN1_SEQUENCE(ECDSA_SIG) = {
61 ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
62 ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
63} ASN1_SEQUENCE_END(ECDSA_SIG)
64
65DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
66DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
67IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG)
diff --git a/src/lib/libcrypto/ecdsa/ecs_err.c b/src/lib/libcrypto/ecdsa/ecs_err.c
deleted file mode 100644
index 81542e6d15..0000000000
--- a/src/lib/libcrypto/ecdsa/ecs_err.c
+++ /dev/null
@@ -1,106 +0,0 @@
1/* crypto/ecdsa/ecs_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2011 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/ecdsa.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason)
70
71static ERR_STRING_DATA ECDSA_str_functs[]=
72 {
73{ERR_FUNC(ECDSA_F_ECDSA_CHECK), "ECDSA_CHECK"},
74{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"},
75{ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"},
76{ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
77{ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"},
78{0,NULL}
79 };
80
81static ERR_STRING_DATA ECDSA_str_reasons[]=
82 {
83{ERR_REASON(ECDSA_R_BAD_SIGNATURE) ,"bad signature"},
84{ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
85{ERR_REASON(ECDSA_R_ERR_EC_LIB) ,"err ec lib"},
86{ERR_REASON(ECDSA_R_MISSING_PARAMETERS) ,"missing parameters"},
87{ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"},
88{ERR_REASON(ECDSA_R_NON_FIPS_METHOD) ,"non fips method"},
89{ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"},
90{ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"},
91{0,NULL}
92 };
93
94#endif
95
96void ERR_load_ECDSA_strings(void)
97 {
98#ifndef OPENSSL_NO_ERR
99
100 if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL)
101 {
102 ERR_load_strings(0,ECDSA_str_functs);
103 ERR_load_strings(0,ECDSA_str_reasons);
104 }
105#endif
106 }
diff --git a/src/lib/libcrypto/ecdsa/ecs_lib.c b/src/lib/libcrypto/ecdsa/ecs_lib.c
deleted file mode 100644
index e477da430b..0000000000
--- a/src/lib/libcrypto/ecdsa/ecs_lib.c
+++ /dev/null
@@ -1,278 +0,0 @@
1/* crypto/ecdsa/ecs_lib.c */
2/* ====================================================================
3 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <string.h>
57#include "ecs_locl.h"
58#ifndef OPENSSL_NO_ENGINE
59#include <openssl/engine.h>
60#endif
61#include <openssl/err.h>
62#include <openssl/bn.h>
63#ifdef OPENSSL_FIPS
64#include <openssl/fips.h>
65#endif
66
67const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT;
68
69static const ECDSA_METHOD *default_ECDSA_method = NULL;
70
71static void *ecdsa_data_new(void);
72static void *ecdsa_data_dup(void *);
73static void ecdsa_data_free(void *);
74
75void ECDSA_set_default_method(const ECDSA_METHOD *meth)
76{
77 default_ECDSA_method = meth;
78}
79
80const ECDSA_METHOD *ECDSA_get_default_method(void)
81{
82 if(!default_ECDSA_method)
83 {
84#ifdef OPENSSL_FIPS
85 if (FIPS_mode())
86 return FIPS_ecdsa_openssl();
87 else
88 return ECDSA_OpenSSL();
89#else
90 default_ECDSA_method = ECDSA_OpenSSL();
91#endif
92 }
93 return default_ECDSA_method;
94}
95
96int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
97{
98 ECDSA_DATA *ecdsa;
99
100 ecdsa = ecdsa_check(eckey);
101
102 if (ecdsa == NULL)
103 return 0;
104
105#ifndef OPENSSL_NO_ENGINE
106 if (ecdsa->engine)
107 {
108 ENGINE_finish(ecdsa->engine);
109 ecdsa->engine = NULL;
110 }
111#endif
112 ecdsa->meth = meth;
113
114 return 1;
115}
116
117static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
118{
119 ECDSA_DATA *ret;
120
121 ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA));
122 if (ret == NULL)
123 {
124 ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
125 return(NULL);
126 }
127
128 ret->init = NULL;
129
130 ret->meth = ECDSA_get_default_method();
131 ret->engine = engine;
132#ifndef OPENSSL_NO_ENGINE
133 if (!ret->engine)
134 ret->engine = ENGINE_get_default_ECDSA();
135 if (ret->engine)
136 {
137 ret->meth = ENGINE_get_ECDSA(ret->engine);
138 if (!ret->meth)
139 {
140 ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
141 ENGINE_finish(ret->engine);
142 OPENSSL_free(ret);
143 return NULL;
144 }
145 }
146#endif
147
148 ret->flags = ret->meth->flags;
149 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
150#if 0
151 if ((ret->meth->init != NULL) && !ret->meth->init(ret))
152 {
153 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
154 OPENSSL_free(ret);
155 ret=NULL;
156 }
157#endif
158 return(ret);
159}
160
161static void *ecdsa_data_new(void)
162{
163 return (void *)ECDSA_DATA_new_method(NULL);
164}
165
166static void *ecdsa_data_dup(void *data)
167{
168 ECDSA_DATA *r = (ECDSA_DATA *)data;
169
170 /* XXX: dummy operation */
171 if (r == NULL)
172 return NULL;
173
174 return ecdsa_data_new();
175}
176
177static void ecdsa_data_free(void *data)
178{
179 ECDSA_DATA *r = (ECDSA_DATA *)data;
180
181#ifndef OPENSSL_NO_ENGINE
182 if (r->engine)
183 ENGINE_finish(r->engine);
184#endif
185 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
186
187 OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA));
188
189 OPENSSL_free(r);
190}
191
192ECDSA_DATA *ecdsa_check(EC_KEY *key)
193{
194 ECDSA_DATA *ecdsa_data;
195
196 void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
197 ecdsa_data_free, ecdsa_data_free);
198 if (data == NULL)
199 {
200 ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
201 if (ecdsa_data == NULL)
202 return NULL;
203 EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
204 ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
205 }
206 else
207 ecdsa_data = (ECDSA_DATA *)data;
208#ifdef OPENSSL_FIPS
209 if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD)
210 && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW))
211 {
212 ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD);
213 return NULL;
214 }
215#endif
216
217 return ecdsa_data;
218}
219
220int ECDSA_size(const EC_KEY *r)
221{
222 int ret,i;
223 ASN1_INTEGER bs;
224 BIGNUM *order=NULL;
225 unsigned char buf[4];
226 const EC_GROUP *group;
227
228 if (r == NULL)
229 return 0;
230 group = EC_KEY_get0_group(r);
231 if (group == NULL)
232 return 0;
233
234 if ((order = BN_new()) == NULL) return 0;
235 if (!EC_GROUP_get_order(group,order,NULL))
236 {
237 BN_clear_free(order);
238 return 0;
239 }
240 i=BN_num_bits(order);
241 bs.length=(i+7)/8;
242 bs.data=buf;
243 bs.type=V_ASN1_INTEGER;
244 /* If the top bit is set the asn1 encoding is 1 larger. */
245 buf[0]=0xff;
246
247 i=i2d_ASN1_INTEGER(&bs,NULL);
248 i+=i; /* r and s */
249 ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
250 BN_clear_free(order);
251 return(ret);
252}
253
254
255int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
256 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
257{
258 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
259 new_func, dup_func, free_func);
260}
261
262int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
263{
264 ECDSA_DATA *ecdsa;
265 ecdsa = ecdsa_check(d);
266 if (ecdsa == NULL)
267 return 0;
268 return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg));
269}
270
271void *ECDSA_get_ex_data(EC_KEY *d, int idx)
272{
273 ECDSA_DATA *ecdsa;
274 ecdsa = ecdsa_check(d);
275 if (ecdsa == NULL)
276 return NULL;
277 return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx));
278}
diff --git a/src/lib/libcrypto/ecdsa/ecs_locl.h b/src/lib/libcrypto/ecdsa/ecs_locl.h
deleted file mode 100644
index cb3be13cfc..0000000000
--- a/src/lib/libcrypto/ecdsa/ecs_locl.h
+++ /dev/null
@@ -1,115 +0,0 @@
1/* crypto/ecdsa/ecs_locl.h */
2/*
3 * Written by Nils Larsch for the OpenSSL project
4 */
5/* ====================================================================
6 * Copyright (c) 2000-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 * 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#ifndef HEADER_ECS_LOCL_H
60#define HEADER_ECS_LOCL_H
61
62#include <openssl/ecdsa.h>
63
64#ifdef __cplusplus
65extern "C" {
66#endif
67
68struct ecdsa_method
69 {
70 const char *name;
71 ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len,
72 const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey);
73 int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
74 BIGNUM **r);
75 int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len,
76 const ECDSA_SIG *sig, EC_KEY *eckey);
77#if 0
78 int (*init)(EC_KEY *eckey);
79 int (*finish)(EC_KEY *eckey);
80#endif
81 int flags;
82 char *app_data;
83 };
84
85/* If this flag is set the ECDSA method is FIPS compliant and can be used
86 * in FIPS mode. This is set in the validated module method. If an
87 * application sets this flag in its own methods it is its responsibility
88 * to ensure the result is compliant.
89 */
90
91#define ECDSA_FLAG_FIPS_METHOD 0x1
92
93typedef struct ecdsa_data_st {
94 /* EC_KEY_METH_DATA part */
95 int (*init)(EC_KEY *);
96 /* method (ECDSA) specific part */
97 ENGINE *engine;
98 int flags;
99 const ECDSA_METHOD *meth;
100 CRYPTO_EX_DATA ex_data;
101} ECDSA_DATA;
102
103/** ecdsa_check
104 * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure
105 * and if not it removes the old meth_data and creates a ECDSA_DATA structure.
106 * \param eckey pointer to a EC_KEY object
107 * \return pointer to a ECDSA_DATA structure
108 */
109ECDSA_DATA *ecdsa_check(EC_KEY *eckey);
110
111#ifdef __cplusplus
112}
113#endif
114
115#endif /* HEADER_ECS_LOCL_H */
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c
deleted file mode 100644
index 7725935610..0000000000
--- a/src/lib/libcrypto/ecdsa/ecs_ossl.c
+++ /dev/null
@@ -1,483 +0,0 @@
1/* crypto/ecdsa/ecs_ossl.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#include "ecs_locl.h"
60#include <openssl/err.h>
61#include <openssl/obj_mac.h>
62#include <openssl/bn.h>
63
64static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
65 const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
66static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
67 BIGNUM **rp);
68static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
69 const ECDSA_SIG *sig, EC_KEY *eckey);
70
71static ECDSA_METHOD openssl_ecdsa_meth = {
72 "OpenSSL ECDSA method",
73 ecdsa_do_sign,
74 ecdsa_sign_setup,
75 ecdsa_do_verify,
76#if 0
77 NULL, /* init */
78 NULL, /* finish */
79#endif
80 0, /* flags */
81 NULL /* app_data */
82};
83
84const ECDSA_METHOD *ECDSA_OpenSSL(void)
85{
86 return &openssl_ecdsa_meth;
87}
88
89static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
90 BIGNUM **rp)
91{
92 BN_CTX *ctx = NULL;
93 BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
94 EC_POINT *tmp_point=NULL;
95 const EC_GROUP *group;
96 int ret = 0;
97
98 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
99 {
100 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
101 return 0;
102 }
103
104 if (ctx_in == NULL)
105 {
106 if ((ctx = BN_CTX_new()) == NULL)
107 {
108 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
109 return 0;
110 }
111 }
112 else
113 ctx = ctx_in;
114
115 k = BN_new(); /* this value is later returned in *kinvp */
116 r = BN_new(); /* this value is later returned in *rp */
117 order = BN_new();
118 X = BN_new();
119 if (!k || !r || !order || !X)
120 {
121 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
122 goto err;
123 }
124 if ((tmp_point = EC_POINT_new(group)) == NULL)
125 {
126 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
127 goto err;
128 }
129 if (!EC_GROUP_get_order(group, order, ctx))
130 {
131 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
132 goto err;
133 }
134
135 do
136 {
137 /* get random k */
138 do
139 if (!BN_rand_range(k, order))
140 {
141 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
142 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
143 goto err;
144 }
145 while (BN_is_zero(k));
146
147 /* We do not want timing information to leak the length of k,
148 * so we compute G*k using an equivalent scalar of fixed
149 * bit-length. */
150
151 if (!BN_add(k, k, order)) goto err;
152 if (BN_num_bits(k) <= BN_num_bits(order))
153 if (!BN_add(k, k, order)) goto err;
154
155 /* compute r the x-coordinate of generator * k */
156 if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
157 {
158 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
159 goto err;
160 }
161 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
162 {
163 if (!EC_POINT_get_affine_coordinates_GFp(group,
164 tmp_point, X, NULL, ctx))
165 {
166 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
167 goto err;
168 }
169 }
170#ifndef OPENSSL_NO_EC2M
171 else /* NID_X9_62_characteristic_two_field */
172 {
173 if (!EC_POINT_get_affine_coordinates_GF2m(group,
174 tmp_point, X, NULL, ctx))
175 {
176 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
177 goto err;
178 }
179 }
180#endif
181 if (!BN_nnmod(r, X, order, ctx))
182 {
183 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
184 goto err;
185 }
186 }
187 while (BN_is_zero(r));
188
189 /* compute the inverse of k */
190 if (!BN_mod_inverse(k, k, order, ctx))
191 {
192 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
193 goto err;
194 }
195 /* clear old values if necessary */
196 if (*rp != NULL)
197 BN_clear_free(*rp);
198 if (*kinvp != NULL)
199 BN_clear_free(*kinvp);
200 /* save the pre-computed values */
201 *rp = r;
202 *kinvp = k;
203 ret = 1;
204err:
205 if (!ret)
206 {
207 if (k != NULL) BN_clear_free(k);
208 if (r != NULL) BN_clear_free(r);
209 }
210 if (ctx_in == NULL)
211 BN_CTX_free(ctx);
212 if (order != NULL)
213 BN_free(order);
214 if (tmp_point != NULL)
215 EC_POINT_free(tmp_point);
216 if (X)
217 BN_clear_free(X);
218 return(ret);
219}
220
221
222static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
223 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
224{
225 int ok = 0, i;
226 BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
227 const BIGNUM *ckinv;
228 BN_CTX *ctx = NULL;
229 const EC_GROUP *group;
230 ECDSA_SIG *ret;
231 ECDSA_DATA *ecdsa;
232 const BIGNUM *priv_key;
233
234 ecdsa = ecdsa_check(eckey);
235 group = EC_KEY_get0_group(eckey);
236 priv_key = EC_KEY_get0_private_key(eckey);
237
238 if (group == NULL || priv_key == NULL || ecdsa == NULL)
239 {
240 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
241 return NULL;
242 }
243
244 ret = ECDSA_SIG_new();
245 if (!ret)
246 {
247 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
248 return NULL;
249 }
250 s = ret->s;
251
252 if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
253 (tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
254 {
255 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
256 goto err;
257 }
258
259 if (!EC_GROUP_get_order(group, order, ctx))
260 {
261 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
262 goto err;
263 }
264 i = BN_num_bits(order);
265 /* Need to truncate digest if it is too long: first truncate whole
266 * bytes.
267 */
268 if (8 * dgst_len > i)
269 dgst_len = (i + 7)/8;
270 if (!BN_bin2bn(dgst, dgst_len, m))
271 {
272 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
273 goto err;
274 }
275 /* If still too long truncate remaining bits with a shift */
276 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
277 {
278 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
279 goto err;
280 }
281 do
282 {
283 if (in_kinv == NULL || in_r == NULL)
284 {
285 if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r))
286 {
287 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
288 goto err;
289 }
290 ckinv = kinv;
291 }
292 else
293 {
294 ckinv = in_kinv;
295 if (BN_copy(ret->r, in_r) == NULL)
296 {
297 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
298 goto err;
299 }
300 }
301
302 if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
303 {
304 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
305 goto err;
306 }
307 if (!BN_mod_add_quick(s, tmp, m, order))
308 {
309 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
310 goto err;
311 }
312 if (!BN_mod_mul(s, s, ckinv, order, ctx))
313 {
314 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
315 goto err;
316 }
317 if (BN_is_zero(s))
318 {
319 /* if kinv and r have been supplied by the caller
320 * don't to generate new kinv and r values */
321 if (in_kinv != NULL && in_r != NULL)
322 {
323 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
324 goto err;
325 }
326 }
327 else
328 /* s != 0 => we have a valid signature */
329 break;
330 }
331 while (1);
332
333 ok = 1;
334err:
335 if (!ok)
336 {
337 ECDSA_SIG_free(ret);
338 ret = NULL;
339 }
340 if (ctx)
341 BN_CTX_free(ctx);
342 if (m)
343 BN_clear_free(m);
344 if (tmp)
345 BN_clear_free(tmp);
346 if (order)
347 BN_free(order);
348 if (kinv)
349 BN_clear_free(kinv);
350 return ret;
351}
352
353static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
354 const ECDSA_SIG *sig, EC_KEY *eckey)
355{
356 int ret = -1, i;
357 BN_CTX *ctx;
358 BIGNUM *order, *u1, *u2, *m, *X;
359 EC_POINT *point = NULL;
360 const EC_GROUP *group;
361 const EC_POINT *pub_key;
362
363 /* check input values */
364 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
365 (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
366 {
367 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
368 return -1;
369 }
370
371 ctx = BN_CTX_new();
372 if (!ctx)
373 {
374 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
375 return -1;
376 }
377 BN_CTX_start(ctx);
378 order = BN_CTX_get(ctx);
379 u1 = BN_CTX_get(ctx);
380 u2 = BN_CTX_get(ctx);
381 m = BN_CTX_get(ctx);
382 X = BN_CTX_get(ctx);
383 if (!X)
384 {
385 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
386 goto err;
387 }
388
389 if (!EC_GROUP_get_order(group, order, ctx))
390 {
391 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
392 goto err;
393 }
394
395 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
396 BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
397 BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0)
398 {
399 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
400 ret = 0; /* signature is invalid */
401 goto err;
402 }
403 /* calculate tmp1 = inv(S) mod order */
404 if (!BN_mod_inverse(u2, sig->s, order, ctx))
405 {
406 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
407 goto err;
408 }
409 /* digest -> m */
410 i = BN_num_bits(order);
411 /* Need to truncate digest if it is too long: first truncate whole
412 * bytes.
413 */
414 if (8 * dgst_len > i)
415 dgst_len = (i + 7)/8;
416 if (!BN_bin2bn(dgst, dgst_len, m))
417 {
418 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
419 goto err;
420 }
421 /* If still too long truncate remaining bits with a shift */
422 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
423 {
424 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
425 goto err;
426 }
427 /* u1 = m * tmp mod order */
428 if (!BN_mod_mul(u1, m, u2, order, ctx))
429 {
430 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
431 goto err;
432 }
433 /* u2 = r * w mod q */
434 if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
435 {
436 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
437 goto err;
438 }
439
440 if ((point = EC_POINT_new(group)) == NULL)
441 {
442 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
443 goto err;
444 }
445 if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
446 {
447 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
448 goto err;
449 }
450 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
451 {
452 if (!EC_POINT_get_affine_coordinates_GFp(group,
453 point, X, NULL, ctx))
454 {
455 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
456 goto err;
457 }
458 }
459#ifndef OPENSSL_NO_EC2M
460 else /* NID_X9_62_characteristic_two_field */
461 {
462 if (!EC_POINT_get_affine_coordinates_GF2m(group,
463 point, X, NULL, ctx))
464 {
465 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
466 goto err;
467 }
468 }
469#endif
470 if (!BN_nnmod(u1, X, order, ctx))
471 {
472 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
473 goto err;
474 }
475 /* if the signature is correct u1 is equal to sig->r */
476 ret = (BN_ucmp(u1, sig->r) == 0);
477err:
478 BN_CTX_end(ctx);
479 BN_CTX_free(ctx);
480 if (point)
481 EC_POINT_free(point);
482 return ret;
483}
diff --git a/src/lib/libcrypto/ecdsa/ecs_sign.c b/src/lib/libcrypto/ecdsa/ecs_sign.c
deleted file mode 100644
index 353d5af514..0000000000
--- a/src/lib/libcrypto/ecdsa/ecs_sign.c
+++ /dev/null
@@ -1,106 +0,0 @@
1/* crypto/ecdsa/ecdsa_sign.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 "ecs_locl.h"
57#ifndef OPENSSL_NO_ENGINE
58#include <openssl/engine.h>
59#endif
60#include <openssl/rand.h>
61
62ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
63{
64 return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
65}
66
67ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
68 const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey)
69{
70 ECDSA_DATA *ecdsa = ecdsa_check(eckey);
71 if (ecdsa == NULL)
72 return NULL;
73 return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey);
74}
75
76int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
77 *sig, unsigned int *siglen, EC_KEY *eckey)
78{
79 return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
80}
81
82int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
83 *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r,
84 EC_KEY *eckey)
85{
86 ECDSA_SIG *s;
87 RAND_seed(dgst, dlen);
88 s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
89 if (s == NULL)
90 {
91 *siglen=0;
92 return 0;
93 }
94 *siglen = i2d_ECDSA_SIG(s, &sig);
95 ECDSA_SIG_free(s);
96 return 1;
97}
98
99int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
100 BIGNUM **rp)
101{
102 ECDSA_DATA *ecdsa = ecdsa_check(eckey);
103 if (ecdsa == NULL)
104 return 0;
105 return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp);
106}
diff --git a/src/lib/libcrypto/ecdsa/ecs_vrf.c b/src/lib/libcrypto/ecdsa/ecs_vrf.c
deleted file mode 100644
index ef9acf7b61..0000000000
--- a/src/lib/libcrypto/ecdsa/ecs_vrf.c
+++ /dev/null
@@ -1,96 +0,0 @@
1/* crypto/ecdsa/ecdsa_vrf.c */
2/*
3 * Written by Nils Larsch 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#include "ecs_locl.h"
60#ifndef OPENSSL_NO_ENGINE
61#include <openssl/engine.h>
62#endif
63
64/* returns
65 * 1: correct signature
66 * 0: incorrect signature
67 * -1: error
68 */
69int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
70 const ECDSA_SIG *sig, EC_KEY *eckey)
71 {
72 ECDSA_DATA *ecdsa = ecdsa_check(eckey);
73 if (ecdsa == NULL)
74 return 0;
75 return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey);
76 }
77
78/* returns
79 * 1: correct signature
80 * 0: incorrect signature
81 * -1: error
82 */
83int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
84 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
85 {
86 ECDSA_SIG *s;
87 int ret=-1;
88
89 s = ECDSA_SIG_new();
90 if (s == NULL) return(ret);
91 if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
92 ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
93err:
94 ECDSA_SIG_free(s);
95 return(ret);
96 }