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