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