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