5c31efe1f3b08289f6249329b4e32753b9e1ecb9
[openssl.git] / test / ectest.c
1 /*
2  * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4  *
5  * Licensed under the Apache License 2.0 (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  */
10
11 #include <string.h>
12 #include "internal/nelem.h"
13 #include "testutil.h"
14
15 #ifndef OPENSSL_NO_EC
16 # include <openssl/ec.h>
17 # ifndef OPENSSL_NO_ENGINE
18 #  include <openssl/engine.h>
19 # endif
20 # include <openssl/err.h>
21 # include <openssl/obj_mac.h>
22 # include <openssl/objects.h>
23 # include <openssl/rand.h>
24 # include <openssl/bn.h>
25 # include <openssl/opensslconf.h>
26
27 static size_t crv_len = 0;
28 static EC_builtin_curve *curves = NULL;
29
30 /* test multiplication with group order, long and negative scalars */
31 static int group_order_tests(EC_GROUP *group)
32 {
33     BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
34     EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
35     const EC_POINT *G = NULL;
36     BN_CTX *ctx = NULL;
37     int i = 0, r = 0;
38
39     if (!TEST_ptr(n1 = BN_new())
40         || !TEST_ptr(n2 = BN_new())
41         || !TEST_ptr(order = BN_new())
42         || !TEST_ptr(ctx = BN_CTX_new())
43         || !TEST_ptr(G = EC_GROUP_get0_generator(group))
44         || !TEST_ptr(P = EC_POINT_new(group))
45         || !TEST_ptr(Q = EC_POINT_new(group))
46         || !TEST_ptr(R = EC_POINT_new(group))
47         || !TEST_ptr(S = EC_POINT_new(group)))
48         goto err;
49
50     if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
51         || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
52         || !TEST_true(EC_POINT_is_at_infinity(group, Q))
53         || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
54         || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
55         || !TEST_true(EC_POINT_is_at_infinity(group, Q))
56         || !TEST_true(EC_POINT_copy(P, G))
57         || !TEST_true(BN_one(n1))
58         || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
59         || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
60         || !TEST_true(BN_sub(n1, order, n1))
61         || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
62         || !TEST_true(EC_POINT_invert(group, Q, ctx))
63         || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
64         goto err;
65
66     for (i = 1; i <= 2; i++) {
67         const BIGNUM *scalars[6];
68         const EC_POINT *points[6];
69
70         if (!TEST_true(BN_set_word(n1, i))
71             /*
72              * If i == 1, P will be the predefined generator for which
73              * EC_GROUP_precompute_mult has set up precomputation.
74              */
75             || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
76             || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
77             || !TEST_true(BN_one(n1))
78             /* n1 = 1 - order */
79             || !TEST_true(BN_sub(n1, n1, order))
80             || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
81             || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
82
83             /* n2 = 1 + order */
84             || !TEST_true(BN_add(n2, order, BN_value_one()))
85             || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
86             || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
87
88             /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
89             || !TEST_true(BN_mul(n2, n1, n2, ctx))
90             || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
91             || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
92             goto err;
93
94         /* n2 = order^2 - 1 */
95         BN_set_negative(n2, 0);
96         if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
97             /* Add P to verify the result. */
98             || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
99             || !TEST_true(EC_POINT_is_at_infinity(group, Q))
100
101             /* Exercise EC_POINTs_mul, including corner cases. */
102             || !TEST_false(EC_POINT_is_at_infinity(group, P)))
103             goto err;
104
105         scalars[0] = scalars[1] = BN_value_one();
106         points[0]  = points[1]  = P;
107
108         if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
109             || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
110             || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
111             goto err;
112
113         scalars[0] = n1;
114         points[0] = Q;          /* => infinity */
115         scalars[1] = n2;
116         points[1] = P;          /* => -P */
117         scalars[2] = n1;
118         points[2] = Q;          /* => infinity */
119         scalars[3] = n2;
120         points[3] = Q;          /* => infinity */
121         scalars[4] = n1;
122         points[4] = P;          /* => P */
123         scalars[5] = n2;
124         points[5] = Q;          /* => infinity */
125         if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
126             || !TEST_true(EC_POINT_is_at_infinity(group, P)))
127             goto err;
128     }
129
130     r = 1;
131 err:
132     if (r == 0 && i != 0)
133         TEST_info(i == 1 ? "allowing precomputation" :
134                            "without precomputation");
135     EC_POINT_free(P);
136     EC_POINT_free(Q);
137     EC_POINT_free(R);
138     EC_POINT_free(S);
139     BN_free(n1);
140     BN_free(n2);
141     BN_free(order);
142     BN_CTX_free(ctx);
143     return r;
144 }
145
146 static int prime_field_tests(void)
147 {
148     BN_CTX *ctx = NULL;
149     BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
150     EC_GROUP *group = NULL, *tmp = NULL;
151     EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
152              *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
153     EC_POINT *P = NULL, *Q = NULL, *R = NULL;
154     BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
155     const EC_POINT *points[4];
156     const BIGNUM *scalars[4];
157     unsigned char buf[100];
158     size_t len, r = 0;
159     int k;
160
161     if (!TEST_ptr(ctx = BN_CTX_new())
162         || !TEST_ptr(p = BN_new())
163         || !TEST_ptr(a = BN_new())
164         || !TEST_ptr(b = BN_new())
165         || !TEST_true(BN_hex2bn(&p, "17"))
166         || !TEST_true(BN_hex2bn(&a, "1"))
167         || !TEST_true(BN_hex2bn(&b, "1"))
168         /*
169          * applications should use EC_GROUP_new_curve_GFp so
170          * that the library gets to choose the EC_METHOD
171          */
172         || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
173         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
174         || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
175         || !TEST_true(EC_GROUP_copy(tmp, group)))
176         goto err;
177     EC_GROUP_free(group);
178     group = tmp;
179     tmp = NULL;
180
181     if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
182         goto err;
183
184     TEST_info("Curve defined by Weierstrass equation");
185     TEST_note("     y^2 = x^3 + a*x + b (mod p)");
186     test_output_bignum("a", a);
187     test_output_bignum("b", b);
188     test_output_bignum("p", p);
189
190     buf[0] = 0;
191     if (!TEST_ptr(P = EC_POINT_new(group))
192         || !TEST_ptr(Q = EC_POINT_new(group))
193         || !TEST_ptr(R = EC_POINT_new(group))
194         || !TEST_true(EC_POINT_set_to_infinity(group, P))
195         || !TEST_true(EC_POINT_is_at_infinity(group, P))
196         || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
197         || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
198         || !TEST_true(EC_POINT_is_at_infinity(group, P))
199         || !TEST_ptr(x = BN_new())
200         || !TEST_ptr(y = BN_new())
201         || !TEST_ptr(z = BN_new())
202         || !TEST_ptr(yplusone = BN_new())
203         || !TEST_true(BN_hex2bn(&x, "D"))
204         || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
205         goto err;
206
207     if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
208         if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
209             goto err;
210         TEST_info("Point is not on curve");
211         test_output_bignum("x", x);
212         test_output_bignum("y", y);
213         goto err;
214     }
215
216     TEST_note("A cyclic subgroup:");
217     k = 100;
218     do {
219         if (!TEST_int_ne(k--, 0))
220             goto err;
221
222         if (EC_POINT_is_at_infinity(group, P)) {
223             TEST_note("     point at infinity");
224         } else {
225             if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
226                                                            ctx)))
227                 goto err;
228
229             test_output_bignum("x", x);
230             test_output_bignum("y", y);
231         }
232
233         if (!TEST_true(EC_POINT_copy(R, P))
234             || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
235             goto err;
236
237     } while (!EC_POINT_is_at_infinity(group, P));
238
239     if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
240         || !TEST_true(EC_POINT_is_at_infinity(group, P)))
241         goto err;
242
243     len =
244         EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
245                            sizeof(buf), ctx);
246     if (!TEST_size_t_ne(len, 0)
247         || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
248         || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
249         goto err;
250     test_output_memory("Generator as octet string, compressed form:",
251                        buf, len);
252
253     len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
254                              buf, sizeof(buf), ctx);
255     if (!TEST_size_t_ne(len, 0)
256         || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
257         || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
258         goto err;
259     test_output_memory("Generator as octet string, uncompressed form:",
260                        buf, len);
261
262     len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
263                              buf, sizeof(buf), ctx);
264     if (!TEST_size_t_ne(len, 0)
265         || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
266         || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
267         goto err;
268     test_output_memory("Generator as octet string, hybrid form:",
269                        buf, len);
270
271     if (!TEST_true(EC_POINT_invert(group, P, ctx))
272         || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
273
274     /*
275      * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
276      * 2000) -- not a NIST curve, but commonly used
277      */
278
279         || !TEST_true(BN_hex2bn(&p,                         "FFFFFFFF"
280                                     "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
281         || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
282         || !TEST_true(BN_hex2bn(&a,                         "FFFFFFFF"
283                                     "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
284         || !TEST_true(BN_hex2bn(&b,                         "1C97BEFC"
285                                     "54BD7A8B65ACF89F81D4D4ADC565FA45"))
286         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
287         || !TEST_true(BN_hex2bn(&x,                         "4A96B568"
288                                     "8EF573284664698968C38BB913CBFC82"))
289         || !TEST_true(BN_hex2bn(&y,                         "23a62855"
290                                     "3168947d59dcc912042351377ac5fb32"))
291         || !TEST_true(BN_add(yplusone, y, BN_value_one()))
292     /*
293      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
294      * and therefore setting the coordinates should fail.
295      */
296         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
297                                                        ctx))
298         || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
299         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
300         || !TEST_true(BN_hex2bn(&z,                       "0100000000"
301                                     "000000000001F4C8F927AED3CA752257"))
302         || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
303         || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
304         goto err;
305     TEST_info("SEC2 curve secp160r1 -- Generator");
306     test_output_bignum("x", x);
307     test_output_bignum("y", y);
308     /* G_y value taken from the standard: */
309     if (!TEST_true(BN_hex2bn(&z,                         "23a62855"
310                                  "3168947d59dcc912042351377ac5fb32"))
311         || !TEST_BN_eq(y, z)
312         || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
313         || !group_order_tests(group)
314         || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
315         || !TEST_true(EC_GROUP_copy(P_160, group))
316
317     /* Curve P-192 (FIPS PUB 186-2, App. 6) */
318
319         || !TEST_true(BN_hex2bn(&p,                 "FFFFFFFFFFFFFFFF"
320                                     "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
321         || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
322         || !TEST_true(BN_hex2bn(&a,                 "FFFFFFFFFFFFFFFF"
323                                     "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
324         || !TEST_true(BN_hex2bn(&b,                 "64210519E59C80E7"
325                                     "0FA7E9AB72243049FEB8DEECC146B9B1"))
326         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
327         || !TEST_true(BN_hex2bn(&x,                 "188DA80EB03090F6"
328                                     "7CBF20EB43A18800F4FF0AFD82FF1012"))
329         || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
330         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
331         || !TEST_true(BN_hex2bn(&z,                 "FFFFFFFFFFFFFFFF"
332                                     "FFFFFFFF99DEF836146BC9B1B4D22831"))
333         || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
334         || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
335         goto err;
336
337     TEST_info("NIST curve P-192 -- Generator");
338     test_output_bignum("x", x);
339     test_output_bignum("y", y);
340     /* G_y value taken from the standard: */
341     if (!TEST_true(BN_hex2bn(&z,                 "07192B95FFC8DA78"
342                                  "631011ED6B24CDD573F977A11E794811"))
343         || !TEST_BN_eq(y, z)
344         || !TEST_true(BN_add(yplusone, y, BN_value_one()))
345     /*
346      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
347      * and therefore setting the coordinates should fail.
348      */
349         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
350                                                        ctx))
351         || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
352         || !group_order_tests(group)
353         || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
354         || !TEST_true(EC_GROUP_copy(P_192, group))
355
356     /* Curve P-224 (FIPS PUB 186-2, App. 6) */
357
358         || !TEST_true(BN_hex2bn(&p,         "FFFFFFFFFFFFFFFFFFFFFFFF"
359                                     "FFFFFFFF000000000000000000000001"))
360         || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
361         || !TEST_true(BN_hex2bn(&a,         "FFFFFFFFFFFFFFFFFFFFFFFF"
362                                     "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
363         || !TEST_true(BN_hex2bn(&b,         "B4050A850C04B3ABF5413256"
364                                     "5044B0B7D7BFD8BA270B39432355FFB4"))
365         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
366         || !TEST_true(BN_hex2bn(&x,         "B70E0CBD6BB4BF7F321390B9"
367                                     "4A03C1D356C21122343280D6115C1D21"))
368         || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
369         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
370         || !TEST_true(BN_hex2bn(&z,         "FFFFFFFFFFFFFFFFFFFFFFFF"
371                                     "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
372         || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
373         || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
374         goto err;
375
376     TEST_info("NIST curve P-224 -- Generator");
377     test_output_bignum("x", x);
378     test_output_bignum("y", y);
379     /* G_y value taken from the standard: */
380     if (!TEST_true(BN_hex2bn(&z,         "BD376388B5F723FB4C22DFE6"
381                                  "CD4375A05A07476444D5819985007E34"))
382         || !TEST_BN_eq(y, z)
383         || !TEST_true(BN_add(yplusone, y, BN_value_one()))
384     /*
385      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
386      * and therefore setting the coordinates should fail.
387      */
388         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
389                                                        ctx))
390         || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
391         || !group_order_tests(group)
392         || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
393         || !TEST_true(EC_GROUP_copy(P_224, group))
394
395     /* Curve P-256 (FIPS PUB 186-2, App. 6) */
396
397         || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
398                                     "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
399         || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
400         || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
401                                     "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
402         || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
403                                     "651D06B0CC53B0F63BCE3C3E27D2604B"))
404         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
405
406         || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
407                                     "77037D812DEB33A0F4A13945D898C296"))
408         || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
409         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
410         || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
411                                     "BCE6FAADA7179E84F3B9CAC2FC632551"))
412         || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
413         || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
414         goto err;
415
416     TEST_info("NIST curve P-256 -- Generator");
417     test_output_bignum("x", x);
418     test_output_bignum("y", y);
419     /* G_y value taken from the standard: */
420     if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
421                                  "2BCE33576B315ECECBB6406837BF51F5"))
422         || !TEST_BN_eq(y, z)
423         || !TEST_true(BN_add(yplusone, y, BN_value_one()))
424     /*
425      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
426      * and therefore setting the coordinates should fail.
427      */
428         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
429                                                        ctx))
430         || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
431         || !group_order_tests(group)
432         || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
433         || !TEST_true(EC_GROUP_copy(P_256, group))
434
435     /* Curve P-384 (FIPS PUB 186-2, App. 6) */
436
437         || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
438                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
439                                     "FFFFFFFF0000000000000000FFFFFFFF"))
440         || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
441         || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
442                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
443                                     "FFFFFFFF0000000000000000FFFFFFFC"))
444         || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
445                                     "181D9C6EFE8141120314088F5013875A"
446                                     "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
447         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
448
449         || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
450                                     "6E1D3B628BA79B9859F741E082542A38"
451                                     "5502F25DBF55296C3A545E3872760AB7"))
452         || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
453         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
454         || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
455                                     "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
456                                     "581A0DB248B0A77AECEC196ACCC52973"))
457         || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
458         || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
459         goto err;
460
461     TEST_info("NIST curve P-384 -- Generator");
462     test_output_bignum("x", x);
463     test_output_bignum("y", y);
464     /* G_y value taken from the standard: */
465     if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
466                                  "F8F41DBD289A147CE9DA3113B5F0B8C0"
467                                  "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
468         || !TEST_BN_eq(y, z)
469         || !TEST_true(BN_add(yplusone, y, BN_value_one()))
470     /*
471      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
472      * and therefore setting the coordinates should fail.
473      */
474         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
475                                                        ctx))
476         || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
477         || !group_order_tests(group)
478         || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
479         || !TEST_true(EC_GROUP_copy(P_384, group))
480
481     /* Curve P-521 (FIPS PUB 186-2, App. 6) */
482         || !TEST_true(BN_hex2bn(&p,                              "1FF"
483                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
484                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
485                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
486                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
487         || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
488         || !TEST_true(BN_hex2bn(&a,                              "1FF"
489                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
490                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
491                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
492                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
493         || !TEST_true(BN_hex2bn(&b,                              "051"
494                                     "953EB9618E1C9A1F929A21A0B68540EE"
495                                     "A2DA725B99B315F3B8B489918EF109E1"
496                                     "56193951EC7E937B1652C0BD3BB1BF07"
497                                     "3573DF883D2C34F1EF451FD46B503F00"))
498         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
499         || !TEST_true(BN_hex2bn(&x,                               "C6"
500                                     "858E06B70404E9CD9E3ECB662395B442"
501                                     "9C648139053FB521F828AF606B4D3DBA"
502                                     "A14B5E77EFE75928FE1DC127A2FFA8DE"
503                                     "3348B3C1856A429BF97E7E31C2E5BD66"))
504         || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
505         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
506         || !TEST_true(BN_hex2bn(&z,                              "1FF"
507                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
508                                     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
509                                     "51868783BF2F966B7FCC0148F709A5D0"
510                                     "3BB5C9B8899C47AEBB6FB71E91386409"))
511         || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
512         || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
513         goto err;
514
515     TEST_info("NIST curve P-521 -- Generator");
516     test_output_bignum("x", x);
517     test_output_bignum("y", y);
518     /* G_y value taken from the standard: */
519     if (!TEST_true(BN_hex2bn(&z,                              "118"
520                                  "39296A789A3BC0045C8A5FB42C7D1BD9"
521                                  "98F54449579B446817AFBD17273E662C"
522                                  "97EE72995EF42640C550B9013FAD0761"
523                                  "353C7086A272C24088BE94769FD16650"))
524         || !TEST_BN_eq(y, z)
525         || !TEST_true(BN_add(yplusone, y, BN_value_one()))
526     /*
527      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
528      * and therefore setting the coordinates should fail.
529      */
530         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
531                                                        ctx))
532         || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
533         || !group_order_tests(group)
534         || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
535         || !TEST_true(EC_GROUP_copy(P_521, group))
536
537     /* more tests using the last curve */
538
539     /* Restore the point that got mangled in the (x, y + 1) test. */
540         || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
541         || !TEST_true(EC_POINT_copy(Q, P))
542         || !TEST_false(EC_POINT_is_at_infinity(group, Q))
543         || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
544         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
545         || !TEST_true(EC_POINT_invert(group, Q, ctx))       /* P = -2Q */
546         || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
547         || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
548         || !TEST_true(EC_POINT_is_at_infinity(group, R))    /* R = P + 2Q */
549         || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
550         goto err;
551     points[0] = Q;
552     points[1] = Q;
553     points[2] = Q;
554     points[3] = Q;
555
556     if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
557         || !TEST_true(BN_add(y, z, BN_value_one()))
558         || !TEST_BN_even(y)
559         || !TEST_true(BN_rshift1(y, y)))
560         goto err;
561     scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
562     scalars[1] = y;
563
564     TEST_note("combined multiplication ...");
565
566     /* z is still the group order */
567     if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
568         || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
569         || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
570         || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
571         || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
572         || !TEST_true(BN_add(z, z, y)))
573         goto err;
574     BN_set_negative(z, 1);
575     scalars[0] = y;
576     scalars[1] = z;         /* z = -(order + y) */
577
578     if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
579         || !TEST_true(EC_POINT_is_at_infinity(group, P))
580         || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
581         || !TEST_true(BN_add(z, x, y)))
582         goto err;
583     BN_set_negative(z, 1);
584     scalars[0] = x;
585     scalars[1] = y;
586     scalars[2] = z;         /* z = -(x+y) */
587
588     if (!TEST_ptr(scalar3 = BN_new()))
589         goto err;
590     BN_zero(scalar3);
591     scalars[3] = scalar3;
592
593     if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
594         || !TEST_true(EC_POINT_is_at_infinity(group, P)))
595         goto err;
596
597     TEST_note(" ok\n");
598
599
600     r = 1;
601 err:
602     BN_CTX_free(ctx);
603     BN_free(p);
604     BN_free(a);
605     BN_free(b);
606     EC_GROUP_free(group);
607     EC_GROUP_free(tmp);
608     EC_POINT_free(P);
609     EC_POINT_free(Q);
610     EC_POINT_free(R);
611     BN_free(x);
612     BN_free(y);
613     BN_free(z);
614     BN_free(yplusone);
615     BN_free(scalar3);
616
617     EC_GROUP_free(P_160);
618     EC_GROUP_free(P_192);
619     EC_GROUP_free(P_224);
620     EC_GROUP_free(P_256);
621     EC_GROUP_free(P_384);
622     EC_GROUP_free(P_521);
623     return r;
624 }
625
626 # ifndef OPENSSL_NO_EC2M
627
628 static struct c2_curve_test {
629     const char *name;
630     const char *p;
631     const char *a;
632     const char *b;
633     const char *x;
634     const char *y;
635     int ybit;
636     const char *order;
637     const char *cof;
638     int degree;
639 } char2_curve_tests[] = {
640     /* Curve K-163 (FIPS PUB 186-2, App. 6) */
641     {
642         "NIST curve K-163",
643         "0800000000000000000000000000000000000000C9",
644         "1",
645         "1",
646         "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
647         "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
648         1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
649     },
650     /* Curve B-163 (FIPS PUB 186-2, App. 6) */
651     {
652         "NIST curve B-163",
653         "0800000000000000000000000000000000000000C9",
654         "1",
655         "020A601907B8C953CA1481EB10512F78744A3205FD",
656         "03F0EBA16286A2D57EA0991168D4994637E8343E36",
657         "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
658         1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
659     },
660     /* Curve K-233 (FIPS PUB 186-2, App. 6) */
661     {
662         "NIST curve K-233",
663         "020000000000000000000000000000000000000004000000000000000001",
664         "0",
665         "1",
666         "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
667         "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
668         0,
669         "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
670         "4", 233
671     },
672     /* Curve B-233 (FIPS PUB 186-2, App. 6) */
673     {
674         "NIST curve B-233",
675         "020000000000000000000000000000000000000004000000000000000001",
676         "000000000000000000000000000000000000000000000000000000000001",
677         "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
678         "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
679         "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
680         1,
681         "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
682         "2", 233
683     },
684     /* Curve K-283 (FIPS PUB 186-2, App. 6) */
685     {
686         "NIST curve K-283",
687                                                                 "08000000"
688         "00000000000000000000000000000000000000000000000000000000000010A1",
689         "0",
690         "1",
691                                                                 "0503213F"
692         "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
693                                                                 "01CCDA38"
694         "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
695         0,
696                                                                 "01FFFFFF"
697         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
698         "4", 283
699     },
700     /* Curve B-283 (FIPS PUB 186-2, App. 6) */
701     {
702         "NIST curve B-283",
703                                                                 "08000000"
704         "00000000000000000000000000000000000000000000000000000000000010A1",
705                                                                 "00000000"
706         "0000000000000000000000000000000000000000000000000000000000000001",
707                                                                 "027B680A"
708         "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
709                                                                 "05F93925"
710         "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
711                                                                 "03676854"
712         "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
713         1,
714                                                                 "03FFFFFF"
715         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
716         "2", 283
717     },
718     /* Curve K-409 (FIPS PUB 186-2, App. 6) */
719     {
720         "NIST curve K-409",
721                                 "0200000000000000000000000000000000000000"
722         "0000000000000000000000000000000000000000008000000000000000000001",
723         "0",
724         "1",
725                                 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
726         "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
727                                 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
728         "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
729         1,
730                                 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
731         "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
732         "4", 409
733     },
734     /* Curve B-409 (FIPS PUB 186-2, App. 6) */
735     {
736         "NIST curve B-409",
737                                 "0200000000000000000000000000000000000000"
738         "0000000000000000000000000000000000000000008000000000000000000001",
739                                 "0000000000000000000000000000000000000000"
740         "0000000000000000000000000000000000000000000000000000000000000001",
741                                 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
742         "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
743                                 "015D4860D088DDB3496B0C6064756260441CDE4A"
744         "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
745                                 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
746         "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
747         1,
748                                 "0100000000000000000000000000000000000000"
749         "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
750         "2", 409
751     },
752     /* Curve K-571 (FIPS PUB 186-2, App. 6) */
753     {
754         "NIST curve K-571",
755                                                          "800000000000000"
756         "0000000000000000000000000000000000000000000000000000000000000000"
757         "0000000000000000000000000000000000000000000000000000000000000425",
758         "0",
759         "1",
760                                                         "026EB7A859923FBC"
761         "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
762         "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
763                                                         "0349DC807F4FBF37"
764         "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
765         "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
766         0,
767                                                         "0200000000000000"
768         "00000000000000000000000000000000000000000000000000000000131850E1"
769         "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
770         "4", 571
771     },
772     /* Curve B-571 (FIPS PUB 186-2, App. 6) */
773     {
774         "NIST curve B-571",
775                                                          "800000000000000"
776         "0000000000000000000000000000000000000000000000000000000000000000"
777         "0000000000000000000000000000000000000000000000000000000000000425",
778                                                         "0000000000000000"
779         "0000000000000000000000000000000000000000000000000000000000000000"
780         "0000000000000000000000000000000000000000000000000000000000000001",
781                                                         "02F40E7E2221F295"
782         "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
783         "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
784                                                         "0303001D34B85629"
785         "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
786         "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
787                                                         "037BF27342DA639B"
788         "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
789         "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
790         1,
791                                                         "03FFFFFFFFFFFFFF"
792         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
793         "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
794         "2", 571
795     }
796 };
797
798 static int char2_curve_test(int n)
799 {
800     int r = 0;
801     BN_CTX *ctx = NULL;
802     BIGNUM *p = NULL, *a = NULL, *b = NULL;
803     BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
804     EC_GROUP *group = NULL, *variable = NULL;
805     EC_POINT *P = NULL, *Q = NULL, *R = NULL;
806     const EC_POINT *points[3];
807     const BIGNUM *scalars[3];
808     struct c2_curve_test *const test = char2_curve_tests + n;
809
810     if (!TEST_ptr(ctx = BN_CTX_new())
811         || !TEST_ptr(p = BN_new())
812         || !TEST_ptr(a = BN_new())
813         || !TEST_ptr(b = BN_new())
814         || !TEST_ptr(x = BN_new())
815         || !TEST_ptr(y = BN_new())
816         || !TEST_ptr(z = BN_new())
817         || !TEST_ptr(yplusone = BN_new())
818         || !TEST_true(BN_hex2bn(&p, test->p))
819         || !TEST_true(BN_hex2bn(&a, test->a))
820         || !TEST_true(BN_hex2bn(&b, test->b))
821         || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
822         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
823         || !TEST_ptr(P = EC_POINT_new(group))
824         || !TEST_ptr(Q = EC_POINT_new(group))
825         || !TEST_ptr(R = EC_POINT_new(group))
826         || !TEST_true(BN_hex2bn(&x, test->x))
827         || !TEST_true(BN_hex2bn(&y, test->y))
828         || !TEST_true(BN_add(yplusone, y, BN_value_one())))
829         goto err;
830
831 /* Change test based on whether binary point compression is enabled or not. */
832 # ifdef OPENSSL_EC_BIN_PT_COMP
833     /*
834      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
835      * and therefore setting the coordinates should fail.
836      */
837     if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
838         || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
839                                                           test->y_bit,
840                                                           ctx))
841         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
842         || !TEST_true(BN_hex2bn(&z, test->order))
843         || !TEST_true(BN_hex2bn(&cof, test->cof))
844         || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
845         || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
846         goto err;
847     TEST_info("%s -- Generator", test->name);
848     test_output_bignum("x", x);
849     test_output_bignum("y", y);
850     /* G_y value taken from the standard: */
851     if (!TEST_true(BN_hex2bn(&z, test->y))
852         || !TEST_BN_eq(y, z))
853         goto err;
854 # else
855     /*
856      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
857      * and therefore setting the coordinates should fail.
858      */
859     if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
860         || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
861         || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
862         || !TEST_true(BN_hex2bn(&z, test->order))
863         || !TEST_true(BN_hex2bn(&cof, test->cof))
864         || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
865         goto err;
866     TEST_info("%s -- Generator:", test->name);
867     test_output_bignum("x", x);
868     test_output_bignum("y", y);
869 # endif
870
871     if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
872         || !group_order_tests(group)
873         || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
874         || !TEST_true(EC_GROUP_copy(variable, group)))
875         goto err;
876
877     /* more tests using the last curve */
878     if (n == OSSL_NELEM(char2_curve_tests) - 1) {
879         if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
880             || !TEST_true(EC_POINT_copy(Q, P))
881             || !TEST_false(EC_POINT_is_at_infinity(group, Q))
882             || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
883             || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
884             || !TEST_true(EC_POINT_invert(group, Q, ctx))       /* P = -2Q */
885             || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
886             || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
887             || !TEST_true(EC_POINT_is_at_infinity(group, R))   /* R = P + 2Q */
888             || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
889             goto err;
890
891         points[0] = Q;
892         points[1] = Q;
893         points[2] = Q;
894
895         if (!TEST_true(BN_add(y, z, BN_value_one()))
896             || !TEST_BN_even(y)
897             || !TEST_true(BN_rshift1(y, y)))
898             goto err;
899         scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
900         scalars[1] = y;
901
902         TEST_note("combined multiplication ...");
903
904         /* z is still the group order */
905         if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
906             || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
907             || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
908             || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
909             goto err;
910
911         if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
912             || !TEST_true(BN_add(z, z, y)))
913             goto err;
914         BN_set_negative(z, 1);
915         scalars[0] = y;
916         scalars[1] = z;         /* z = -(order + y) */
917
918         if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
919             || !TEST_true(EC_POINT_is_at_infinity(group, P)))
920             goto err;
921
922         if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
923             || !TEST_true(BN_add(z, x, y)))
924             goto err;
925         BN_set_negative(z, 1);
926         scalars[0] = x;
927         scalars[1] = y;
928         scalars[2] = z;         /* z = -(x+y) */
929
930         if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
931             || !TEST_true(EC_POINT_is_at_infinity(group, P)))
932             goto err;;
933     }
934
935     r = 1;
936 err:
937     BN_CTX_free(ctx);
938     BN_free(p);
939     BN_free(a);
940     BN_free(b);
941     BN_free(x);
942     BN_free(y);
943     BN_free(z);
944     BN_free(yplusone);
945     BN_free(cof);
946     EC_POINT_free(P);
947     EC_POINT_free(Q);
948     EC_POINT_free(R);
949     EC_GROUP_free(group);
950     EC_GROUP_free(variable);
951     return r;
952 }
953
954 static int char2_field_tests(void)
955 {
956     BN_CTX *ctx = NULL;
957     BIGNUM *p = NULL, *a = NULL, *b = NULL;
958     EC_GROUP *group = NULL, *tmp = NULL;
959     EC_POINT *P = NULL, *Q = NULL, *R = NULL;
960     BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
961     unsigned char buf[100];
962     size_t len;
963     int k, r = 0;
964
965     if (!TEST_ptr(ctx = BN_CTX_new())
966         || !TEST_ptr(p = BN_new())
967         || !TEST_ptr(a = BN_new())
968         || !TEST_ptr(b = BN_new())
969         || !TEST_true(BN_hex2bn(&p, "13"))
970         || !TEST_true(BN_hex2bn(&a, "3"))
971         || !TEST_true(BN_hex2bn(&b, "1")))
972         goto err;
973
974     group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
975                                                     * EC_GROUP_new_curve_GF2m
976                                                     * so that the library gets
977                                                     * to choose the EC_METHOD */
978     if (!TEST_ptr(group)
979         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
980         || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
981         || !TEST_true(EC_GROUP_copy(tmp, group)))
982         goto err;
983     EC_GROUP_free(group);
984     group = tmp;
985     tmp = NULL;
986
987     if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
988         goto err;
989
990     TEST_info("Curve defined by Weierstrass equation");
991     TEST_note("     y^2 + x*y = x^3 + a*x^2 + b (mod p)");
992     test_output_bignum("a", a);
993     test_output_bignum("b", b);
994     test_output_bignum("p", p);
995
996      if (!TEST_ptr(P = EC_POINT_new(group))
997         || !TEST_ptr(Q = EC_POINT_new(group))
998         || !TEST_ptr(R = EC_POINT_new(group))
999         || !TEST_true(EC_POINT_set_to_infinity(group, P))
1000         || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1001         goto err;
1002
1003     buf[0] = 0;
1004     if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1005         || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1006         || !TEST_true(EC_POINT_is_at_infinity(group, P))
1007         || !TEST_ptr(x = BN_new())
1008         || !TEST_ptr(y = BN_new())
1009         || !TEST_ptr(z = BN_new())
1010         || !TEST_ptr(cof = BN_new())
1011         || !TEST_ptr(yplusone = BN_new())
1012         || !TEST_true(BN_hex2bn(&x, "6"))
1013 /* Change test based on whether binary point compression is enabled or not. */
1014 #  ifdef OPENSSL_EC_BIN_PT_COMP
1015         || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
1016 #  else
1017         || !TEST_true(BN_hex2bn(&y, "8"))
1018         || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1019 #  endif
1020        )
1021         goto err;
1022     if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1023 /* Change test based on whether binary point compression is enabled or not. */
1024 #  ifdef OPENSSL_EC_BIN_PT_COMP
1025         if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1026             goto err;
1027 #  endif
1028         TEST_info("Point is not on curve");
1029         test_output_bignum("x", x);
1030         test_output_bignum("y", y);
1031         goto err;
1032     }
1033
1034     TEST_note("A cyclic subgroup:");
1035     k = 100;
1036     do {
1037         if (!TEST_int_ne(k--, 0))
1038             goto err;
1039
1040         if (EC_POINT_is_at_infinity(group, P))
1041             TEST_note("     point at infinity");
1042         else {
1043             if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1044                                                            ctx)))
1045                 goto err;
1046
1047             test_output_bignum("x", x);
1048             test_output_bignum("y", y);
1049         }
1050
1051         if (!TEST_true(EC_POINT_copy(R, P))
1052             || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1053             goto err;
1054     }
1055     while (!EC_POINT_is_at_infinity(group, P));
1056
1057     if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1058         || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1059         goto err;
1060
1061 /* Change test based on whether binary point compression is enabled or not. */
1062 #  ifdef OPENSSL_EC_BIN_PT_COMP
1063     len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1064                              buf, sizeof(buf), ctx);
1065     if (!TEST_size_t_ne(len, 0)
1066         || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1067         || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1068         goto err;
1069     test_output_memory("Generator as octet string, compressed form:",
1070                        buf, len);
1071 #  endif
1072
1073     len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1074                              buf, sizeof(buf), ctx);
1075     if (!TEST_size_t_ne(len, 0)
1076         || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1077         || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1078         goto err;
1079     test_output_memory("Generator as octet string, uncompressed form:",
1080                        buf, len);
1081
1082 /* Change test based on whether binary point compression is enabled or not. */
1083 #  ifdef OPENSSL_EC_BIN_PT_COMP
1084     len =
1085         EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1086                            ctx);
1087     if (!TEST_size_t_ne(len, 0)
1088         || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1089         || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1090         goto err;
1091     test_output_memory("Generator as octet string, hybrid form:",
1092                        buf, len);
1093 #  endif
1094
1095     if (!TEST_true(EC_POINT_invert(group, P, ctx))
1096         || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1097         goto err;
1098
1099     TEST_note("\n");
1100
1101     r = 1;
1102 err:
1103     BN_CTX_free(ctx);
1104     BN_free(p);
1105     BN_free(a);
1106     BN_free(b);
1107     EC_GROUP_free(group);
1108     EC_GROUP_free(tmp);
1109     EC_POINT_free(P);
1110     EC_POINT_free(Q);
1111     EC_POINT_free(R);
1112     BN_free(x);
1113     BN_free(y);
1114     BN_free(z);
1115     BN_free(cof);
1116     BN_free(yplusone);
1117     return r;
1118 }
1119 # endif
1120
1121 static int internal_curve_test(int n)
1122 {
1123     EC_GROUP *group = NULL;
1124     int nid = curves[n].nid;
1125
1126     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1127         TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1128                   OBJ_nid2sn(nid));
1129         return 0;
1130     }
1131     if (!TEST_true(EC_GROUP_check(group, NULL))) {
1132         TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1133         EC_GROUP_free(group);
1134         return 0;
1135     }
1136     EC_GROUP_free(group);
1137     return 1;
1138 }
1139
1140 static int internal_curve_test_method(int n)
1141 {
1142     int r, nid = curves[n].nid;
1143     EC_GROUP *group;
1144
1145     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1146         TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1147         return 0;
1148     }
1149     r = group_order_tests(group);
1150     EC_GROUP_free(group);
1151     return r;
1152 }
1153
1154 static int group_field_test(void)
1155 {
1156     int r = 1;
1157     BIGNUM *secp521r1_field = NULL;
1158     BIGNUM *sect163r2_field = NULL;
1159     EC_GROUP *secp521r1_group = NULL;
1160     EC_GROUP *sect163r2_group = NULL;
1161
1162     BN_hex2bn(&secp521r1_field,
1163                 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1164                 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1165                 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1166                 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1167                 "FFFF");
1168
1169
1170     BN_hex2bn(&sect163r2_field,
1171                 "08000000000000000000000000000000"
1172                 "00000000C9");
1173
1174     secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1175     if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1176       r = 0;
1177
1178     # ifndef OPENSSL_NO_EC2M
1179     sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1180     if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1181       r = 0;
1182     # endif
1183
1184     EC_GROUP_free(secp521r1_group);
1185     EC_GROUP_free(sect163r2_group);
1186     BN_free(secp521r1_field);
1187     BN_free(sect163r2_field);
1188     return r;
1189 }
1190
1191 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1192 /*
1193  * nistp_test_params contains magic numbers for testing our optimized
1194  * implementations of several NIST curves with characteristic > 3.
1195  */
1196 struct nistp_test_params {
1197     const EC_METHOD *(*meth) (void);
1198     int degree;
1199     /*
1200      * Qx, Qy and D are taken from
1201      * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1202      * Otherwise, values are standard curve parameters from FIPS 180-3
1203      */
1204     const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1205 };
1206
1207 static const struct nistp_test_params nistp_tests_params[] = {
1208     {
1209      /* P-224 */
1210      EC_GFp_nistp224_method,
1211      224,
1212      /* p */
1213      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1214      /* a */
1215      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1216      /* b */
1217      "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1218      /* Qx */
1219      "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1220      /* Qy */
1221      "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1222      /* Gx */
1223      "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1224      /* Gy */
1225      "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1226      /* order */
1227      "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1228      /* d */
1229      "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1230      },
1231     {
1232      /* P-256 */
1233      EC_GFp_nistp256_method,
1234      256,
1235      /* p */
1236      "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1237      /* a */
1238      "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1239      /* b */
1240      "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1241      /* Qx */
1242      "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1243      /* Qy */
1244      "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1245      /* Gx */
1246      "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1247      /* Gy */
1248      "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1249      /* order */
1250      "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1251      /* d */
1252      "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1253      },
1254     {
1255      /* P-521 */
1256      EC_GFp_nistp521_method,
1257      521,
1258      /* p */
1259                                                                   "1ff"
1260      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1261      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1262      /* a */
1263                                                                   "1ff"
1264      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1265      "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1266      /* b */
1267                                                                   "051"
1268      "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1269      "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1270      /* Qx */
1271                                                                  "0098"
1272      "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1273      "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1274      /* Qy */
1275                                                                  "0164"
1276      "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1277      "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1278      /* Gx */
1279                                                                    "c6"
1280      "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1281      "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1282      /* Gy */
1283                                                                   "118"
1284      "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1285      "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1286      /* order */
1287                                                                   "1ff"
1288      "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1289      "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1290      /* d */
1291                                                                  "0100"
1292      "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1293      "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1294      },
1295 };
1296
1297 static int nistp_single_test(int idx)
1298 {
1299     const struct nistp_test_params *test = nistp_tests_params + idx;
1300     BN_CTX *ctx = NULL;
1301     BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1302     BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1303     EC_GROUP *NISTP = NULL;
1304     EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1305     int r = 0;
1306
1307     TEST_note("NIST curve P-%d (optimised implementation):",
1308               test->degree);
1309     if (!TEST_ptr(ctx = BN_CTX_new())
1310         || !TEST_ptr(p = BN_new())
1311         || !TEST_ptr(a = BN_new())
1312         || !TEST_ptr(b = BN_new())
1313         || !TEST_ptr(x = BN_new())
1314         || !TEST_ptr(y = BN_new())
1315         || !TEST_ptr(m = BN_new())
1316         || !TEST_ptr(n = BN_new())
1317         || !TEST_ptr(order = BN_new())
1318         || !TEST_ptr(yplusone = BN_new())
1319
1320         || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1321         || !TEST_true(BN_hex2bn(&p, test->p))
1322         || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
1323         || !TEST_true(BN_hex2bn(&a, test->a))
1324         || !TEST_true(BN_hex2bn(&b, test->b))
1325         || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1326         || !TEST_ptr(G = EC_POINT_new(NISTP))
1327         || !TEST_ptr(P = EC_POINT_new(NISTP))
1328         || !TEST_ptr(Q = EC_POINT_new(NISTP))
1329         || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1330         || !TEST_true(BN_hex2bn(&x, test->Qx))
1331         || !TEST_true(BN_hex2bn(&y, test->Qy))
1332         || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1333     /*
1334      * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1335      * and therefore setting the coordinates should fail.
1336      */
1337         || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1338                                                        yplusone, ctx))
1339         || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1340                                                       ctx))
1341         || !TEST_true(BN_hex2bn(&x, test->Gx))
1342         || !TEST_true(BN_hex2bn(&y, test->Gy))
1343         || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1344         || !TEST_true(BN_hex2bn(&order, test->order))
1345         || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1346         || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1347         goto err;
1348
1349     TEST_note("NIST test vectors ... ");
1350     if (!TEST_true(BN_hex2bn(&n, test->d)))
1351         goto err;
1352     /* fixed point multiplication */
1353     EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1354     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1355         goto err;
1356     /* random point multiplication */
1357     EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1358     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1359
1360         /* set generator to P = 2*G, where G is the standard generator */
1361         || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1362         || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1363         /* set the scalar to m=n/2, where n is the NIST test scalar */
1364         || !TEST_true(BN_rshift(m, n, 1)))
1365         goto err;
1366
1367     /* test the non-standard generator */
1368     /* fixed point multiplication */
1369     EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1370     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1371         goto err;
1372     /* random point multiplication */
1373     EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1374     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1375
1376     /*
1377      * We have not performed precomputation so have_precompute mult should be
1378      * false
1379      */
1380         || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1381
1382     /* now repeat all tests with precomputation */
1383         || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1384         || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1385         goto err;
1386
1387     /* fixed point multiplication */
1388     EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1389     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1390         goto err;
1391     /* random point multiplication */
1392     EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1393     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1394
1395     /* reset generator */
1396         || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1397         goto err;
1398     /* fixed point multiplication */
1399     EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1400     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1401         goto err;
1402     /* random point multiplication */
1403     EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1404     if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1405         goto err;
1406
1407     /* regression test for felem_neg bug */
1408     if (!TEST_true(BN_set_word(m, 32))
1409         || !TEST_true(BN_set_word(n, 31))
1410         || !TEST_true(EC_POINT_copy(P, G))
1411         || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1412         || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1413         || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1414       goto err;
1415
1416     r = group_order_tests(NISTP);
1417 err:
1418     EC_GROUP_free(NISTP);
1419     EC_POINT_free(G);
1420     EC_POINT_free(P);
1421     EC_POINT_free(Q);
1422     EC_POINT_free(Q_CHECK);
1423     BN_free(n);
1424     BN_free(m);
1425     BN_free(p);
1426     BN_free(a);
1427     BN_free(b);
1428     BN_free(x);
1429     BN_free(y);
1430     BN_free(order);
1431     BN_free(yplusone);
1432     BN_CTX_free(ctx);
1433     return r;
1434 }
1435 # endif
1436
1437 static const unsigned char p521_named[] = {
1438     0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1439 };
1440
1441 static const unsigned char p521_explicit[] = {
1442     0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1443     0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1444     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1445     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1446     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1447     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1448     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1449     0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1450     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1451     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1452     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1453     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1454     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1455     0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1456     0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1457     0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1458     0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1459     0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1460     0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1461     0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1462     0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1463     0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1464     0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1465     0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1466     0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1467     0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1468     0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1469     0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1470     0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1471     0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1472     0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1473     0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1474     0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1475     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1476     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1477     0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1478     0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1479     0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1480 };
1481
1482 /*
1483  * This test validates a named curve's group parameters using
1484  * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1485  * group parameters results in the curve not being valid.
1486  */
1487 static int check_named_curve_test(int id)
1488 {
1489     int ret = 0, nid, field_nid, has_seed;
1490     EC_GROUP *group = NULL, *gtest = NULL;
1491     const EC_POINT *group_gen = NULL;
1492     EC_POINT *other_gen = NULL;
1493     BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1494     BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1495     BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1496     BIGNUM *other_order = NULL;
1497     const BIGNUM *group_order = NULL;
1498     BN_CTX *bn_ctx = NULL;
1499     static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1500     static size_t invalid_seed_len = sizeof(invalid_seed);
1501
1502     /* Do some setup */
1503     nid = curves[id].nid;
1504     if (!TEST_ptr(bn_ctx = BN_CTX_new())
1505         || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1506         || !TEST_ptr(gtest = EC_GROUP_dup(group))
1507         || !TEST_ptr(group_p = BN_new())
1508         || !TEST_ptr(group_a = BN_new())
1509         || !TEST_ptr(group_b = BN_new())
1510         || !TEST_ptr(group_cofactor = BN_new())
1511         || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1512         || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1513         || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1514         || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1515         || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1516         || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1517         || !TEST_ptr(other_order = BN_dup(group_order))
1518         || !TEST_true(BN_add_word(other_order, 1))
1519         || !TEST_ptr(other_a = BN_dup(group_a))
1520         || !TEST_true(BN_add_word(other_a, 1))
1521         || !TEST_ptr(other_b = BN_dup(group_b))
1522         || !TEST_true(BN_add_word(other_b, 1))
1523         || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1524         || !TEST_true(BN_add_word(other_cofactor, 1)))
1525         goto err;
1526
1527     /* Determine if the built-in curve has a seed field set */
1528     has_seed = (EC_GROUP_get_seed_len(group) > 0);
1529     field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
1530     if (field_nid == NID_X9_62_characteristic_two_field) {
1531         if (!TEST_ptr(other_p = BN_dup(group_p))
1532             || !TEST_true(BN_lshift1(other_p, other_p)))
1533             goto err;
1534     } else {
1535         if (!TEST_ptr(other_p = BN_dup(group_p)))
1536             goto err;
1537         /*
1538          * Just choosing any arbitrary prime does not work..
1539          * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1540          * nist prime. So only select one of these as an alternate prime.
1541          */
1542         if (!TEST_ptr(BN_copy(other_p,
1543                               BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1544                                       BN_get0_nist_prime_256() :
1545                                       BN_get0_nist_prime_192())))
1546             goto err;
1547     }
1548
1549     /* Passes because this is a valid curve */
1550     if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
1551         /* Only NIST curves pass */
1552         || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
1553                         EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1554         goto err;
1555
1556     /* Fail if the curve name doesn't match the parameters */
1557     EC_GROUP_set_curve_name(group, nid + 1);
1558     ERR_set_mark();
1559     if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1560         goto err;
1561     ERR_pop_to_mark();
1562
1563     /* Restore curve name and ensure it's passing */
1564     EC_GROUP_set_curve_name(group, nid);
1565     if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1566         goto err;
1567
1568     if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1569                      invalid_seed_len))
1570         goto err;
1571
1572     if (has_seed) {
1573         /*
1574          * If the built-in curve has a seed and we set the seed to another value
1575          * then it will fail the check.
1576          */
1577         if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
1578             goto err;
1579     } else {
1580         /*
1581          * If the built-in curve does not have a seed then setting the seed will
1582          * pass the check (as the seed is optional).
1583          */
1584         if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1585             goto err;
1586     }
1587     /* Pass if the seed is unknown (as it is optional) */
1588     if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
1589         || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
1590         goto err;
1591
1592     /* Check that a duped group passes */
1593     if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1594         goto err;
1595
1596     /* check that changing any generator parameter fails */
1597     if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1598                                           group_cofactor))
1599         || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1600         || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1601                                              group_cofactor))
1602         || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1603         /* The order is not an optional field, so this should fail */
1604         || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1605                                               group_cofactor))
1606         || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1607                                              other_cofactor))
1608         || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
1609         /* Check that if the cofactor is not set then it still passes */
1610         || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1611                                              NULL))
1612         || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
1613         /* check that restoring the generator passes */
1614         || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1615                                              group_cofactor))
1616         || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1617         goto err;
1618
1619     /*
1620      * check that changing any curve parameter fails
1621      *
1622      * Setting arbitrary p, a or b might fail for some EC_GROUPs
1623      * depending on the internal EC_METHOD implementation, hence run
1624      * these tests conditionally to the success of EC_GROUP_set_curve().
1625      */
1626     ERR_set_mark();
1627     if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
1628         if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1629             goto err;
1630     } else {
1631         /* clear the error stack if EC_GROUP_set_curve() failed */
1632         ERR_pop_to_mark();
1633         ERR_set_mark();
1634     }
1635     if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
1636         if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1637             goto err;
1638     } else {
1639         /* clear the error stack if EC_GROUP_set_curve() failed */
1640         ERR_pop_to_mark();
1641         ERR_set_mark();
1642     }
1643     if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
1644         if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
1645             goto err;
1646     } else {
1647         /* clear the error stack if EC_GROUP_set_curve() failed */
1648         ERR_pop_to_mark();
1649         ERR_set_mark();
1650     }
1651     ERR_pop_to_mark();
1652
1653     /* Check that restoring the curve parameters passes */
1654     if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
1655         || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
1656         goto err;
1657
1658     ret = 1;
1659 err:
1660     BN_free(group_p);
1661     BN_free(other_p);
1662     BN_free(group_a);
1663     BN_free(other_a);
1664     BN_free(group_b);
1665     BN_free(other_b);
1666     BN_free(group_cofactor);
1667     BN_free(other_cofactor);
1668     BN_free(other_order);
1669     EC_POINT_free(other_gen);
1670     EC_GROUP_free(gtest);
1671     EC_GROUP_free(group);
1672     BN_CTX_free(bn_ctx);
1673     return ret;
1674 }
1675
1676 /*
1677  * This checks the lookup capability of EC_GROUP_check_named_curve()
1678  * when the given group was created with explicit parameters.
1679  *
1680  * It is possible to retrieve an alternative alias that does not match
1681  * the original nid in this case.
1682  */
1683 static int check_named_curve_lookup_test(int id)
1684 {
1685     int ret = 0, nid, rv = 0;
1686     EC_GROUP *g = NULL , *ga = NULL;
1687     ECPARAMETERS *p = NULL, *pa = NULL;
1688     BN_CTX *ctx = NULL;
1689
1690     /* Do some setup */
1691     nid = curves[id].nid;
1692     if (!TEST_ptr(ctx = BN_CTX_new())
1693         || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1694         || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1695         goto err;
1696
1697     /* replace with group from explicit parameters */
1698     EC_GROUP_free(g);
1699     if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1700         goto err;
1701
1702     if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
1703         goto err;
1704     if (rv != nid) {
1705         /*
1706          * Found an alias:
1707          * fail if the returned nid is not an alias of the original group.
1708          *
1709          * The comparison here is done by comparing two explicit
1710          * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1711          * comparison happens with unnamed EC_GROUPs using the same
1712          * EC_METHODs.
1713          */
1714         if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1715                 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1716             goto err;
1717
1718         /* replace with group from explicit parameters, then compare */
1719         EC_GROUP_free(ga);
1720         if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1721                 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1722             goto err;
1723     }
1724
1725     ret = 1;
1726
1727  err:
1728     EC_GROUP_free(g);
1729     EC_GROUP_free(ga);
1730     ECPARAMETERS_free(p);
1731     ECPARAMETERS_free(pa);
1732     BN_CTX_free(ctx);
1733
1734     return ret;
1735 }
1736
1737 /*
1738  * Sometime we cannot compare nids for equality, as the built-in curve table
1739  * includes aliases with different names for the same curve.
1740  *
1741  * This function returns TRUE (1) if the checked nids are identical, or if they
1742  * alias to the same curve. FALSE (0) otherwise.
1743  */
1744 static ossl_inline
1745 int are_ec_nids_compatible(int n1d, int n2d)
1746 {
1747     int ret = 0;
1748     switch (n1d) {
1749 # ifndef OPENSSL_NO_EC2M
1750         case NID_sect113r1:
1751         case NID_wap_wsg_idm_ecid_wtls4:
1752             ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1753             break;
1754         case NID_sect163k1:
1755         case NID_wap_wsg_idm_ecid_wtls3:
1756             ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1757             break;
1758         case NID_sect233k1:
1759         case NID_wap_wsg_idm_ecid_wtls10:
1760             ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1761             break;
1762         case NID_sect233r1:
1763         case NID_wap_wsg_idm_ecid_wtls11:
1764             ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1765             break;
1766         case NID_X9_62_c2pnb163v1:
1767         case NID_wap_wsg_idm_ecid_wtls5:
1768             ret = (n2d == NID_X9_62_c2pnb163v1
1769                    || n2d == NID_wap_wsg_idm_ecid_wtls5);
1770             break;
1771 # endif /* OPENSSL_NO_EC2M */
1772         case NID_secp112r1:
1773         case NID_wap_wsg_idm_ecid_wtls6:
1774             ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1775             break;
1776         case NID_secp160r2:
1777         case NID_wap_wsg_idm_ecid_wtls7:
1778             ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1779             break;
1780 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1781         case NID_secp224r1:
1782         case NID_wap_wsg_idm_ecid_wtls12:
1783             ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1784             break;
1785 # else
1786         /*
1787          * For SEC P-224 we want to ensure that the SECP nid is returned, as
1788          * that is associated with a specialized method.
1789          */
1790         case NID_wap_wsg_idm_ecid_wtls12:
1791             ret = (n2d == NID_secp224r1);
1792             break;
1793 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1794
1795         default:
1796             ret = (n1d == n2d);
1797     }
1798     return ret;
1799 }
1800
1801 /*
1802  * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1803  * EC_GROUP for built-in curves.
1804  *
1805  * Note that it is possible to retrieve an alternative alias that does not match
1806  * the original nid.
1807  *
1808  * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1809  */
1810 static int check_named_curve_from_ecparameters(int id)
1811 {
1812     int ret = 0, nid, tnid;
1813     EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1814     const EC_POINT *group_gen = NULL;
1815     EC_POINT *other_gen = NULL;
1816     BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1817     BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1818     const BIGNUM *group_order = NULL;
1819     BIGNUM *other_order = NULL;
1820     BN_CTX *bn_ctx = NULL;
1821     static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1822     static size_t invalid_seed_len = sizeof(invalid_seed);
1823     ECPARAMETERS *params = NULL, *other_params = NULL;
1824     EC_GROUP *g_ary[8] = {NULL};
1825     EC_GROUP **g_next = &g_ary[0];
1826     ECPARAMETERS *p_ary[8] = {NULL};
1827     ECPARAMETERS **p_next = &p_ary[0];
1828
1829     /* Do some setup */
1830     nid = curves[id].nid;
1831     TEST_note("Curve %s", OBJ_nid2sn(nid));
1832     if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1833         return ret;
1834     BN_CTX_start(bn_ctx);
1835
1836     if (/* Allocations */
1837         !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1838         || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1839         || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1840         || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1841         || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1842         /* Generate reference group and params */
1843         || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1844         || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1845         || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1846         || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1847         || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1848         /* compute `other_*` values */
1849         || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1850         || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1851         || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1852         || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1853                       other_gen_x, other_gen_y, bn_ctx))
1854         || !TEST_true(BN_copy(other_order, group_order))
1855         || !TEST_true(BN_add_word(other_order, 1))
1856         || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1857         || !TEST_true(BN_add_word(other_cofactor, 1)))
1858         goto err;
1859
1860     EC_POINT_free(other_gen);
1861     other_gen = NULL;
1862
1863     if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1864         || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1865                                                       other_gen_x, other_gen_y,
1866                                                       bn_ctx)))
1867         goto err;
1868
1869     /*
1870      * ###########################
1871      * # Actual tests start here #
1872      * ###########################
1873      */
1874
1875     /*
1876      * Creating a group from built-in explicit parameters returns a
1877      * "named" EC_GROUP
1878      */
1879     if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1880         || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1881         goto err;
1882     /*
1883      * We cannot always guarantee the names match, as the built-in table
1884      * contains aliases for the same curve with different names.
1885      */
1886     if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1887         TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1888         goto err;
1889     }
1890     /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1891     if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1892         goto err;
1893
1894     /*
1895      * An invalid seed in the parameters should be ignored: expect a "named"
1896      * group.
1897      */
1898     if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1899                      invalid_seed_len)
1900             || !TEST_ptr(other_params = *p_next++ =
1901                          EC_GROUP_get_ecparameters(tmpg, NULL))
1902             || !TEST_ptr(tgroup = *g_next++ =
1903                           EC_GROUP_new_from_ecparameters(other_params))
1904             || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1905             || !TEST_true(are_ec_nids_compatible(nid, tnid))
1906             || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1907                             OPENSSL_EC_EXPLICIT_CURVE)) {
1908         TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1909         goto err;
1910     }
1911
1912     /*
1913      * A null seed in the parameters should be ignored, as it is optional:
1914      * expect a "named" group.
1915      */
1916     if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1917             || !TEST_ptr(other_params = *p_next++ =
1918                          EC_GROUP_get_ecparameters(tmpg, NULL))
1919             || !TEST_ptr(tgroup = *g_next++ =
1920                           EC_GROUP_new_from_ecparameters(other_params))
1921             || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1922             || !TEST_true(are_ec_nids_compatible(nid, tnid))
1923             || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1924                             OPENSSL_EC_EXPLICIT_CURVE)) {
1925         TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1926         goto err;
1927     }
1928
1929     /*
1930      * Check that changing any of the generator parameters does not yield a
1931      * match with the built-in curves
1932      */
1933     if (/* Other gen, same group order & cofactor */
1934         !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1935                                           group_cofactor))
1936         || !TEST_ptr(other_params = *p_next++ =
1937                      EC_GROUP_get_ecparameters(tmpg, NULL))
1938         || !TEST_ptr(tgroup = *g_next++ =
1939                       EC_GROUP_new_from_ecparameters(other_params))
1940         || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1941         /* Same gen & cofactor, different order */
1942         || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1943                                              group_cofactor))
1944         || !TEST_ptr(other_params = *p_next++ =
1945                      EC_GROUP_get_ecparameters(tmpg, NULL))
1946         || !TEST_ptr(tgroup = *g_next++ =
1947                       EC_GROUP_new_from_ecparameters(other_params))
1948         || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1949         /* The order is not an optional field, so this should fail */
1950         || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1951                                               group_cofactor))
1952         /* Check that a wrong cofactor is ignored, and we still match */
1953         || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1954                                              other_cofactor))
1955         || !TEST_ptr(other_params = *p_next++ =
1956                      EC_GROUP_get_ecparameters(tmpg, NULL))
1957         || !TEST_ptr(tgroup = *g_next++ =
1958                       EC_GROUP_new_from_ecparameters(other_params))
1959         || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1960         || !TEST_true(are_ec_nids_compatible(nid, tnid))
1961         || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1962                         OPENSSL_EC_EXPLICIT_CURVE)
1963         /* Check that if the cofactor is not set then it still matches */
1964         || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1965                                              NULL))
1966         || !TEST_ptr(other_params = *p_next++ =
1967                      EC_GROUP_get_ecparameters(tmpg, NULL))
1968         || !TEST_ptr(tgroup = *g_next++ =
1969                       EC_GROUP_new_from_ecparameters(other_params))
1970         || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1971         || !TEST_true(are_ec_nids_compatible(nid, tnid))
1972         || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1973                         OPENSSL_EC_EXPLICIT_CURVE)
1974         /* check that restoring the generator passes */
1975         || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1976                                              group_cofactor))
1977         || !TEST_ptr(other_params = *p_next++ =
1978                      EC_GROUP_get_ecparameters(tmpg, NULL))
1979         || !TEST_ptr(tgroup = *g_next++ =
1980                       EC_GROUP_new_from_ecparameters(other_params))
1981         || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1982         || !TEST_true(are_ec_nids_compatible(nid, tnid))
1983         || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1984                         OPENSSL_EC_EXPLICIT_CURVE))
1985         goto err;
1986
1987     ret = 1;
1988 err:
1989     for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1990         EC_GROUP_free(*g_next);
1991     for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1992         ECPARAMETERS_free(*p_next);
1993     ECPARAMETERS_free(params);
1994     EC_POINT_free(other_gen);
1995     EC_GROUP_free(tmpg);
1996     EC_GROUP_free(group);
1997     BN_CTX_end(bn_ctx);
1998     BN_CTX_free(bn_ctx);
1999     return ret;
2000 }
2001
2002
2003 static int parameter_test(void)
2004 {
2005     EC_GROUP *group = NULL, *group2 = NULL;
2006     ECPARAMETERS *ecparameters = NULL;
2007     unsigned char *buf = NULL;
2008     int r = 0, len;
2009
2010     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
2011         || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
2012         || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
2013         || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
2014         goto err;
2015
2016     EC_GROUP_free(group);
2017     group = NULL;
2018
2019     /* Test the named curve encoding, which should be default. */
2020     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
2021         || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2022         || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
2023         goto err;
2024
2025     OPENSSL_free(buf);
2026     buf = NULL;
2027
2028     /*
2029      * Test the explicit encoding. P-521 requires correctly zero-padding the
2030      * curve coefficients.
2031      */
2032     EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
2033     if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
2034         || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
2035         goto err;
2036
2037     r = 1;
2038 err:
2039     EC_GROUP_free(group);
2040     EC_GROUP_free(group2);
2041     ECPARAMETERS_free(ecparameters);
2042     OPENSSL_free(buf);
2043     return r;
2044 }
2045
2046 /*-
2047  * random 256-bit explicit parameters curve, cofactor absent
2048  * order:    0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2049  * cofactor:   0x12bc94785251297abfafddf1565100da (125 bit)
2050  */
2051 static const unsigned char params_cf_pass[] = {
2052     0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2053     0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2054     0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2055     0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2056     0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2057     0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2058     0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2059     0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2060     0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2061     0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2062     0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2063     0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2064     0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2065     0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2066     0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2067     0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2068     0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2069     0x14, 0xa8, 0x2f, 0x4f
2070 };
2071
2072 /*-
2073  * random 256-bit explicit parameters curve, cofactor absent
2074  * order:    0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2075  * cofactor:   0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2076  */
2077 static const unsigned char params_cf_fail[] = {
2078     0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2079     0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2080     0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2081     0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2082     0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2083     0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2084     0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2085     0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2086     0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2087     0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2088     0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2089     0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2090     0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2091     0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2092     0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2093     0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2094     0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2095     0x34, 0xa2, 0x21, 0x01
2096 };
2097
2098 /*-
2099  * Test two random 256-bit explicit parameters curves with absent cofactor.
2100  * The two curves are chosen to roughly straddle the bounds at which the lib
2101  * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2102  *
2103  * - params_cf_pass: order is sufficiently close to p to compute cofactor
2104  * - params_cf_fail: order is too far away from p to compute cofactor
2105  *
2106  * For standards-compliant curves, cofactor is chosen as small as possible.
2107  * So you can see neither of these curves are fit for cryptographic use.
2108  *
2109  * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2110  * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2111  * will always succeed in computing the cofactor. Neither of these curves
2112  * conform to that -- this is just robustness testing.
2113  */
2114 static int cofactor_range_test(void)
2115 {
2116     EC_GROUP *group = NULL;
2117     BIGNUM *cf = NULL;
2118     int ret = 0;
2119     const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2120     const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2121
2122     if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2123         || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2124         || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2125                                                 sizeof(params_cf_pass)))
2126         || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2127         || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2128         goto err;
2129     ret = 1;
2130  err:
2131     BN_free(cf);
2132     EC_GROUP_free(group);
2133     return ret;
2134 }
2135
2136 /*-
2137  * For named curves, test that:
2138  * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2139  * - a nonsensical cofactor throws an error (negative test)
2140  * - nonsensical orders throw errors (negative tests)
2141  */
2142 static int cardinality_test(int n)
2143 {
2144     int ret = 0;
2145     int nid = curves[n].nid;
2146     BN_CTX *ctx = NULL;
2147     EC_GROUP *g1 = NULL, *g2 = NULL;
2148     EC_POINT *g2_gen = NULL;
2149     BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2150            *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2151
2152     TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
2153
2154     if (!TEST_ptr(ctx = BN_CTX_new())
2155         || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
2156         || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
2157         EC_GROUP_free(g1);
2158         EC_GROUP_free(g2);
2159         BN_CTX_free(ctx);
2160         return 0;
2161     }
2162
2163     BN_CTX_start(ctx);
2164     g1_p = BN_CTX_get(ctx);
2165     g1_a = BN_CTX_get(ctx);
2166     g1_b = BN_CTX_get(ctx);
2167     g1_x = BN_CTX_get(ctx);
2168     g1_y = BN_CTX_get(ctx);
2169     g1_order = BN_CTX_get(ctx);
2170     g1_cf = BN_CTX_get(ctx);
2171
2172     if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2173         /* pull out the explicit curve parameters */
2174         || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2175         || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2176                       EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2177         || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2178         || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2179         /* construct g2 manually with g1 parameters */
2180         || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
2181         || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2182         || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2183         /* pass NULL cofactor: lib should compute it */
2184         || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2185         || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2186         || !TEST_BN_eq(g1_cf, g2_cf)
2187         /* pass zero cofactor: lib should compute it */
2188         || !TEST_true(BN_set_word(g2_cf, 0))
2189         || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2190         || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2191         || !TEST_BN_eq(g1_cf, g2_cf)
2192         /* negative test for invalid cofactor */
2193         || !TEST_true(BN_set_word(g2_cf, 0))
2194         || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2195         || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2196         /* negative test for NULL order */
2197         || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2198         /* negative test for zero order */
2199         || !TEST_true(BN_set_word(g1_order, 0))
2200         || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2201         /* negative test for negative order */
2202         || !TEST_true(BN_set_word(g2_cf, 0))
2203         || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2204         || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2205         /* negative test for too large order */
2206         || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2207         || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2208         goto err;
2209     ret = 1;
2210  err:
2211     EC_POINT_free(g2_gen);
2212     EC_GROUP_free(g1);
2213     EC_GROUP_free(g2);
2214     BN_CTX_end(ctx);
2215     BN_CTX_free(ctx);
2216     return ret;
2217 }
2218
2219 static int check_ec_key_field_public_range_test(int id)
2220 {
2221     int ret = 0, type = 0;
2222     const EC_POINT *pub = NULL;
2223     const EC_GROUP *group = NULL;
2224     const EC_METHOD *meth = NULL;
2225     const BIGNUM *field = NULL;
2226     BIGNUM *x = NULL, *y = NULL;
2227     EC_KEY *key = NULL;
2228
2229     if (!TEST_ptr(x = BN_new())
2230             || !TEST_ptr(y = BN_new())
2231             || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2232             || !TEST_ptr(group = EC_KEY_get0_group(key))
2233             || !TEST_ptr(meth = EC_GROUP_method_of(group))
2234             || !TEST_ptr(field = EC_GROUP_get0_field(group))
2235             || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2236             || !TEST_int_gt(EC_KEY_check_key(key), 0)
2237             || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2238             || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2239                                                             NULL), 0))
2240         goto err;
2241
2242     /*
2243      * Make the public point out of range by adding the field (which will still
2244      * be the same point on the curve). The add is different for char2 fields.
2245      */
2246     type = EC_METHOD_get_field_type(meth);
2247 #ifndef OPENSSL_NO_EC2M
2248     if (type == NID_X9_62_characteristic_two_field) {
2249         /* test for binary curves */
2250         if (!TEST_true(BN_GF2m_add(x, x, field)))
2251             goto err;
2252     } else
2253 #endif
2254     if (type == NID_X9_62_prime_field) {
2255         /* test for prime curves */
2256         if (!TEST_true(BN_add(x, x, field)))
2257             goto err;
2258     } else {
2259         /* this should never happen */
2260         TEST_error("Unsupported EC_METHOD field_type");
2261         goto err;
2262     }
2263     if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2264         goto err;
2265
2266     ret = 1;
2267 err:
2268     BN_free(x);
2269     BN_free(y);
2270     EC_KEY_free(key);
2271     return ret;
2272 }
2273
2274 /*
2275  * Helper for ec_point_hex2point_test
2276  *
2277  * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2278  * (group,P) pair.
2279  *
2280  * If P is NULL use point at infinity.
2281  */
2282 static ossl_inline
2283 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2284                                    point_conversion_form_t form,
2285                                    BN_CTX *bnctx)
2286 {
2287     int ret = 0;
2288     EC_POINT *Q = NULL, *Pinf = NULL;
2289     char *hex = NULL;
2290
2291     if (P == NULL) {
2292         /* If P is NULL use point at infinity. */
2293         if (!TEST_ptr(Pinf = EC_POINT_new(group))
2294                 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2295             goto err;
2296         P = Pinf;
2297     }
2298
2299     if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2300             || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2301             || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2302         goto err;
2303
2304     /*
2305      * The next check is most likely superfluous, as EC_POINT_cmp should already
2306      * cover this.
2307      * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2308      * so we include it anyway!
2309      */
2310     if (Pinf != NULL
2311             && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2312         goto err;
2313
2314     ret = 1;
2315
2316  err:
2317     EC_POINT_free(Pinf);
2318     OPENSSL_free(hex);
2319     EC_POINT_free(Q);
2320
2321     return ret;
2322 }
2323
2324 /*
2325  * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2326  */
2327 static int ec_point_hex2point_test(int id)
2328 {
2329     int ret = 0, nid;
2330     EC_GROUP *group = NULL;
2331     const EC_POINT *G = NULL;
2332     EC_POINT *P = NULL;
2333     BN_CTX * bnctx = NULL;
2334
2335     /* Do some setup */
2336     nid = curves[id].nid;
2337     if (!TEST_ptr(bnctx = BN_CTX_new())
2338             || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2339             || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2340             || !TEST_ptr(P = EC_POINT_dup(G, group)))
2341         goto err;
2342
2343     if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2344                                                   POINT_CONVERSION_COMPRESSED,
2345                                                   bnctx))
2346             || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2347                                                          POINT_CONVERSION_COMPRESSED,
2348                                                          bnctx))
2349             || !TEST_true(ec_point_hex2point_test_helper(group, P,
2350                                                          POINT_CONVERSION_UNCOMPRESSED,
2351                                                          bnctx))
2352             || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2353                                                          POINT_CONVERSION_UNCOMPRESSED,
2354                                                          bnctx))
2355             || !TEST_true(ec_point_hex2point_test_helper(group, P,
2356                                                          POINT_CONVERSION_HYBRID,
2357                                                          bnctx))
2358             || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2359                                                          POINT_CONVERSION_HYBRID,
2360                                                          bnctx)))
2361         goto err;
2362
2363     ret = 1;
2364
2365  err:
2366     EC_POINT_free(P);
2367     EC_GROUP_free(group);
2368     BN_CTX_free(bnctx);
2369
2370     return ret;
2371 }
2372
2373 #endif /* OPENSSL_NO_EC */
2374
2375 int setup_tests(void)
2376 {
2377 #ifndef OPENSSL_NO_EC
2378     crv_len = EC_get_builtin_curves(NULL, 0);
2379     if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2380         || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2381         return 0;
2382
2383     ADD_TEST(parameter_test);
2384     ADD_TEST(cofactor_range_test);
2385     ADD_ALL_TESTS(cardinality_test, crv_len);
2386     ADD_TEST(prime_field_tests);
2387 # ifndef OPENSSL_NO_EC2M
2388     ADD_TEST(char2_field_tests);
2389     ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2390 # endif
2391 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
2392     ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2393 # endif
2394     ADD_ALL_TESTS(internal_curve_test, crv_len);
2395     ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2396     ADD_TEST(group_field_test);
2397     ADD_ALL_TESTS(check_named_curve_test, crv_len);
2398     ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2399     ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2400     ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2401     ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2402 #endif /* OPENSSL_NO_EC */
2403     return 1;
2404 }
2405
2406 void cleanup_tests(void)
2407 {
2408 #ifndef OPENSSL_NO_EC
2409     OPENSSL_free(curves);
2410 #endif
2411 }