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