summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec')
-rw-r--r--src/lib/libcrypto/ec/Makefile231
-rw-r--r--src/lib/libcrypto/ec/ec.h69
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c351
-rw-r--r--src/lib/libcrypto/ec/ec_cvt.c28
-rw-r--r--src/lib/libcrypto/ec/ec_err.c20
-rw-r--r--src/lib/libcrypto/ec/ec_lcl.h55
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c80
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c14
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c13
-rw-r--r--src/lib/libcrypto/ec/ecp_smpl.c379
-rw-r--r--src/lib/libcrypto/ec/ectest.c1334
11 files changed, 2359 insertions, 215 deletions
diff --git a/src/lib/libcrypto/ec/Makefile b/src/lib/libcrypto/ec/Makefile
new file mode 100644
index 0000000000..db380ed16f
--- /dev/null
+++ b/src/lib/libcrypto/ec/Makefile
@@ -0,0 +1,231 @@
1#
2# crypto/ec/Makefile
3#
4
5DIR= ec
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g
10MAKEFILE= Makefile
11AR= ar r
12
13CFLAGS= $(INCLUDES) $(CFLAG)
14
15GENERAL=Makefile
16TEST=ectest.c
17APPS=
18
19LIB=$(TOP)/libcrypto.a
20LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
21 ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
22 ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c
23
24LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
25 ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
26 ec2_smpl.o ec2_mult.o ec_ameth.o ec_pmeth.o eck_prn.o
27
28SRC= $(LIBSRC)
29
30EXHEADER= ec.h
31HEADER= ec_lcl.h $(EXHEADER)
32
33ALL= $(GENERAL) $(SRC) $(HEADER)
34
35top:
36 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
37
38all: lib
39
40lib: $(LIBOBJ)
41 $(AR) $(LIB) $(LIBOBJ)
42 $(RANLIB) $(LIB) || echo Never mind.
43 @touch lib
44
45files:
46 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
47
48links:
49 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
50 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
51 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
52
53install:
54 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
55 @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
56 do \
57 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
58 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
59 done;
60
61tags:
62 ctags $(SRC)
63
64tests:
65
66lint:
67 lint -DLINT $(INCLUDES) $(SRC)>fluff
68
69depend:
70 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
71 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
72
73dclean:
74 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
75 mv -f Makefile.new $(MAKEFILE)
76
77clean:
78 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
79
80# DO NOT DELETE THIS LINE -- make depend depends on it.
81
82ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
83ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
84ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
85ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
86ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
87ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
88ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
89ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
90ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
91ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
92ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
93ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
94ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
95ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
96ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
97ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec_lcl.h
98ec_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
99ec_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
100ec_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
101ec_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
102ec_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
103ec_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
104ec_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
105ec_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
106ec_ameth.o: ../../include/openssl/opensslconf.h
107ec_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
108ec_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
109ec_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
110ec_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
111ec_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
112ec_ameth.o: ec_ameth.c
113ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
114ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
115ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
116ec_asn1.o: ../../include/openssl/ec.h ../../include/openssl/err.h
117ec_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
118ec_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
119ec_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
120ec_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
121ec_asn1.o: ../../include/openssl/symhacks.h ec_asn1.c ec_lcl.h
122ec_check.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
123ec_check.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
124ec_check.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
125ec_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
126ec_check.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
127ec_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
128ec_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
129ec_check.o: ../../include/openssl/symhacks.h ec_check.c ec_lcl.h
130ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
131ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
132ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
133ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
134ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
135ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
136ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
137ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
138ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
139ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
140ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
141ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
142ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
143ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
144ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
145ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
146ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
147ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
148ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
149ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
150ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
151ec_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
152ec_err.o: ../../include/openssl/symhacks.h ec_err.c
153ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
154ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
155ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
156ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
157ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
158ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
159ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
160ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
161ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
162ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
163ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
164ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
165ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
166ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
167ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
168ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
169ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
170ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
171ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
172ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
173ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
174ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
175ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
176ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
177ec_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
178ec_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
179ec_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
180ec_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
181ec_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
182ec_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
183ec_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
184ec_pmeth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
185ec_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
186ec_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
187ec_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
188ec_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
189ec_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
190ec_pmeth.o: ec_pmeth.c
191ec_print.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
192ec_print.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
193ec_print.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
194ec_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
195ec_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
196ec_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
197ec_print.o: ../../include/openssl/symhacks.h ec_lcl.h ec_print.c
198eck_prn.o: ../../e_os.h ../../include/openssl/asn1.h
199eck_prn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
200eck_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
201eck_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
202eck_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
203eck_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
204eck_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
205eck_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
206eck_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
207eck_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h eck_prn.c
208ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
209ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
210ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
211ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
212ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
213ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
214ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
215ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
216ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
217ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
218ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
219ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
220ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
221ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
222ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
223ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
224ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
225ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
226ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
227ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
228ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
229ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
230ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
231ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
index 9d01325af3..ee7078130c 100644
--- a/src/lib/libcrypto/ec/ec.h
+++ b/src/lib/libcrypto/ec/ec.h
@@ -151,24 +151,7 @@ const EC_METHOD *EC_GFp_mont_method(void);
151 */ 151 */
152const EC_METHOD *EC_GFp_nist_method(void); 152const EC_METHOD *EC_GFp_nist_method(void);
153 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 154
171#ifndef OPENSSL_NO_EC2M
172/********************************************************************/ 155/********************************************************************/
173/* EC_METHOD for curves over GF(2^m) */ 156/* EC_METHOD for curves over GF(2^m) */
174/********************************************************************/ 157/********************************************************************/
@@ -178,8 +161,6 @@ const EC_METHOD *EC_GFp_nistp521_method(void);
178 */ 161 */
179const EC_METHOD *EC_GF2m_simple_method(void); 162const EC_METHOD *EC_GF2m_simple_method(void);
180 163
181#endif
182
183 164
184/********************************************************************/ 165/********************************************************************/
185/* EC_GROUP functions */ 166/* EC_GROUP functions */
@@ -301,7 +282,6 @@ int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, co
301 */ 282 */
302int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); 283int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
303 284
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 285/** 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 286 * \param group EC_GROUP object
307 * \param p BIGNUM with the polynomial defining the underlying field 287 * \param p BIGNUM with the polynomial defining the underlying field
@@ -321,7 +301,7 @@ int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, c
321 * \return 1 on success and 0 if an error occured 301 * \return 1 on success and 0 if an error occured
322 */ 302 */
323int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); 303int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
324#endif 304
325/** Returns the number of bits needed to represent a field element 305/** Returns the number of bits needed to represent a field element
326 * \param group EC_GROUP object 306 * \param group EC_GROUP object
327 * \return number of bits needed to represent a field element 307 * \return number of bits needed to represent a field element
@@ -362,7 +342,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
362 * \return newly created EC_GROUP object with the specified parameters 342 * \return newly created EC_GROUP object with the specified parameters
363 */ 343 */
364EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); 344EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
365#ifndef OPENSSL_NO_EC2M 345
366/** Creates a new EC_GROUP object with the specified parameters defined 346/** 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) 347 * 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 348 * \param p BIGNUM with the polynomial defining the underlying field
@@ -372,7 +352,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
372 * \return newly created EC_GROUP object with the specified parameters 352 * \return newly created EC_GROUP object with the specified parameters
373 */ 353 */
374EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); 354EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
375#endif 355
376/** Creates a EC_GROUP object with a curve specified by a NID 356/** Creates a EC_GROUP object with a curve specified by a NID
377 * \param nid NID of the OID of the curve name 357 * \param nid NID of the OID of the curve name
378 * \return newly created EC_GROUP object with specified curve or NULL 358 * \return newly created EC_GROUP object with specified curve or NULL
@@ -501,7 +481,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
501 */ 481 */
502int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, 482int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
503 const BIGNUM *x, int y_bit, BN_CTX *ctx); 483 const BIGNUM *x, int y_bit, BN_CTX *ctx);
504#ifndef OPENSSL_NO_EC2M 484
505/** Sets the affine coordinates of a EC_POINT over GF2m 485/** Sets the affine coordinates of a EC_POINT over GF2m
506 * \param group underlying EC_GROUP object 486 * \param group underlying EC_GROUP object
507 * \param p EC_POINT object 487 * \param p EC_POINT object
@@ -534,7 +514,7 @@ int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
534 */ 514 */
535int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, 515int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
536 const BIGNUM *x, int y_bit, BN_CTX *ctx); 516 const BIGNUM *x, int y_bit, BN_CTX *ctx);
537#endif 517
538/** Encodes a EC_POINT object to a octet string 518/** Encodes a EC_POINT object to a octet string
539 * \param group underlying EC_GROUP object 519 * \param group underlying EC_GROUP object
540 * \param p EC_POINT object 520 * \param p EC_POINT object
@@ -673,11 +653,9 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
673/* EC_GROUP_get_basis_type() returns the NID of the basis type 653/* EC_GROUP_get_basis_type() returns the NID of the basis type
674 * used to represent the field elements */ 654 * used to represent the field elements */
675int EC_GROUP_get_basis_type(const EC_GROUP *); 655int 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); 656int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
678int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, 657int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
679 unsigned int *k2, unsigned int *k3); 658 unsigned int *k2, unsigned int *k3);
680#endif
681 659
682#define OPENSSL_EC_NAMED_CURVE 0x001 660#define OPENSSL_EC_NAMED_CURVE 0x001
683 661
@@ -711,21 +689,11 @@ typedef struct ec_key_st EC_KEY;
711#define EC_PKEY_NO_PARAMETERS 0x001 689#define EC_PKEY_NO_PARAMETERS 0x001
712#define EC_PKEY_NO_PUBKEY 0x002 690#define EC_PKEY_NO_PUBKEY 0x002
713 691
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. 692/** Creates a new EC_KEY object.
719 * \return EC_KEY object or NULL if an error occurred. 693 * \return EC_KEY object or NULL if an error occurred.
720 */ 694 */
721EC_KEY *EC_KEY_new(void); 695EC_KEY *EC_KEY_new(void);
722 696
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 697/** Creates a new EC_KEY object using a named curve as underlying
730 * EC_GROUP object. 698 * EC_GROUP object.
731 * \param nid NID of the named curve. 699 * \param nid NID of the named curve.
@@ -831,15 +799,6 @@ int EC_KEY_generate_key(EC_KEY *key);
831 */ 799 */
832int EC_KEY_check_key(const EC_KEY *key); 800int EC_KEY_check_key(const EC_KEY *key);
833 801
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 802
844/********************************************************************/ 803/********************************************************************/
845/* de- and encoding functions for SEC1 ECPrivateKey */ 804/* de- and encoding functions for SEC1 ECPrivateKey */
@@ -967,7 +926,6 @@ void ERR_load_EC_strings(void);
967/* Error codes for the EC functions. */ 926/* Error codes for the EC functions. */
968 927
969/* Function codes. */ 928/* Function codes. */
970#define EC_F_BN_TO_FELEM 224
971#define EC_F_COMPUTE_WNAF 143 929#define EC_F_COMPUTE_WNAF 143
972#define EC_F_D2I_ECPARAMETERS 144 930#define EC_F_D2I_ECPARAMETERS 144
973#define EC_F_D2I_ECPKPARAMETERS 145 931#define EC_F_D2I_ECPKPARAMETERS 145
@@ -1010,15 +968,6 @@ void ERR_load_EC_strings(void);
1010#define EC_F_EC_GFP_MONT_FIELD_SQR 132 968#define EC_F_EC_GFP_MONT_FIELD_SQR 132
1011#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 969#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
1012#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 970#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 971#define EC_F_EC_GFP_NIST_FIELD_MUL 200
1023#define EC_F_EC_GFP_NIST_FIELD_SQR 201 972#define EC_F_EC_GFP_NIST_FIELD_SQR 201
1024#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 973#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
@@ -1061,7 +1010,6 @@ void ERR_load_EC_strings(void);
1061#define EC_F_EC_KEY_NEW 182 1010#define EC_F_EC_KEY_NEW 182
1062#define EC_F_EC_KEY_PRINT 180 1011#define EC_F_EC_KEY_PRINT 180
1063#define EC_F_EC_KEY_PRINT_FP 181 1012#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 1013#define EC_F_EC_POINTS_MAKE_AFFINE 136
1066#define EC_F_EC_POINT_ADD 112 1014#define EC_F_EC_POINT_ADD 112
1067#define EC_F_EC_POINT_CMP 113 1015#define EC_F_EC_POINT_CMP 113
@@ -1092,9 +1040,6 @@ void ERR_load_EC_strings(void);
1092#define EC_F_I2D_ECPKPARAMETERS 191 1040#define EC_F_I2D_ECPKPARAMETERS 191
1093#define EC_F_I2D_ECPRIVATEKEY 192 1041#define EC_F_I2D_ECPRIVATEKEY 192
1094#define EC_F_I2O_ECPUBLICKEY 151 1042#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 1043#define EC_F_O2I_ECPUBLICKEY 152
1099#define EC_F_OLD_EC_PRIV_DECODE 222 1044#define EC_F_OLD_EC_PRIV_DECODE 222
1100#define EC_F_PKEY_EC_CTRL 197 1045#define EC_F_PKEY_EC_CTRL 197
@@ -1107,15 +1052,12 @@ void ERR_load_EC_strings(void);
1107/* Reason codes. */ 1052/* Reason codes. */
1108#define EC_R_ASN1_ERROR 115 1053#define EC_R_ASN1_ERROR 115
1109#define EC_R_ASN1_UNKNOWN_FIELD 116 1054#define EC_R_ASN1_UNKNOWN_FIELD 116
1110#define EC_R_BIGNUM_OUT_OF_RANGE 144
1111#define EC_R_BUFFER_TOO_SMALL 100 1055#define EC_R_BUFFER_TOO_SMALL 100
1112#define EC_R_COORDINATES_OUT_OF_RANGE 146
1113#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 1056#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
1114#define EC_R_DECODE_ERROR 142 1057#define EC_R_DECODE_ERROR 142
1115#define EC_R_DISCRIMINANT_IS_ZERO 118 1058#define EC_R_DISCRIMINANT_IS_ZERO 118
1116#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 1059#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
1117#define EC_R_FIELD_TOO_LARGE 143 1060#define EC_R_FIELD_TOO_LARGE 143
1118#define EC_R_GF2M_NOT_SUPPORTED 147
1119#define EC_R_GROUP2PKPARAMETERS_FAILURE 120 1061#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
1120#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 1062#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
1121#define EC_R_INCOMPATIBLE_OBJECTS 101 1063#define EC_R_INCOMPATIBLE_OBJECTS 101
@@ -1150,7 +1092,6 @@ void ERR_load_EC_strings(void);
1150#define EC_R_UNKNOWN_GROUP 129 1092#define EC_R_UNKNOWN_GROUP 129
1151#define EC_R_UNKNOWN_ORDER 114 1093#define EC_R_UNKNOWN_ORDER 114
1152#define EC_R_UNSUPPORTED_FIELD 131 1094#define EC_R_UNSUPPORTED_FIELD 131
1153#define EC_R_WRONG_CURVE_PARAMETERS 145
1154#define EC_R_WRONG_ORDER 130 1095#define EC_R_WRONG_ORDER 130
1155 1096
1156#ifdef __cplusplus 1097#ifdef __cplusplus
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
index e0e59c7d82..03deae6674 100644
--- a/src/lib/libcrypto/ec/ec2_smpl.c
+++ b/src/lib/libcrypto/ec/ec2_smpl.c
@@ -71,20 +71,10 @@
71 71
72#include "ec_lcl.h" 72#include "ec_lcl.h"
73 73
74#ifndef OPENSSL_NO_EC2M
75
76#ifdef OPENSSL_FIPS
77#include <openssl/fips.h>
78#endif
79
80 74
81const EC_METHOD *EC_GF2m_simple_method(void) 75const EC_METHOD *EC_GF2m_simple_method(void)
82 { 76 {
83#ifdef OPENSSL_FIPS
84 return fips_ec_gf2m_simple_method();
85#else
86 static const EC_METHOD ret = { 77 static const EC_METHOD ret = {
87 EC_FLAGS_DEFAULT_OCT,
88 NID_X9_62_characteristic_two_field, 78 NID_X9_62_characteristic_two_field,
89 ec_GF2m_simple_group_init, 79 ec_GF2m_simple_group_init,
90 ec_GF2m_simple_group_finish, 80 ec_GF2m_simple_group_finish,
@@ -103,7 +93,9 @@ const EC_METHOD *EC_GF2m_simple_method(void)
103 0 /* get_Jprojective_coordinates_GFp */, 93 0 /* get_Jprojective_coordinates_GFp */,
104 ec_GF2m_simple_point_set_affine_coordinates, 94 ec_GF2m_simple_point_set_affine_coordinates,
105 ec_GF2m_simple_point_get_affine_coordinates, 95 ec_GF2m_simple_point_get_affine_coordinates,
106 0,0,0, 96 ec_GF2m_simple_set_compressed_coordinates,
97 ec_GF2m_simple_point2oct,
98 ec_GF2m_simple_oct2point,
107 ec_GF2m_simple_add, 99 ec_GF2m_simple_add,
108 ec_GF2m_simple_dbl, 100 ec_GF2m_simple_dbl,
109 ec_GF2m_simple_invert, 101 ec_GF2m_simple_invert,
@@ -126,7 +118,6 @@ const EC_METHOD *EC_GF2m_simple_method(void)
126 0 /* field_set_to_one */ }; 118 0 /* field_set_to_one */ };
127 119
128 return &ret; 120 return &ret;
129#endif
130 } 121 }
131 122
132 123
@@ -414,6 +405,340 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_
414 return ret; 405 return ret;
415 } 406 }
416 407
408
409/* Calculates and sets the affine coordinates of an EC_POINT from the given
410 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
411 * Note that the simple implementation only uses affine coordinates.
412 *
413 * The method is from the following publication:
414 *
415 * Harper, Menezes, Vanstone:
416 * "Public-Key Cryptosystems with Very Small Key Lengths",
417 * EUROCRYPT '92, Springer-Verlag LNCS 658,
418 * published February 1993
419 *
420 * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
421 * the same method, but claim no priority date earlier than July 29, 1994
422 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
423 */
424int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
425 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
426 {
427 BN_CTX *new_ctx = NULL;
428 BIGNUM *tmp, *x, *y, *z;
429 int ret = 0, z0;
430
431 /* clear error queue */
432 ERR_clear_error();
433
434 if (ctx == NULL)
435 {
436 ctx = new_ctx = BN_CTX_new();
437 if (ctx == NULL)
438 return 0;
439 }
440
441 y_bit = (y_bit != 0) ? 1 : 0;
442
443 BN_CTX_start(ctx);
444 tmp = BN_CTX_get(ctx);
445 x = BN_CTX_get(ctx);
446 y = BN_CTX_get(ctx);
447 z = BN_CTX_get(ctx);
448 if (z == NULL) goto err;
449
450 if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
451 if (BN_is_zero(x))
452 {
453 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
454 }
455 else
456 {
457 if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
458 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
459 if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
460 if (!BN_GF2m_add(tmp, x, tmp)) goto err;
461 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
462 {
463 unsigned long err = ERR_peek_last_error();
464
465 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
466 {
467 ERR_clear_error();
468 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
469 }
470 else
471 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
472 goto err;
473 }
474 z0 = (BN_is_odd(z)) ? 1 : 0;
475 if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
476 if (z0 != y_bit)
477 {
478 if (!BN_GF2m_add(y, y, x)) goto err;
479 }
480 }
481
482 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
483
484 ret = 1;
485
486 err:
487 BN_CTX_end(ctx);
488 if (new_ctx != NULL)
489 BN_CTX_free(new_ctx);
490 return ret;
491 }
492
493
494/* Converts an EC_POINT to an octet string.
495 * If buf is NULL, the encoded length will be returned.
496 * If the length len of buf is smaller than required an error will be returned.
497 */
498size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
499 unsigned char *buf, size_t len, BN_CTX *ctx)
500 {
501 size_t ret;
502 BN_CTX *new_ctx = NULL;
503 int used_ctx = 0;
504 BIGNUM *x, *y, *yxi;
505 size_t field_len, i, skip;
506
507 if ((form != POINT_CONVERSION_COMPRESSED)
508 && (form != POINT_CONVERSION_UNCOMPRESSED)
509 && (form != POINT_CONVERSION_HYBRID))
510 {
511 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
512 goto err;
513 }
514
515 if (EC_POINT_is_at_infinity(group, point))
516 {
517 /* encodes to a single 0 octet */
518 if (buf != NULL)
519 {
520 if (len < 1)
521 {
522 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
523 return 0;
524 }
525 buf[0] = 0;
526 }
527 return 1;
528 }
529
530
531 /* ret := required output buffer length */
532 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
533 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
534
535 /* if 'buf' is NULL, just return required length */
536 if (buf != NULL)
537 {
538 if (len < ret)
539 {
540 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
541 goto err;
542 }
543
544 if (ctx == NULL)
545 {
546 ctx = new_ctx = BN_CTX_new();
547 if (ctx == NULL)
548 return 0;
549 }
550
551 BN_CTX_start(ctx);
552 used_ctx = 1;
553 x = BN_CTX_get(ctx);
554 y = BN_CTX_get(ctx);
555 yxi = BN_CTX_get(ctx);
556 if (yxi == NULL) goto err;
557
558 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
559
560 buf[0] = form;
561 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
562 {
563 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
564 if (BN_is_odd(yxi)) buf[0]++;
565 }
566
567 i = 1;
568
569 skip = field_len - BN_num_bytes(x);
570 if (skip > field_len)
571 {
572 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
573 goto err;
574 }
575 while (skip > 0)
576 {
577 buf[i++] = 0;
578 skip--;
579 }
580 skip = BN_bn2bin(x, buf + i);
581 i += skip;
582 if (i != 1 + field_len)
583 {
584 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
585 goto err;
586 }
587
588 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
589 {
590 skip = field_len - BN_num_bytes(y);
591 if (skip > field_len)
592 {
593 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
594 goto err;
595 }
596 while (skip > 0)
597 {
598 buf[i++] = 0;
599 skip--;
600 }
601 skip = BN_bn2bin(y, buf + i);
602 i += skip;
603 }
604
605 if (i != ret)
606 {
607 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
608 goto err;
609 }
610 }
611
612 if (used_ctx)
613 BN_CTX_end(ctx);
614 if (new_ctx != NULL)
615 BN_CTX_free(new_ctx);
616 return ret;
617
618 err:
619 if (used_ctx)
620 BN_CTX_end(ctx);
621 if (new_ctx != NULL)
622 BN_CTX_free(new_ctx);
623 return 0;
624 }
625
626
627/* Converts an octet string representation to an EC_POINT.
628 * Note that the simple implementation only uses affine coordinates.
629 */
630int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
631 const unsigned char *buf, size_t len, BN_CTX *ctx)
632 {
633 point_conversion_form_t form;
634 int y_bit;
635 BN_CTX *new_ctx = NULL;
636 BIGNUM *x, *y, *yxi;
637 size_t field_len, enc_len;
638 int ret = 0;
639
640 if (len == 0)
641 {
642 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
643 return 0;
644 }
645 form = buf[0];
646 y_bit = form & 1;
647 form = form & ~1U;
648 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
649 && (form != POINT_CONVERSION_UNCOMPRESSED)
650 && (form != POINT_CONVERSION_HYBRID))
651 {
652 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
653 return 0;
654 }
655 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
656 {
657 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
658 return 0;
659 }
660
661 if (form == 0)
662 {
663 if (len != 1)
664 {
665 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
666 return 0;
667 }
668
669 return EC_POINT_set_to_infinity(group, point);
670 }
671
672 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
673 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
674
675 if (len != enc_len)
676 {
677 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
678 return 0;
679 }
680
681 if (ctx == NULL)
682 {
683 ctx = new_ctx = BN_CTX_new();
684 if (ctx == NULL)
685 return 0;
686 }
687
688 BN_CTX_start(ctx);
689 x = BN_CTX_get(ctx);
690 y = BN_CTX_get(ctx);
691 yxi = BN_CTX_get(ctx);
692 if (yxi == NULL) goto err;
693
694 if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
695 if (BN_ucmp(x, &group->field) >= 0)
696 {
697 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
698 goto err;
699 }
700
701 if (form == POINT_CONVERSION_COMPRESSED)
702 {
703 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
704 }
705 else
706 {
707 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
708 if (BN_ucmp(y, &group->field) >= 0)
709 {
710 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
711 goto err;
712 }
713 if (form == POINT_CONVERSION_HYBRID)
714 {
715 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
716 if (y_bit != BN_is_odd(yxi))
717 {
718 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
719 goto err;
720 }
721 }
722
723 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
724 }
725
726 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
727 {
728 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
729 goto err;
730 }
731
732 ret = 1;
733
734 err:
735 BN_CTX_end(ctx);
736 if (new_ctx != NULL)
737 BN_CTX_free(new_ctx);
738 return ret;
739 }
740
741
417/* Computes a + b and stores the result in r. r could be a or b, a could be b. 742/* 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. 743 * Uses algorithm A.10.2 of IEEE P1363.
419 */ 744 */
@@ -715,5 +1040,3 @@ int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
715 { 1040 {
716 return BN_GF2m_mod_div(r, a, b, &group->field, ctx); 1041 return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
717 } 1042 }
718
719#endif
diff --git a/src/lib/libcrypto/ec/ec_cvt.c b/src/lib/libcrypto/ec/ec_cvt.c
index bfcbab35fe..d45640bab9 100644
--- a/src/lib/libcrypto/ec/ec_cvt.c
+++ b/src/lib/libcrypto/ec/ec_cvt.c
@@ -78,32 +78,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
78 const EC_METHOD *meth; 78 const EC_METHOD *meth;
79 EC_GROUP *ret; 79 EC_GROUP *ret;
80 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(); 81 meth = EC_GFp_nist_method();
106#endif
107 82
108 ret = EC_GROUP_new(meth); 83 ret = EC_GROUP_new(meth);
109 if (ret == NULL) 84 if (ret == NULL)
@@ -147,7 +122,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
147 return ret; 122 return ret;
148 } 123 }
149 124
150#ifndef OPENSSL_NO_EC2M 125
151EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 126EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
152 { 127 {
153 const EC_METHOD *meth; 128 const EC_METHOD *meth;
@@ -167,4 +142,3 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM
167 142
168 return ret; 143 return ret;
169 } 144 }
170#endif
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
index 0d19398731..84b4833371 100644
--- a/src/lib/libcrypto/ec/ec_err.c
+++ b/src/lib/libcrypto/ec/ec_err.c
@@ -1,6 +1,6 @@
1/* crypto/ec/ec_err.c */ 1/* crypto/ec/ec_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -70,7 +70,6 @@
70 70
71static ERR_STRING_DATA EC_str_functs[]= 71static ERR_STRING_DATA EC_str_functs[]=
72 { 72 {
73{ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"},
74{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"}, 73{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
75{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"}, 74{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
76{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"}, 75{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
@@ -113,15 +112,6 @@ static ERR_STRING_DATA EC_str_functs[]=
113{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"}, 112{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"}, 113{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"}, 114{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"}, 115{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"}, 116{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"}, 117{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
@@ -164,7 +154,6 @@ static ERR_STRING_DATA EC_str_functs[]=
164{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"}, 154{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
165{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"}, 155{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
166{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"}, 156{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"}, 157{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
169{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, 158{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
170{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, 159{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
@@ -195,9 +184,6 @@ static ERR_STRING_DATA EC_str_functs[]=
195{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"}, 184{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
196{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"}, 185{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
197{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"}, 186{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"}, 187{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
202{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"}, 188{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
203{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"}, 189{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
@@ -213,15 +199,12 @@ static ERR_STRING_DATA EC_str_reasons[]=
213 { 199 {
214{ERR_REASON(EC_R_ASN1_ERROR) ,"asn1 error"}, 200{ERR_REASON(EC_R_ASN1_ERROR) ,"asn1 error"},
215{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"}, 201{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"}, 202{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"}, 203{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
220{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"}, 204{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"},
221{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"}, 205{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"}, 206{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"}, 207{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"}, 208{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
226{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"}, 209{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
227{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"}, 210{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"},
@@ -256,7 +239,6 @@ static ERR_STRING_DATA EC_str_reasons[]=
256{ERR_REASON(EC_R_UNKNOWN_GROUP) ,"unknown group"}, 239{ERR_REASON(EC_R_UNKNOWN_GROUP) ,"unknown group"},
257{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"}, 240{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"},
258{ERR_REASON(EC_R_UNSUPPORTED_FIELD) ,"unsupported field"}, 241{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"}, 242{ERR_REASON(EC_R_WRONG_ORDER) ,"wrong order"},
261{0,NULL} 243{0,NULL}
262 }; 244 };
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h
index da7967df38..3e2c34b0bc 100644
--- a/src/lib/libcrypto/ec/ec_lcl.h
+++ b/src/lib/libcrypto/ec/ec_lcl.h
@@ -3,7 +3,7 @@
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -82,15 +82,10 @@
82# endif 82# endif
83#endif 83#endif
84 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, 85/* Structure details are not part of the exported interface,
89 * so all this may change in future versions. */ 86 * so all this may change in future versions. */
90 87
91struct ec_method_st { 88struct ec_method_st {
92 /* Various method flags */
93 int flags;
94 /* used by EC_METHOD_get_field_type: */ 89 /* used by EC_METHOD_get_field_type: */
95 int field_type; /* a NID */ 90 int field_type; /* a NID */
96 91
@@ -249,7 +244,6 @@ struct ec_key_st {
249 point_conversion_form_t conv_form; 244 point_conversion_form_t conv_form;
250 245
251 int references; 246 int references;
252 int flags;
253 247
254 EC_EXTRA_DATA *method_data; 248 EC_EXTRA_DATA *method_data;
255} /* EC_KEY */; 249} /* EC_KEY */;
@@ -397,50 +391,3 @@ int 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 *); 391 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
398int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); 392int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
399int ec_GF2m_have_precompute_mult(const EC_GROUP *group); 393int 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
index 25247b5803..dd7da0fcf9 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -425,7 +425,7 @@ int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *
425 return group->meth->group_get_curve(group, p, a, b, ctx); 425 return group->meth->group_get_curve(group, p, a, b, ctx);
426 } 426 }
427 427
428#ifndef OPENSSL_NO_EC2M 428
429int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 429int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
430 { 430 {
431 if (group->meth->group_set_curve == 0) 431 if (group->meth->group_set_curve == 0)
@@ -446,7 +446,7 @@ int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM
446 } 446 }
447 return group->meth->group_get_curve(group, p, a, b, ctx); 447 return group->meth->group_get_curve(group, p, a, b, ctx);
448 } 448 }
449#endif 449
450 450
451int EC_GROUP_get_degree(const EC_GROUP *group) 451int EC_GROUP_get_degree(const EC_GROUP *group)
452 { 452 {
@@ -856,7 +856,7 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
856 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 856 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
857 } 857 }
858 858
859#ifndef OPENSSL_NO_EC2M 859
860int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point, 860int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
861 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 861 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
862 { 862 {
@@ -872,7 +872,7 @@ int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
872 } 872 }
873 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 873 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
874 } 874 }
875#endif 875
876 876
877int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, 877int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
878 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 878 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
@@ -890,7 +890,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *p
890 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 890 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
891 } 891 }
892 892
893#ifndef OPENSSL_NO_EC2M 893
894int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point, 894int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
895 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 895 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
896 { 896 {
@@ -906,7 +906,75 @@ int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *
906 } 906 }
907 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 907 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
908 } 908 }
909#endif 909
910
911int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
912 const BIGNUM *x, int y_bit, BN_CTX *ctx)
913 {
914 if (group->meth->point_set_compressed_coordinates == 0)
915 {
916 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
917 return 0;
918 }
919 if (group->meth != point->meth)
920 {
921 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
922 return 0;
923 }
924 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
925 }
926
927
928int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
929 const BIGNUM *x, int y_bit, BN_CTX *ctx)
930 {
931 if (group->meth->point_set_compressed_coordinates == 0)
932 {
933 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
934 return 0;
935 }
936 if (group->meth != point->meth)
937 {
938 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
939 return 0;
940 }
941 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
942 }
943
944
945size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
946 unsigned char *buf, size_t len, BN_CTX *ctx)
947 {
948 if (group->meth->point2oct == 0)
949 {
950 ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
951 return 0;
952 }
953 if (group->meth != point->meth)
954 {
955 ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
956 return 0;
957 }
958 return group->meth->point2oct(group, point, form, buf, len, ctx);
959 }
960
961
962int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
963 const unsigned char *buf, size_t len, BN_CTX *ctx)
964 {
965 if (group->meth->oct2point == 0)
966 {
967 ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
968 return 0;
969 }
970 if (group->meth != point->meth)
971 {
972 ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
973 return 0;
974 }
975 return group->meth->oct2point(group, point, buf, len, ctx);
976 }
977
910 978
911int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) 979int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
912 { 980 {
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
index 079e47431b..9fc4a466a5 100644
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ b/src/lib/libcrypto/ec/ecp_mont.c
@@ -63,20 +63,12 @@
63 63
64#include <openssl/err.h> 64#include <openssl/err.h>
65 65
66#ifdef OPENSSL_FIPS
67#include <openssl/fips.h>
68#endif
69
70#include "ec_lcl.h" 66#include "ec_lcl.h"
71 67
72 68
73const EC_METHOD *EC_GFp_mont_method(void) 69const EC_METHOD *EC_GFp_mont_method(void)
74 { 70 {
75#ifdef OPENSSL_FIPS
76 return fips_ec_gfp_mont_method();
77#else
78 static const EC_METHOD ret = { 71 static const EC_METHOD ret = {
79 EC_FLAGS_DEFAULT_OCT,
80 NID_X9_62_prime_field, 72 NID_X9_62_prime_field,
81 ec_GFp_mont_group_init, 73 ec_GFp_mont_group_init,
82 ec_GFp_mont_group_finish, 74 ec_GFp_mont_group_finish,
@@ -95,7 +87,9 @@ const EC_METHOD *EC_GFp_mont_method(void)
95 ec_GFp_simple_get_Jprojective_coordinates_GFp, 87 ec_GFp_simple_get_Jprojective_coordinates_GFp,
96 ec_GFp_simple_point_set_affine_coordinates, 88 ec_GFp_simple_point_set_affine_coordinates,
97 ec_GFp_simple_point_get_affine_coordinates, 89 ec_GFp_simple_point_get_affine_coordinates,
98 0,0,0, 90 ec_GFp_simple_set_compressed_coordinates,
91 ec_GFp_simple_point2oct,
92 ec_GFp_simple_oct2point,
99 ec_GFp_simple_add, 93 ec_GFp_simple_add,
100 ec_GFp_simple_dbl, 94 ec_GFp_simple_dbl,
101 ec_GFp_simple_invert, 95 ec_GFp_simple_invert,
@@ -114,9 +108,7 @@ const EC_METHOD *EC_GFp_mont_method(void)
114 ec_GFp_mont_field_decode, 108 ec_GFp_mont_field_decode,
115 ec_GFp_mont_field_set_to_one }; 109 ec_GFp_mont_field_set_to_one };
116 110
117
118 return &ret; 111 return &ret;
119#endif
120 } 112 }
121 113
122 114
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
index aad2d5f443..2a5682ea41 100644
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ b/src/lib/libcrypto/ec/ecp_nist.c
@@ -67,17 +67,9 @@
67#include <openssl/obj_mac.h> 67#include <openssl/obj_mac.h>
68#include "ec_lcl.h" 68#include "ec_lcl.h"
69 69
70#ifdef OPENSSL_FIPS
71#include <openssl/fips.h>
72#endif
73
74const EC_METHOD *EC_GFp_nist_method(void) 70const EC_METHOD *EC_GFp_nist_method(void)
75 { 71 {
76#ifdef OPENSSL_FIPS
77 return fips_ec_gfp_nist_method();
78#else
79 static const EC_METHOD ret = { 72 static const EC_METHOD ret = {
80 EC_FLAGS_DEFAULT_OCT,
81 NID_X9_62_prime_field, 73 NID_X9_62_prime_field,
82 ec_GFp_simple_group_init, 74 ec_GFp_simple_group_init,
83 ec_GFp_simple_group_finish, 75 ec_GFp_simple_group_finish,
@@ -96,7 +88,9 @@ const EC_METHOD *EC_GFp_nist_method(void)
96 ec_GFp_simple_get_Jprojective_coordinates_GFp, 88 ec_GFp_simple_get_Jprojective_coordinates_GFp,
97 ec_GFp_simple_point_set_affine_coordinates, 89 ec_GFp_simple_point_set_affine_coordinates,
98 ec_GFp_simple_point_get_affine_coordinates, 90 ec_GFp_simple_point_get_affine_coordinates,
99 0,0,0, 91 ec_GFp_simple_set_compressed_coordinates,
92 ec_GFp_simple_point2oct,
93 ec_GFp_simple_oct2point,
100 ec_GFp_simple_add, 94 ec_GFp_simple_add,
101 ec_GFp_simple_dbl, 95 ec_GFp_simple_dbl,
102 ec_GFp_simple_invert, 96 ec_GFp_simple_invert,
@@ -116,7 +110,6 @@ const EC_METHOD *EC_GFp_nist_method(void)
116 0 /* field_set_to_one */ }; 110 0 /* field_set_to_one */ };
117 111
118 return &ret; 112 return &ret;
119#endif
120 } 113 }
121 114
122int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) 115int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c
index 7cbb321f9a..66a92e2a90 100644
--- a/src/lib/libcrypto/ec/ecp_smpl.c
+++ b/src/lib/libcrypto/ec/ecp_smpl.c
@@ -65,19 +65,11 @@
65#include <openssl/err.h> 65#include <openssl/err.h>
66#include <openssl/symhacks.h> 66#include <openssl/symhacks.h>
67 67
68#ifdef OPENSSL_FIPS
69#include <openssl/fips.h>
70#endif
71
72#include "ec_lcl.h" 68#include "ec_lcl.h"
73 69
74const EC_METHOD *EC_GFp_simple_method(void) 70const EC_METHOD *EC_GFp_simple_method(void)
75 { 71 {
76#ifdef OPENSSL_FIPS
77 return fips_ec_gfp_simple_method();
78#else
79 static const EC_METHOD ret = { 72 static const EC_METHOD ret = {
80 EC_FLAGS_DEFAULT_OCT,
81 NID_X9_62_prime_field, 73 NID_X9_62_prime_field,
82 ec_GFp_simple_group_init, 74 ec_GFp_simple_group_init,
83 ec_GFp_simple_group_finish, 75 ec_GFp_simple_group_finish,
@@ -96,7 +88,9 @@ const EC_METHOD *EC_GFp_simple_method(void)
96 ec_GFp_simple_get_Jprojective_coordinates_GFp, 88 ec_GFp_simple_get_Jprojective_coordinates_GFp,
97 ec_GFp_simple_point_set_affine_coordinates, 89 ec_GFp_simple_point_set_affine_coordinates,
98 ec_GFp_simple_point_get_affine_coordinates, 90 ec_GFp_simple_point_get_affine_coordinates,
99 0,0,0, 91 ec_GFp_simple_set_compressed_coordinates,
92 ec_GFp_simple_point2oct,
93 ec_GFp_simple_oct2point,
100 ec_GFp_simple_add, 94 ec_GFp_simple_add,
101 ec_GFp_simple_dbl, 95 ec_GFp_simple_dbl,
102 ec_GFp_simple_invert, 96 ec_GFp_simple_invert,
@@ -116,7 +110,6 @@ const EC_METHOD *EC_GFp_simple_method(void)
116 0 /* field_set_to_one */ }; 110 0 /* field_set_to_one */ };
117 111
118 return &ret; 112 return &ret;
119#endif
120 } 113 }
121 114
122 115
@@ -640,6 +633,372 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_P
640 return ret; 633 return ret;
641 } 634 }
642 635
636
637int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
638 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
639 {
640 BN_CTX *new_ctx = NULL;
641 BIGNUM *tmp1, *tmp2, *x, *y;
642 int ret = 0;
643
644 /* clear error queue*/
645 ERR_clear_error();
646
647 if (ctx == NULL)
648 {
649 ctx = new_ctx = BN_CTX_new();
650 if (ctx == NULL)
651 return 0;
652 }
653
654 y_bit = (y_bit != 0);
655
656 BN_CTX_start(ctx);
657 tmp1 = BN_CTX_get(ctx);
658 tmp2 = BN_CTX_get(ctx);
659 x = BN_CTX_get(ctx);
660 y = BN_CTX_get(ctx);
661 if (y == NULL) goto err;
662
663 /* Recover y. We have a Weierstrass equation
664 * y^2 = x^3 + a*x + b,
665 * so y is one of the square roots of x^3 + a*x + b.
666 */
667
668 /* tmp1 := x^3 */
669 if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
670 if (group->meth->field_decode == 0)
671 {
672 /* field_{sqr,mul} work on standard representation */
673 if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
674 if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
675 }
676 else
677 {
678 if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
679 if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
680 }
681
682 /* tmp1 := tmp1 + a*x */
683 if (group->a_is_minus3)
684 {
685 if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
686 if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
687 if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
688 }
689 else
690 {
691 if (group->meth->field_decode)
692 {
693 if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
694 if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
695 }
696 else
697 {
698 /* field_mul works on standard representation */
699 if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
700 }
701
702 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
703 }
704
705 /* tmp1 := tmp1 + b */
706 if (group->meth->field_decode)
707 {
708 if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
709 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
710 }
711 else
712 {
713 if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
714 }
715
716 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
717 {
718 unsigned long err = ERR_peek_last_error();
719
720 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
721 {
722 ERR_clear_error();
723 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
724 }
725 else
726 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
727 goto err;
728 }
729
730 if (y_bit != BN_is_odd(y))
731 {
732 if (BN_is_zero(y))
733 {
734 int kron;
735
736 kron = BN_kronecker(x, &group->field, ctx);
737 if (kron == -2) goto err;
738
739 if (kron == 1)
740 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
741 else
742 /* BN_mod_sqrt() should have cought this error (not a square) */
743 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
744 goto err;
745 }
746 if (!BN_usub(y, &group->field, y)) goto err;
747 }
748 if (y_bit != BN_is_odd(y))
749 {
750 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
751 goto err;
752 }
753
754 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
755
756 ret = 1;
757
758 err:
759 BN_CTX_end(ctx);
760 if (new_ctx != NULL)
761 BN_CTX_free(new_ctx);
762 return ret;
763 }
764
765
766size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
767 unsigned char *buf, size_t len, BN_CTX *ctx)
768 {
769 size_t ret;
770 BN_CTX *new_ctx = NULL;
771 int used_ctx = 0;
772 BIGNUM *x, *y;
773 size_t field_len, i, skip;
774
775 if ((form != POINT_CONVERSION_COMPRESSED)
776 && (form != POINT_CONVERSION_UNCOMPRESSED)
777 && (form != POINT_CONVERSION_HYBRID))
778 {
779 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
780 goto err;
781 }
782
783 if (EC_POINT_is_at_infinity(group, point))
784 {
785 /* encodes to a single 0 octet */
786 if (buf != NULL)
787 {
788 if (len < 1)
789 {
790 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
791 return 0;
792 }
793 buf[0] = 0;
794 }
795 return 1;
796 }
797
798
799 /* ret := required output buffer length */
800 field_len = BN_num_bytes(&group->field);
801 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
802
803 /* if 'buf' is NULL, just return required length */
804 if (buf != NULL)
805 {
806 if (len < ret)
807 {
808 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
809 goto err;
810 }
811
812 if (ctx == NULL)
813 {
814 ctx = new_ctx = BN_CTX_new();
815 if (ctx == NULL)
816 return 0;
817 }
818
819 BN_CTX_start(ctx);
820 used_ctx = 1;
821 x = BN_CTX_get(ctx);
822 y = BN_CTX_get(ctx);
823 if (y == NULL) goto err;
824
825 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
826
827 if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
828 buf[0] = form + 1;
829 else
830 buf[0] = form;
831
832 i = 1;
833
834 skip = field_len - BN_num_bytes(x);
835 if (skip > field_len)
836 {
837 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
838 goto err;
839 }
840 while (skip > 0)
841 {
842 buf[i++] = 0;
843 skip--;
844 }
845 skip = BN_bn2bin(x, buf + i);
846 i += skip;
847 if (i != 1 + field_len)
848 {
849 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
850 goto err;
851 }
852
853 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
854 {
855 skip = field_len - BN_num_bytes(y);
856 if (skip > field_len)
857 {
858 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
859 goto err;
860 }
861 while (skip > 0)
862 {
863 buf[i++] = 0;
864 skip--;
865 }
866 skip = BN_bn2bin(y, buf + i);
867 i += skip;
868 }
869
870 if (i != ret)
871 {
872 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
873 goto err;
874 }
875 }
876
877 if (used_ctx)
878 BN_CTX_end(ctx);
879 if (new_ctx != NULL)
880 BN_CTX_free(new_ctx);
881 return ret;
882
883 err:
884 if (used_ctx)
885 BN_CTX_end(ctx);
886 if (new_ctx != NULL)
887 BN_CTX_free(new_ctx);
888 return 0;
889 }
890
891
892int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
893 const unsigned char *buf, size_t len, BN_CTX *ctx)
894 {
895 point_conversion_form_t form;
896 int y_bit;
897 BN_CTX *new_ctx = NULL;
898 BIGNUM *x, *y;
899 size_t field_len, enc_len;
900 int ret = 0;
901
902 if (len == 0)
903 {
904 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
905 return 0;
906 }
907 form = buf[0];
908 y_bit = form & 1;
909 form = form & ~1U;
910 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
911 && (form != POINT_CONVERSION_UNCOMPRESSED)
912 && (form != POINT_CONVERSION_HYBRID))
913 {
914 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
915 return 0;
916 }
917 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
918 {
919 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
920 return 0;
921 }
922
923 if (form == 0)
924 {
925 if (len != 1)
926 {
927 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
928 return 0;
929 }
930
931 return EC_POINT_set_to_infinity(group, point);
932 }
933
934 field_len = BN_num_bytes(&group->field);
935 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
936
937 if (len != enc_len)
938 {
939 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
940 return 0;
941 }
942
943 if (ctx == NULL)
944 {
945 ctx = new_ctx = BN_CTX_new();
946 if (ctx == NULL)
947 return 0;
948 }
949
950 BN_CTX_start(ctx);
951 x = BN_CTX_get(ctx);
952 y = BN_CTX_get(ctx);
953 if (y == NULL) goto err;
954
955 if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
956 if (BN_ucmp(x, &group->field) >= 0)
957 {
958 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
959 goto err;
960 }
961
962 if (form == POINT_CONVERSION_COMPRESSED)
963 {
964 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
965 }
966 else
967 {
968 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
969 if (BN_ucmp(y, &group->field) >= 0)
970 {
971 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
972 goto err;
973 }
974 if (form == POINT_CONVERSION_HYBRID)
975 {
976 if (y_bit != BN_is_odd(y))
977 {
978 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
979 goto err;
980 }
981 }
982
983 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
984 }
985
986 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
987 {
988 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
989 goto err;
990 }
991
992 ret = 1;
993
994 err:
995 BN_CTX_end(ctx);
996 if (new_ctx != NULL)
997 BN_CTX_free(new_ctx);
998 return ret;
999 }
1000
1001
643int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) 1002int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
644 { 1003 {
645 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); 1004 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
diff --git a/src/lib/libcrypto/ec/ectest.c b/src/lib/libcrypto/ec/ectest.c
new file mode 100644
index 0000000000..7509cb9c7c
--- /dev/null
+++ b/src/lib/libcrypto/ec/ectest.c
@@ -0,0 +1,1334 @@
1/* crypto/ec/ectest.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 *
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 <stdio.h>
73#include <stdlib.h>
74#ifdef FLAT_INC
75#include "e_os.h"
76#else
77#include "../e_os.h"
78#endif
79#include <string.h>
80#include <time.h>
81
82
83#ifdef OPENSSL_NO_EC
84int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
85#else
86
87
88#include <openssl/ec.h>
89#ifndef OPENSSL_NO_ENGINE
90#include <openssl/engine.h>
91#endif
92#include <openssl/err.h>
93#include <openssl/obj_mac.h>
94#include <openssl/objects.h>
95#include <openssl/rand.h>
96#include <openssl/bn.h>
97
98#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
99/* suppress "too big too optimize" warning */
100#pragma warning(disable:4959)
101#endif
102
103#define ABORT do { \
104 fflush(stdout); \
105 fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
106 ERR_print_errors_fp(stderr); \
107 EXIT(1); \
108} while (0)
109
110void prime_field_tests(void);
111void char2_field_tests(void);
112void internal_curve_test(void);
113
114#define TIMING_BASE_PT 0
115#define TIMING_RAND_PT 1
116#define TIMING_SIMUL 2
117
118#if 0
119static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
120 {
121 clock_t clck;
122 int i, j;
123 BIGNUM *s;
124 BIGNUM *r[10], *r0[10];
125 EC_POINT *P;
126
127 s = BN_new();
128 if (s == NULL) ABORT;
129
130 fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
131 if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
132 fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
133 fflush(stdout);
134
135 P = EC_POINT_new(group);
136 if (P == NULL) ABORT;
137 EC_POINT_copy(P, EC_GROUP_get0_generator(group));
138
139 for (i = 0; i < 10; i++)
140 {
141 if ((r[i] = BN_new()) == NULL) ABORT;
142 if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) ABORT;
143 if (type != TIMING_BASE_PT)
144 {
145 if ((r0[i] = BN_new()) == NULL) ABORT;
146 if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) ABORT;
147 }
148 }
149
150 clck = clock();
151 for (i = 0; i < 10; i++)
152 {
153 for (j = 0; j < 10; j++)
154 {
155 if (!EC_POINT_mul(group, P, (type != TIMING_RAND_PT) ? r[i] : NULL,
156 (type != TIMING_BASE_PT) ? P : NULL, (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) ABORT;
157 }
158 }
159 clck = clock() - clck;
160
161 fprintf(stdout, "\n");
162
163#ifdef CLOCKS_PER_SEC
164 /* "To determine the time in seconds, the value returned
165 * by the clock function should be divided by the value
166 * of the macro CLOCKS_PER_SEC."
167 * -- ISO/IEC 9899 */
168# define UNIT "s"
169#else
170 /* "`CLOCKS_PER_SEC' undeclared (first use this function)"
171 * -- cc on NeXTstep/OpenStep */
172# define UNIT "units"
173# define CLOCKS_PER_SEC 1
174#endif
175
176 if (type == TIMING_BASE_PT) {
177 fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
178 "base point multiplications", (double)clck/CLOCKS_PER_SEC);
179 } else if (type == TIMING_RAND_PT) {
180 fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
181 "random point multiplications", (double)clck/CLOCKS_PER_SEC);
182 } else if (type == TIMING_SIMUL) {
183 fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
184 "s*P+t*Q operations", (double)clck/CLOCKS_PER_SEC);
185 }
186 fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));
187
188 EC_POINT_free(P);
189 BN_free(s);
190 for (i = 0; i < 10; i++)
191 {
192 BN_free(r[i]);
193 if (type != TIMING_BASE_PT) BN_free(r0[i]);
194 }
195 }
196#endif
197
198void prime_field_tests()
199 {
200 BN_CTX *ctx = NULL;
201 BIGNUM *p, *a, *b;
202 EC_GROUP *group;
203 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
204 EC_POINT *P, *Q, *R;
205 BIGNUM *x, *y, *z;
206 unsigned char buf[100];
207 size_t i, len;
208 int k;
209
210#if 1 /* optional */
211 ctx = BN_CTX_new();
212 if (!ctx) ABORT;
213#endif
214
215 p = BN_new();
216 a = BN_new();
217 b = BN_new();
218 if (!p || !a || !b) ABORT;
219
220 if (!BN_hex2bn(&p, "17")) ABORT;
221 if (!BN_hex2bn(&a, "1")) ABORT;
222 if (!BN_hex2bn(&b, "1")) ABORT;
223
224 group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
225 * so that the library gets to choose the EC_METHOD */
226 if (!group) ABORT;
227
228 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
229
230 {
231 EC_GROUP *tmp;
232 tmp = EC_GROUP_new(EC_GROUP_method_of(group));
233 if (!tmp) ABORT;
234 if (!EC_GROUP_copy(tmp, group)) ABORT;
235 EC_GROUP_free(group);
236 group = tmp;
237 }
238
239 if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;
240
241 fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x");
242 BN_print_fp(stdout, p);
243 fprintf(stdout, ")\n a = 0x");
244 BN_print_fp(stdout, a);
245 fprintf(stdout, "\n b = 0x");
246 BN_print_fp(stdout, b);
247 fprintf(stdout, "\n");
248
249 P = EC_POINT_new(group);
250 Q = EC_POINT_new(group);
251 R = EC_POINT_new(group);
252 if (!P || !Q || !R) ABORT;
253
254 if (!EC_POINT_set_to_infinity(group, P)) ABORT;
255 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
256
257 buf[0] = 0;
258 if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
259
260 if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
261 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
262
263 x = BN_new();
264 y = BN_new();
265 z = BN_new();
266 if (!x || !y || !z) ABORT;
267
268 if (!BN_hex2bn(&x, "D")) ABORT;
269 if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
270 if (!EC_POINT_is_on_curve(group, Q, ctx))
271 {
272 if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
273 fprintf(stderr, "Point is not on curve: x = 0x");
274 BN_print_fp(stderr, x);
275 fprintf(stderr, ", y = 0x");
276 BN_print_fp(stderr, y);
277 fprintf(stderr, "\n");
278 ABORT;
279 }
280
281 fprintf(stdout, "A cyclic subgroup:\n");
282 k = 100;
283 do
284 {
285 if (k-- == 0) ABORT;
286
287 if (EC_POINT_is_at_infinity(group, P))
288 fprintf(stdout, " point at infinity\n");
289 else
290 {
291 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
292
293 fprintf(stdout, " x = 0x");
294 BN_print_fp(stdout, x);
295 fprintf(stdout, ", y = 0x");
296 BN_print_fp(stdout, y);
297 fprintf(stdout, "\n");
298 }
299
300 if (!EC_POINT_copy(R, P)) ABORT;
301 if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
302
303#if 0 /* optional */
304 {
305 EC_POINT *points[3];
306
307 points[0] = R;
308 points[1] = Q;
309 points[2] = P;
310 if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
311 }
312#endif
313
314 }
315 while (!EC_POINT_is_at_infinity(group, P));
316
317 if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
318 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
319
320 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
321 if (len == 0) ABORT;
322 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
323 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
324 fprintf(stdout, "Generator as octect string, compressed form:\n ");
325 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
326
327 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
328 if (len == 0) ABORT;
329 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
330 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
331 fprintf(stdout, "\nGenerator as octect string, uncompressed form:\n ");
332 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
333
334 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
335 if (len == 0) ABORT;
336 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
337 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
338 fprintf(stdout, "\nGenerator as octect string, hybrid form:\n ");
339 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
340
341 if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
342 fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x");
343 BN_print_fp(stdout, x);
344 fprintf(stdout, ", Y = 0x");
345 BN_print_fp(stdout, y);
346 fprintf(stdout, ", Z = 0x");
347 BN_print_fp(stdout, z);
348 fprintf(stdout, "\n");
349
350 if (!EC_POINT_invert(group, P, ctx)) ABORT;
351 if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
352
353
354 /* Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 2000)
355 * -- not a NIST curve, but commonly used */
356
357 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) ABORT;
358 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
359 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) ABORT;
360 if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) ABORT;
361 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
362
363 if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
364 if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
365 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
366 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
367 if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
368 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
369
370 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
371 fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x");
372 BN_print_fp(stdout, x);
373 fprintf(stdout, "\n y = 0x");
374 BN_print_fp(stdout, y);
375 fprintf(stdout, "\n");
376 /* G_y value taken from the standard: */
377 if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
378 if (0 != BN_cmp(y, z)) ABORT;
379
380 fprintf(stdout, "verify degree ...");
381 if (EC_GROUP_get_degree(group) != 160) ABORT;
382 fprintf(stdout, " ok\n");
383
384 fprintf(stdout, "verify group order ...");
385 fflush(stdout);
386 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
387 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
388 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
389 fprintf(stdout, ".");
390 fflush(stdout);
391 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
392 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
393 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
394 fprintf(stdout, " ok\n");
395
396 if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
397 if (!EC_GROUP_copy(P_160, group)) ABORT;
398
399
400 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
401
402 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
403 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
404 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
405 if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
406 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
407
408 if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
409 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
410 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
411 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
412 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
413
414 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
415 fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x");
416 BN_print_fp(stdout, x);
417 fprintf(stdout, "\n y = 0x");
418 BN_print_fp(stdout, y);
419 fprintf(stdout, "\n");
420 /* G_y value taken from the standard: */
421 if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
422 if (0 != BN_cmp(y, z)) ABORT;
423
424 fprintf(stdout, "verify degree ...");
425 if (EC_GROUP_get_degree(group) != 192) ABORT;
426 fprintf(stdout, " ok\n");
427
428 fprintf(stdout, "verify group order ...");
429 fflush(stdout);
430 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
431 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
432 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
433 fprintf(stdout, ".");
434 fflush(stdout);
435 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
436 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
437 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
438 fprintf(stdout, " ok\n");
439
440 if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
441 if (!EC_GROUP_copy(P_192, group)) ABORT;
442
443
444 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
445
446 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
447 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
448 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
449 if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
450 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
451
452 if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
453 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
454 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
455 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
456 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
457
458 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
459 fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x");
460 BN_print_fp(stdout, x);
461 fprintf(stdout, "\n y = 0x");
462 BN_print_fp(stdout, y);
463 fprintf(stdout, "\n");
464 /* G_y value taken from the standard: */
465 if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
466 if (0 != BN_cmp(y, z)) ABORT;
467
468 fprintf(stdout, "verify degree ...");
469 if (EC_GROUP_get_degree(group) != 224) ABORT;
470 fprintf(stdout, " ok\n");
471
472 fprintf(stdout, "verify group order ...");
473 fflush(stdout);
474 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
475 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
476 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
477 fprintf(stdout, ".");
478 fflush(stdout);
479 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
480 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
481 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
482 fprintf(stdout, " ok\n");
483
484 if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
485 if (!EC_GROUP_copy(P_224, group)) ABORT;
486
487
488 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
489
490 if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
491 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
492 if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
493 if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
494 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
495
496 if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
497 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
498 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
499 if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
500 "84F3B9CAC2FC632551")) ABORT;
501 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
502
503 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
504 fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x");
505 BN_print_fp(stdout, x);
506 fprintf(stdout, "\n y = 0x");
507 BN_print_fp(stdout, y);
508 fprintf(stdout, "\n");
509 /* G_y value taken from the standard: */
510 if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
511 if (0 != BN_cmp(y, z)) ABORT;
512
513 fprintf(stdout, "verify degree ...");
514 if (EC_GROUP_get_degree(group) != 256) ABORT;
515 fprintf(stdout, " ok\n");
516
517 fprintf(stdout, "verify group order ...");
518 fflush(stdout);
519 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
520 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
521 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
522 fprintf(stdout, ".");
523 fflush(stdout);
524 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
525 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
526 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
527 fprintf(stdout, " ok\n");
528
529 if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
530 if (!EC_GROUP_copy(P_256, group)) ABORT;
531
532
533 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
534
535 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
536 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
537 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
538 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
539 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
540 if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
541 "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
542 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
543
544 if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
545 "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
546 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
547 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
548 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
549 "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
550 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
551
552 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
553 fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x");
554 BN_print_fp(stdout, x);
555 fprintf(stdout, "\n y = 0x");
556 BN_print_fp(stdout, y);
557 fprintf(stdout, "\n");
558 /* G_y value taken from the standard: */
559 if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
560 "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
561 if (0 != BN_cmp(y, z)) ABORT;
562
563 fprintf(stdout, "verify degree ...");
564 if (EC_GROUP_get_degree(group) != 384) ABORT;
565 fprintf(stdout, " ok\n");
566
567 fprintf(stdout, "verify group order ...");
568 fflush(stdout);
569 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
570 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
571 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
572 fprintf(stdout, ".");
573 fflush(stdout);
574 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
575 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
576 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
577 fprintf(stdout, " ok\n");
578
579 if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
580 if (!EC_GROUP_copy(P_384, group)) ABORT;
581
582
583 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
584
585 if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
586 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
587 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
588 if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
589 if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
590 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
591 "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
592 if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
593 "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
594 "DF883D2C34F1EF451FD46B503F00")) ABORT;
595 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
596
597 if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
598 "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
599 "3C1856A429BF97E7E31C2E5BD66")) ABORT;
600 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
601 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
602 if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
603 "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
604 "C9B8899C47AEBB6FB71E91386409")) ABORT;
605 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
606
607 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
608 fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x");
609 BN_print_fp(stdout, x);
610 fprintf(stdout, "\n y = 0x");
611 BN_print_fp(stdout, y);
612 fprintf(stdout, "\n");
613 /* G_y value taken from the standard: */
614 if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
615 "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
616 "7086A272C24088BE94769FD16650")) ABORT;
617 if (0 != BN_cmp(y, z)) ABORT;
618
619 fprintf(stdout, "verify degree ...");
620 if (EC_GROUP_get_degree(group) != 521) ABORT;
621 fprintf(stdout, " ok\n");
622
623 fprintf(stdout, "verify group order ...");
624 fflush(stdout);
625 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
626 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
627 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
628 fprintf(stdout, ".");
629 fflush(stdout);
630 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
631 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
632 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
633 fprintf(stdout, " ok\n");
634
635 if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
636 if (!EC_GROUP_copy(P_521, group)) ABORT;
637
638
639 /* more tests using the last curve */
640
641 if (!EC_POINT_copy(Q, P)) ABORT;
642 if (EC_POINT_is_at_infinity(group, Q)) ABORT;
643 if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
644 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
645 if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
646
647 if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
648 if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
649 if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
650
651 {
652 const EC_POINT *points[4];
653 const BIGNUM *scalars[4];
654 BIGNUM scalar3;
655
656 if (EC_POINT_is_at_infinity(group, Q)) ABORT;
657 points[0] = Q;
658 points[1] = Q;
659 points[2] = Q;
660 points[3] = Q;
661
662 if (!BN_add(y, z, BN_value_one())) ABORT;
663 if (BN_is_odd(y)) ABORT;
664 if (!BN_rshift1(y, y)) ABORT;
665 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
666 scalars[1] = y;
667
668 fprintf(stdout, "combined multiplication ...");
669 fflush(stdout);
670
671 /* z is still the group order */
672 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
673 if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
674 if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
675 if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
676
677 fprintf(stdout, ".");
678 fflush(stdout);
679
680 if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
681 if (!BN_add(z, z, y)) ABORT;
682 BN_set_negative(z, 1);
683 scalars[0] = y;
684 scalars[1] = z; /* z = -(order + y) */
685
686 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
687 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
688
689 fprintf(stdout, ".");
690 fflush(stdout);
691
692 if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
693 if (!BN_add(z, x, y)) ABORT;
694 BN_set_negative(z, 1);
695 scalars[0] = x;
696 scalars[1] = y;
697 scalars[2] = z; /* z = -(x+y) */
698
699 BN_init(&scalar3);
700 BN_zero(&scalar3);
701 scalars[3] = &scalar3;
702
703 if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) ABORT;
704 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
705
706 fprintf(stdout, " ok\n\n");
707
708 BN_free(&scalar3);
709 }
710
711
712#if 0
713 timings(P_160, TIMING_BASE_PT, ctx);
714 timings(P_160, TIMING_RAND_PT, ctx);
715 timings(P_160, TIMING_SIMUL, ctx);
716 timings(P_192, TIMING_BASE_PT, ctx);
717 timings(P_192, TIMING_RAND_PT, ctx);
718 timings(P_192, TIMING_SIMUL, ctx);
719 timings(P_224, TIMING_BASE_PT, ctx);
720 timings(P_224, TIMING_RAND_PT, ctx);
721 timings(P_224, TIMING_SIMUL, ctx);
722 timings(P_256, TIMING_BASE_PT, ctx);
723 timings(P_256, TIMING_RAND_PT, ctx);
724 timings(P_256, TIMING_SIMUL, ctx);
725 timings(P_384, TIMING_BASE_PT, ctx);
726 timings(P_384, TIMING_RAND_PT, ctx);
727 timings(P_384, TIMING_SIMUL, ctx);
728 timings(P_521, TIMING_BASE_PT, ctx);
729 timings(P_521, TIMING_RAND_PT, ctx);
730 timings(P_521, TIMING_SIMUL, ctx);
731#endif
732
733
734 if (ctx)
735 BN_CTX_free(ctx);
736 BN_free(p); BN_free(a); BN_free(b);
737 EC_GROUP_free(group);
738 EC_POINT_free(P);
739 EC_POINT_free(Q);
740 EC_POINT_free(R);
741 BN_free(x); BN_free(y); BN_free(z);
742
743 if (P_160) EC_GROUP_free(P_160);
744 if (P_192) EC_GROUP_free(P_192);
745 if (P_224) EC_GROUP_free(P_224);
746 if (P_256) EC_GROUP_free(P_256);
747 if (P_384) EC_GROUP_free(P_384);
748 if (P_521) EC_GROUP_free(P_521);
749
750 }
751
752/* Change test based on whether binary point compression is enabled or not. */
753#ifdef OPENSSL_EC_BIN_PT_COMP
754#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
755 if (!BN_hex2bn(&x, _x)) ABORT; \
756 if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
757 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
758 if (!BN_hex2bn(&z, _order)) ABORT; \
759 if (!BN_hex2bn(&cof, _cof)) ABORT; \
760 if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
761 if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
762 fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \
763 BN_print_fp(stdout, x); \
764 fprintf(stdout, "\n y = 0x"); \
765 BN_print_fp(stdout, y); \
766 fprintf(stdout, "\n"); \
767 /* G_y value taken from the standard: */ \
768 if (!BN_hex2bn(&z, _y)) ABORT; \
769 if (0 != BN_cmp(y, z)) ABORT;
770#else
771#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
772 if (!BN_hex2bn(&x, _x)) ABORT; \
773 if (!BN_hex2bn(&y, _y)) ABORT; \
774 if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
775 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
776 if (!BN_hex2bn(&z, _order)) ABORT; \
777 if (!BN_hex2bn(&cof, _cof)) ABORT; \
778 if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
779 fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \
780 BN_print_fp(stdout, x); \
781 fprintf(stdout, "\n y = 0x"); \
782 BN_print_fp(stdout, y); \
783 fprintf(stdout, "\n");
784#endif
785
786#define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
787 if (!BN_hex2bn(&p, _p)) ABORT; \
788 if (!BN_hex2bn(&a, _a)) ABORT; \
789 if (!BN_hex2bn(&b, _b)) ABORT; \
790 if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
791 CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
792 fprintf(stdout, "verify degree ..."); \
793 if (EC_GROUP_get_degree(group) != _degree) ABORT; \
794 fprintf(stdout, " ok\n"); \
795 fprintf(stdout, "verify group order ..."); \
796 fflush(stdout); \
797 if (!EC_GROUP_get_order(group, z, ctx)) ABORT; \
798 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
799 if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
800 fprintf(stdout, "."); \
801 fflush(stdout); \
802 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; \
803 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
804 if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
805 fprintf(stdout, " ok\n"); \
806 if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
807 if (!EC_GROUP_copy(_variable, group)) ABORT;
808
809void char2_field_tests()
810 {
811 BN_CTX *ctx = NULL;
812 BIGNUM *p, *a, *b;
813 EC_GROUP *group;
814 EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
815 EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
816 EC_POINT *P, *Q, *R;
817 BIGNUM *x, *y, *z, *cof;
818 unsigned char buf[100];
819 size_t i, len;
820 int k;
821
822#if 1 /* optional */
823 ctx = BN_CTX_new();
824 if (!ctx) ABORT;
825#endif
826
827 p = BN_new();
828 a = BN_new();
829 b = BN_new();
830 if (!p || !a || !b) ABORT;
831
832 if (!BN_hex2bn(&p, "13")) ABORT;
833 if (!BN_hex2bn(&a, "3")) ABORT;
834 if (!BN_hex2bn(&b, "1")) ABORT;
835
836 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
837 * so that the library gets to choose the EC_METHOD */
838 if (!group) ABORT;
839 if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;
840
841 {
842 EC_GROUP *tmp;
843 tmp = EC_GROUP_new(EC_GROUP_method_of(group));
844 if (!tmp) ABORT;
845 if (!EC_GROUP_copy(tmp, group)) ABORT;
846 EC_GROUP_free(group);
847 group = tmp;
848 }
849
850 if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;
851
852 fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 + x*y = x^3 + a*x^2 + b (mod 0x");
853 BN_print_fp(stdout, p);
854 fprintf(stdout, ")\n a = 0x");
855 BN_print_fp(stdout, a);
856 fprintf(stdout, "\n b = 0x");
857 BN_print_fp(stdout, b);
858 fprintf(stdout, "\n(0x... means binary polynomial)\n");
859
860 P = EC_POINT_new(group);
861 Q = EC_POINT_new(group);
862 R = EC_POINT_new(group);
863 if (!P || !Q || !R) ABORT;
864
865 if (!EC_POINT_set_to_infinity(group, P)) ABORT;
866 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
867
868 buf[0] = 0;
869 if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
870
871 if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
872 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
873
874 x = BN_new();
875 y = BN_new();
876 z = BN_new();
877 cof = BN_new();
878 if (!x || !y || !z || !cof) ABORT;
879
880 if (!BN_hex2bn(&x, "6")) ABORT;
881/* Change test based on whether binary point compression is enabled or not. */
882#ifdef OPENSSL_EC_BIN_PT_COMP
883 if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
884#else
885 if (!BN_hex2bn(&y, "8")) ABORT;
886 if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
887#endif
888 if (!EC_POINT_is_on_curve(group, Q, ctx))
889 {
890/* Change test based on whether binary point compression is enabled or not. */
891#ifdef OPENSSL_EC_BIN_PT_COMP
892 if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
893#endif
894 fprintf(stderr, "Point is not on curve: x = 0x");
895 BN_print_fp(stderr, x);
896 fprintf(stderr, ", y = 0x");
897 BN_print_fp(stderr, y);
898 fprintf(stderr, "\n");
899 ABORT;
900 }
901
902 fprintf(stdout, "A cyclic subgroup:\n");
903 k = 100;
904 do
905 {
906 if (k-- == 0) ABORT;
907
908 if (EC_POINT_is_at_infinity(group, P))
909 fprintf(stdout, " point at infinity\n");
910 else
911 {
912 if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;
913
914 fprintf(stdout, " x = 0x");
915 BN_print_fp(stdout, x);
916 fprintf(stdout, ", y = 0x");
917 BN_print_fp(stdout, y);
918 fprintf(stdout, "\n");
919 }
920
921 if (!EC_POINT_copy(R, P)) ABORT;
922 if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
923 }
924 while (!EC_POINT_is_at_infinity(group, P));
925
926 if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
927 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
928
929/* Change test based on whether binary point compression is enabled or not. */
930#ifdef OPENSSL_EC_BIN_PT_COMP
931 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
932 if (len == 0) ABORT;
933 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
934 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
935 fprintf(stdout, "Generator as octet string, compressed form:\n ");
936 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
937#endif
938
939 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
940 if (len == 0) ABORT;
941 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
942 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
943 fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n ");
944 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
945
946/* Change test based on whether binary point compression is enabled or not. */
947#ifdef OPENSSL_EC_BIN_PT_COMP
948 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
949 if (len == 0) ABORT;
950 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
951 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
952 fprintf(stdout, "\nGenerator as octet string, hybrid form:\n ");
953 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
954#endif
955
956 fprintf(stdout, "\n");
957
958 if (!EC_POINT_invert(group, P, ctx)) ABORT;
959 if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
960
961
962 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
963 CHAR2_CURVE_TEST
964 (
965 "NIST curve K-163",
966 "0800000000000000000000000000000000000000C9",
967 "1",
968 "1",
969 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
970 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
971 1,
972 "04000000000000000000020108A2E0CC0D99F8A5EF",
973 "2",
974 163,
975 C2_K163
976 );
977
978 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
979 CHAR2_CURVE_TEST
980 (
981 "NIST curve B-163",
982 "0800000000000000000000000000000000000000C9",
983 "1",
984 "020A601907B8C953CA1481EB10512F78744A3205FD",
985 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
986 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
987 1,
988 "040000000000000000000292FE77E70C12A4234C33",
989 "2",
990 163,
991 C2_B163
992 );
993
994 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
995 CHAR2_CURVE_TEST
996 (
997 "NIST curve K-233",
998 "020000000000000000000000000000000000000004000000000000000001",
999 "0",
1000 "1",
1001 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
1002 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
1003 0,
1004 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
1005 "4",
1006 233,
1007 C2_K233
1008 );
1009
1010 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
1011 CHAR2_CURVE_TEST
1012 (
1013 "NIST curve B-233",
1014 "020000000000000000000000000000000000000004000000000000000001",
1015 "000000000000000000000000000000000000000000000000000000000001",
1016 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
1017 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
1018 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
1019 1,
1020 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
1021 "2",
1022 233,
1023 C2_B233
1024 );
1025
1026 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
1027 CHAR2_CURVE_TEST
1028 (
1029 "NIST curve K-283",
1030 "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1031 "0",
1032 "1",
1033 "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
1034 "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
1035 0,
1036 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
1037 "4",
1038 283,
1039 C2_K283
1040 );
1041
1042 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
1043 CHAR2_CURVE_TEST
1044 (
1045 "NIST curve B-283",
1046 "0800000000000000000000000000000000000000000000000000000000000000000010A1",
1047 "000000000000000000000000000000000000000000000000000000000000000000000001",
1048 "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
1049 "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
1050 "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
1051 1,
1052 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
1053 "2",
1054 283,
1055 C2_B283
1056 );
1057
1058 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
1059 CHAR2_CURVE_TEST
1060 (
1061 "NIST curve K-409",
1062 "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1063 "0",
1064 "1",
1065 "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
1066 "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
1067 1,
1068 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
1069 "4",
1070 409,
1071 C2_K409
1072 );
1073
1074 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
1075 CHAR2_CURVE_TEST
1076 (
1077 "NIST curve B-409",
1078 "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
1079 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1080 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
1081 "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
1082 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
1083 1,
1084 "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
1085 "2",
1086 409,
1087 C2_B409
1088 );
1089
1090 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
1091 CHAR2_CURVE_TEST
1092 (
1093 "NIST curve K-571",
1094 "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1095 "0",
1096 "1",
1097 "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
1098 "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
1099 0,
1100 "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
1101 "4",
1102 571,
1103 C2_K571
1104 );
1105
1106 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
1107 CHAR2_CURVE_TEST
1108 (
1109 "NIST curve B-571",
1110 "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
1111 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
1112 "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
1113 "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
1114 "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
1115 1,
1116 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
1117 "2",
1118 571,
1119 C2_B571
1120 );
1121
1122 /* more tests using the last curve */
1123
1124 if (!EC_POINT_copy(Q, P)) ABORT;
1125 if (EC_POINT_is_at_infinity(group, Q)) ABORT;
1126 if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
1127 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
1128 if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
1129
1130 if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
1131 if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
1132 if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
1133
1134 {
1135 const EC_POINT *points[3];
1136 const BIGNUM *scalars[3];
1137
1138 if (EC_POINT_is_at_infinity(group, Q)) ABORT;
1139 points[0] = Q;
1140 points[1] = Q;
1141 points[2] = Q;
1142
1143 if (!BN_add(y, z, BN_value_one())) ABORT;
1144 if (BN_is_odd(y)) ABORT;
1145 if (!BN_rshift1(y, y)) ABORT;
1146 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
1147 scalars[1] = y;
1148
1149 fprintf(stdout, "combined multiplication ...");
1150 fflush(stdout);
1151
1152 /* z is still the group order */
1153 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
1154 if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
1155 if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
1156 if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
1157
1158 fprintf(stdout, ".");
1159 fflush(stdout);
1160
1161 if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
1162 if (!BN_add(z, z, y)) ABORT;
1163 BN_set_negative(z, 1);
1164 scalars[0] = y;
1165 scalars[1] = z; /* z = -(order + y) */
1166
1167 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
1168 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
1169
1170 fprintf(stdout, ".");
1171 fflush(stdout);
1172
1173 if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
1174 if (!BN_add(z, x, y)) ABORT;
1175 BN_set_negative(z, 1);
1176 scalars[0] = x;
1177 scalars[1] = y;
1178 scalars[2] = z; /* z = -(x+y) */
1179
1180 if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
1181 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
1182
1183 fprintf(stdout, " ok\n\n");
1184 }
1185
1186
1187#if 0
1188 timings(C2_K163, TIMING_BASE_PT, ctx);
1189 timings(C2_K163, TIMING_RAND_PT, ctx);
1190 timings(C2_K163, TIMING_SIMUL, ctx);
1191 timings(C2_B163, TIMING_BASE_PT, ctx);
1192 timings(C2_B163, TIMING_RAND_PT, ctx);
1193 timings(C2_B163, TIMING_SIMUL, ctx);
1194 timings(C2_K233, TIMING_BASE_PT, ctx);
1195 timings(C2_K233, TIMING_RAND_PT, ctx);
1196 timings(C2_K233, TIMING_SIMUL, ctx);
1197 timings(C2_B233, TIMING_BASE_PT, ctx);
1198 timings(C2_B233, TIMING_RAND_PT, ctx);
1199 timings(C2_B233, TIMING_SIMUL, ctx);
1200 timings(C2_K283, TIMING_BASE_PT, ctx);
1201 timings(C2_K283, TIMING_RAND_PT, ctx);
1202 timings(C2_K283, TIMING_SIMUL, ctx);
1203 timings(C2_B283, TIMING_BASE_PT, ctx);
1204 timings(C2_B283, TIMING_RAND_PT, ctx);
1205 timings(C2_B283, TIMING_SIMUL, ctx);
1206 timings(C2_K409, TIMING_BASE_PT, ctx);
1207 timings(C2_K409, TIMING_RAND_PT, ctx);
1208 timings(C2_K409, TIMING_SIMUL, ctx);
1209 timings(C2_B409, TIMING_BASE_PT, ctx);
1210 timings(C2_B409, TIMING_RAND_PT, ctx);
1211 timings(C2_B409, TIMING_SIMUL, ctx);
1212 timings(C2_K571, TIMING_BASE_PT, ctx);
1213 timings(C2_K571, TIMING_RAND_PT, ctx);
1214 timings(C2_K571, TIMING_SIMUL, ctx);
1215 timings(C2_B571, TIMING_BASE_PT, ctx);
1216 timings(C2_B571, TIMING_RAND_PT, ctx);
1217 timings(C2_B571, TIMING_SIMUL, ctx);
1218#endif
1219
1220
1221 if (ctx)
1222 BN_CTX_free(ctx);
1223 BN_free(p); BN_free(a); BN_free(b);
1224 EC_GROUP_free(group);
1225 EC_POINT_free(P);
1226 EC_POINT_free(Q);
1227 EC_POINT_free(R);
1228 BN_free(x); BN_free(y); BN_free(z); BN_free(cof);
1229
1230 if (C2_K163) EC_GROUP_free(C2_K163);
1231 if (C2_B163) EC_GROUP_free(C2_B163);
1232 if (C2_K233) EC_GROUP_free(C2_K233);
1233 if (C2_B233) EC_GROUP_free(C2_B233);
1234 if (C2_K283) EC_GROUP_free(C2_K283);
1235 if (C2_B283) EC_GROUP_free(C2_B283);
1236 if (C2_K409) EC_GROUP_free(C2_K409);
1237 if (C2_B409) EC_GROUP_free(C2_B409);
1238 if (C2_K571) EC_GROUP_free(C2_K571);
1239 if (C2_B571) EC_GROUP_free(C2_B571);
1240
1241 }
1242
1243void internal_curve_test(void)
1244 {
1245 EC_builtin_curve *curves = NULL;
1246 size_t crv_len = 0, n = 0;
1247 int ok = 1;
1248
1249 crv_len = EC_get_builtin_curves(NULL, 0);
1250
1251 curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
1252
1253 if (curves == NULL)
1254 return;
1255
1256 if (!EC_get_builtin_curves(curves, crv_len))
1257 {
1258 OPENSSL_free(curves);
1259 return;
1260 }
1261
1262 fprintf(stdout, "testing internal curves: ");
1263
1264 for (n = 0; n < crv_len; n++)
1265 {
1266 EC_GROUP *group = NULL;
1267 int nid = curves[n].nid;
1268 if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
1269 {
1270 ok = 0;
1271 fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
1272 " curve %s\n", OBJ_nid2sn(nid));
1273 /* try next curve */
1274 continue;
1275 }
1276 if (!EC_GROUP_check(group, NULL))
1277 {
1278 ok = 0;
1279 fprintf(stdout, "\nEC_GROUP_check() failed with"
1280 " curve %s\n", OBJ_nid2sn(nid));
1281 EC_GROUP_free(group);
1282 /* try the next curve */
1283 continue;
1284 }
1285 fprintf(stdout, ".");
1286 fflush(stdout);
1287 EC_GROUP_free(group);
1288 }
1289 if (ok)
1290 fprintf(stdout, " ok\n");
1291 else
1292 fprintf(stdout, " failed\n");
1293 OPENSSL_free(curves);
1294 return;
1295 }
1296
1297static const char rnd_seed[] = "string to make the random number generator think it has entropy";
1298
1299int main(int argc, char *argv[])
1300 {
1301
1302 /* enable memory leak checking unless explicitly disabled */
1303 if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
1304 {
1305 CRYPTO_malloc_debug_init();
1306 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1307 }
1308 else
1309 {
1310 /* OPENSSL_DEBUG_MEMORY=off */
1311 CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
1312 }
1313 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
1314 ERR_load_crypto_strings();
1315
1316 RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
1317
1318 prime_field_tests();
1319 puts("");
1320 char2_field_tests();
1321 /* test the internal curves */
1322 internal_curve_test();
1323
1324#ifndef OPENSSL_NO_ENGINE
1325 ENGINE_cleanup();
1326#endif
1327 CRYPTO_cleanup_all_ex_data();
1328 ERR_free_strings();
1329 ERR_remove_thread_state(NULL);
1330 CRYPTO_mem_leaks_fp(stderr);
1331
1332 return 0;
1333 }
1334#endif