Raise an error on syscall failure in tls_retry_write_records
[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_param_fromdata_init(pctx), 0)
2413         || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &pkeyparam, params), 0))
2414         goto err;
2415
2416     /*- Check that all the set values are retrievable -*/
2417
2418     /* There should be no match to a group name since the generator changed */
2419     if (!TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
2420                         OSSL_PKEY_PARAM_GROUP_NAME, name, sizeof(name),
2421                         &name_len)))
2422         goto err;
2423
2424     /* The encoding should be explicit as it has no group */
2425     if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2426                        OSSL_PKEY_PARAM_EC_ENCODING,
2427                        name, sizeof(name), &name_len))
2428         || !TEST_str_eq(name, OSSL_PKEY_EC_ENCODING_EXPLICIT))
2429         goto err;
2430
2431     if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2432                        OSSL_PKEY_PARAM_EC_FIELD_TYPE, name, sizeof(name),
2433                        &name_len))
2434         || !TEST_str_eq(name, field_name))
2435         goto err;
2436
2437     if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
2438                        OSSL_PKEY_PARAM_EC_GENERATOR, buf, sizeof(buf), &buf_len))
2439         || !TEST_mem_eq(buf, (int)buf_len, gen, gen_size))
2440         goto err;
2441
2442     if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_P, &p_out))
2443         || !TEST_BN_eq(p_out, p)
2444         || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_A,
2445                                             &a_out))
2446         || !TEST_BN_eq(a_out, a)
2447         || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_B,
2448                                             &b_out))
2449         || !TEST_BN_eq(b_out, b)
2450         || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_ORDER,
2451                                             &order_out))
2452         || !TEST_BN_eq(order_out, EC_GROUP_get0_order(group)))
2453         goto err;
2454
2455     if (EC_GROUP_get0_cofactor(group) != NULL) {
2456         if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam,
2457                            OSSL_PKEY_PARAM_EC_COFACTOR, &cofactor_out))
2458             || !TEST_BN_eq(cofactor_out, EC_GROUP_get0_cofactor(group)))
2459             goto err;
2460     }
2461     if (EC_GROUP_get0_seed(group) != NULL) {
2462         if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
2463                            OSSL_PKEY_PARAM_EC_SEED, buf, sizeof(buf), &buf_len))
2464             || !TEST_mem_eq(buf, buf_len, EC_GROUP_get0_seed(group),
2465                             EC_GROUP_get_seed_len(group)))
2466             goto err;
2467     }
2468
2469     if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
2470         /* No extra fields should be set for a prime field */
2471         if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2472                             OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
2473             || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2474                                OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2475             || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2476                                OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2477             || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2478                                OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2479             || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2480                                OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
2481             || !TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
2482                                OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
2483                                &name_len)))
2484             goto err;
2485     } else {
2486 #ifndef OPENSSL_NO_EC2M
2487         if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2488                            OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
2489             || !TEST_int_eq(EC_GROUP_get_degree(group), i_out)
2490             || !TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
2491                               OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
2492                               &name_len))
2493             || !TEST_str_eq(name, basis_name))
2494             goto err;
2495
2496         if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
2497             if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2498                                OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2499                 || !TEST_int_eq(k1, i_out)
2500                 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2501                                    OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2502                 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2503                                    OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2504                 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2505                                    OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out)))
2506                 goto err;
2507         } else {
2508             if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
2509                                 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
2510                 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2511                                   OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
2512                 || !TEST_int_eq(k1, i_out)
2513                 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2514                                   OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
2515                 || !TEST_int_eq(k2, i_out)
2516                 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
2517                                   OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
2518                 || !TEST_int_eq(k3, i_out))
2519                 goto err;
2520         }
2521 #endif /* OPENSSL_NO_EC2M */
2522     }
2523     if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pkeyparam))
2524         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_GROUP_NAME))
2525         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ENCODING))
2526         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_FIELD_TYPE))
2527         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_P))
2528         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_A))
2529         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_B))
2530         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_GENERATOR))
2531         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ORDER))
2532         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_COFACTOR))
2533         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_SEED))
2534 #ifndef OPENSSL_NO_EC2M
2535         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_M))
2536         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TYPE))
2537         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS))
2538         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K1))
2539         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K2))
2540         || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K3))
2541 #endif
2542         )
2543         goto err;
2544     ret = 1;
2545 err:
2546     BN_free(order_out);
2547     BN_free(cofactor_out);
2548     BN_free(a_out);
2549     BN_free(b_out);
2550     BN_free(p_out);
2551     OSSL_PARAM_BLD_free_params(params);
2552     OSSL_PARAM_BLD_free(bld);
2553     EVP_PKEY_free(pkeyparam);
2554     EVP_PKEY_CTX_free(pctx);
2555     return ret;
2556 }
2557
2558 /*
2559  * check the EC_METHOD respects the supplied EC_GROUP_set_generator G
2560  */
2561 static int custom_generator_test(int id)
2562 {
2563     int ret = 0, nid, bsize;
2564     EC_GROUP *group = NULL;
2565     EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
2566     BN_CTX *ctx = NULL;
2567     BIGNUM *k = NULL;
2568     unsigned char *b1 = NULL, *b2 = NULL;
2569
2570     /* Do some setup */
2571     nid = curves[id].nid;
2572     TEST_note("Curve %s", OBJ_nid2sn(nid));
2573     if (!TEST_ptr(ctx = BN_CTX_new()))
2574         return 0;
2575
2576     BN_CTX_start(ctx);
2577
2578     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
2579         goto err;
2580
2581     /* expected byte length of encoded points */
2582     bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2583     bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */
2584
2585     if (!TEST_ptr(k = BN_CTX_get(ctx))
2586         /* fetch a testing scalar k != 0,1 */
2587         || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
2588                               BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
2589         /* make k even */
2590         || !TEST_true(BN_clear_bit(k, 0))
2591         || !TEST_ptr(G2 = EC_POINT_new(group))
2592         || !TEST_ptr(Q1 = EC_POINT_new(group))
2593         /* Q1 := kG */
2594         || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
2595         /* pull out the bytes of that */
2596         || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2597                                            POINT_CONVERSION_UNCOMPRESSED, NULL,
2598                                            0, ctx), bsize)
2599         || !TEST_ptr(b1 = OPENSSL_malloc(bsize))
2600         || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2601                                            POINT_CONVERSION_UNCOMPRESSED, b1,
2602                                            bsize, ctx), bsize)
2603         /* new generator is G2 := 2G */
2604         || !TEST_true(EC_POINT_dbl(group, G2, EC_GROUP_get0_generator(group),
2605                                    ctx))
2606         || !TEST_true(EC_GROUP_set_generator(group, G2,
2607                                              EC_GROUP_get0_order(group),
2608                                              EC_GROUP_get0_cofactor(group)))
2609         || !TEST_ptr(Q2 = EC_POINT_new(group))
2610         || !TEST_true(BN_rshift1(k, k))
2611         /* Q2 := k/2 G2 */
2612         || !TEST_true(EC_POINT_mul(group, Q2, k, NULL, NULL, ctx))
2613         || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2614                                            POINT_CONVERSION_UNCOMPRESSED, NULL,
2615                                            0, ctx), bsize)
2616         || !TEST_ptr(b2 = OPENSSL_malloc(bsize))
2617         || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2618                                            POINT_CONVERSION_UNCOMPRESSED, b2,
2619                                            bsize, ctx), bsize)
2620         /* Q1 = kG = k/2 G2 = Q2 should hold */
2621         || !TEST_mem_eq(b1, bsize, b2, bsize))
2622         goto err;
2623
2624     if (!do_test_custom_explicit_fromdata(group, ctx, b1, bsize))
2625         goto err;
2626
2627     ret = 1;
2628
2629  err:
2630     EC_POINT_free(Q1);
2631     EC_POINT_free(Q2);
2632     EC_POINT_free(G2);
2633     EC_GROUP_free(group);
2634     BN_CTX_end(ctx);
2635     BN_CTX_free(ctx);
2636     OPENSSL_free(b1);
2637     OPENSSL_free(b2);
2638
2639     return ret;
2640 }
2641
2642 /*
2643  * check creation of curves from explicit params through the public API
2644  */
2645 static int custom_params_test(int id)
2646 {
2647     int ret = 0, nid, bsize;
2648     const char *curve_name = NULL;
2649     EC_GROUP *group = NULL, *altgroup = NULL;
2650     EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
2651     const EC_POINT *Q = NULL;
2652     BN_CTX *ctx = NULL;
2653     BIGNUM *k = NULL;
2654     unsigned char *buf1 = NULL, *buf2 = NULL;
2655     const BIGNUM *z = NULL, *cof = NULL, *priv1 = NULL;
2656     BIGNUM *p = NULL, *a = NULL, *b = NULL;
2657     int is_prime = 0;
2658     EC_KEY *eckey1 = NULL, *eckey2 = NULL;
2659     EVP_PKEY *pkey1 = NULL, *pkey2 = NULL;
2660     EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL;
2661     size_t sslen, t;
2662     unsigned char *pub1 = NULL , *pub2 = NULL;
2663     OSSL_PARAM_BLD *param_bld = NULL;
2664     OSSL_PARAM *params1 = NULL, *params2 = NULL;
2665
2666     /* Do some setup */
2667     nid = curves[id].nid;
2668     curve_name = OBJ_nid2sn(nid);
2669     TEST_note("Curve %s", curve_name);
2670
2671     if (nid == NID_sm2)
2672         return TEST_skip("custom params not supported with SM2");
2673
2674     if (!TEST_ptr(ctx = BN_CTX_new()))
2675         return 0;
2676
2677     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
2678         goto err;
2679
2680     is_prime = EC_GROUP_get_field_type(group) == NID_X9_62_prime_field;
2681 #ifdef OPENSSL_NO_EC2M
2682     if (!is_prime) {
2683         ret = TEST_skip("binary curves not supported in this build");
2684         goto err;
2685     }
2686 #endif
2687
2688     BN_CTX_start(ctx);
2689     if (!TEST_ptr(p = BN_CTX_get(ctx))
2690             || !TEST_ptr(a = BN_CTX_get(ctx))
2691             || !TEST_ptr(b = BN_CTX_get(ctx))
2692             || !TEST_ptr(k = BN_CTX_get(ctx)))
2693         goto err;
2694
2695     /* expected byte length of encoded points */
2696     bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2697     bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */
2698
2699     /* extract parameters from built-in curve */
2700     if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))
2701             || !TEST_ptr(G2 = EC_POINT_new(group))
2702             /* new generator is G2 := 2G */
2703             || !TEST_true(EC_POINT_dbl(group, G2,
2704                                        EC_GROUP_get0_generator(group), ctx))
2705             /* pull out the bytes of that */
2706             || !TEST_int_eq(EC_POINT_point2oct(group, G2,
2707                                                POINT_CONVERSION_UNCOMPRESSED,
2708                                                NULL, 0, ctx), bsize)
2709             || !TEST_ptr(buf1 = OPENSSL_malloc(bsize))
2710             || !TEST_int_eq(EC_POINT_point2oct(group, G2,
2711                                                POINT_CONVERSION_UNCOMPRESSED,
2712                                                buf1, bsize, ctx), bsize)
2713             || !TEST_ptr(z = EC_GROUP_get0_order(group))
2714             || !TEST_ptr(cof = EC_GROUP_get0_cofactor(group))
2715         )
2716         goto err;
2717
2718     /* create a new group using same params (but different generator) */
2719     if (is_prime) {
2720         if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GFp(p, a, b, ctx)))
2721             goto err;
2722     }
2723 #ifndef OPENSSL_NO_EC2M
2724     else {
2725         if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
2726             goto err;
2727     }
2728 #endif
2729
2730     /* set 2*G as the generator of altgroup */
2731     EC_POINT_free(G2); /* discard G2 as it refers to the original group */
2732     if (!TEST_ptr(G2 = EC_POINT_new(altgroup))
2733             || !TEST_true(EC_POINT_oct2point(altgroup, G2, buf1, bsize, ctx))
2734             || !TEST_int_eq(EC_POINT_is_on_curve(altgroup, G2, ctx), 1)
2735             || !TEST_true(EC_GROUP_set_generator(altgroup, G2, z, cof))
2736        )
2737         goto err;
2738
2739     /* verify math checks out */
2740     if (/* allocate temporary points on group and altgroup */
2741             !TEST_ptr(Q1 = EC_POINT_new(group))
2742             || !TEST_ptr(Q2 = EC_POINT_new(altgroup))
2743             /* fetch a testing scalar k != 0,1 */
2744             || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
2745                                   BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
2746             /* make k even */
2747             || !TEST_true(BN_clear_bit(k, 0))
2748             /* Q1 := kG on group */
2749             || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
2750             /* pull out the bytes of that */
2751             || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2752                                                POINT_CONVERSION_UNCOMPRESSED,
2753                                                NULL, 0, ctx), bsize)
2754             || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2755                                                POINT_CONVERSION_UNCOMPRESSED,
2756                                                buf1, bsize, ctx), bsize)
2757             /* k := k/2 */
2758             || !TEST_true(BN_rshift1(k, k))
2759             /* Q2 := k/2 G2 on altgroup */
2760             || !TEST_true(EC_POINT_mul(altgroup, Q2, k, NULL, NULL, ctx))
2761             /* pull out the bytes of that */
2762             || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2,
2763                                                POINT_CONVERSION_UNCOMPRESSED,
2764                                                NULL, 0, ctx), bsize)
2765             || !TEST_ptr(buf2 = OPENSSL_malloc(bsize))
2766             || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2,
2767                                                POINT_CONVERSION_UNCOMPRESSED,
2768                                                buf2, bsize, ctx), bsize)
2769             /* Q1 = kG = k/2 G2 = Q2 should hold */
2770             || !TEST_mem_eq(buf1, bsize, buf2, bsize))
2771         goto err;
2772
2773     /* create two `EC_KEY`s on altgroup */
2774     if (!TEST_ptr(eckey1 = EC_KEY_new())
2775             || !TEST_true(EC_KEY_set_group(eckey1, altgroup))
2776             || !TEST_true(EC_KEY_generate_key(eckey1))
2777             || !TEST_ptr(eckey2 = EC_KEY_new())
2778             || !TEST_true(EC_KEY_set_group(eckey2, altgroup))
2779             || !TEST_true(EC_KEY_generate_key(eckey2)))
2780         goto err;
2781
2782     /* retrieve priv1 for later */
2783     if (!TEST_ptr(priv1 = EC_KEY_get0_private_key(eckey1)))
2784         goto err;
2785
2786     /*
2787      * retrieve bytes for pub1 for later
2788      *
2789      * We compute the pub key in the original group as we will later use it to
2790      * define a provider key in the built-in group.
2791      */
2792     if (!TEST_true(EC_POINT_mul(group, Q1, priv1, NULL, NULL, ctx))
2793             || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2794                                                POINT_CONVERSION_UNCOMPRESSED,
2795                                                NULL, 0, ctx), bsize)
2796             || !TEST_ptr(pub1 = OPENSSL_malloc(bsize))
2797             || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2798                                                POINT_CONVERSION_UNCOMPRESSED,
2799                                                pub1, bsize, ctx), bsize))
2800         goto err;
2801
2802     /* retrieve bytes for pub2 for later */
2803     if (!TEST_ptr(Q = EC_KEY_get0_public_key(eckey2))
2804             || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q,
2805                                                POINT_CONVERSION_UNCOMPRESSED,
2806                                                NULL, 0, ctx), bsize)
2807             || !TEST_ptr(pub2 = OPENSSL_malloc(bsize))
2808             || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q,
2809                                                POINT_CONVERSION_UNCOMPRESSED,
2810                                                pub2, bsize, ctx), bsize))
2811         goto err;
2812
2813     /* create two `EVP_PKEY`s from the `EC_KEY`s */
2814     if(!TEST_ptr(pkey1 = EVP_PKEY_new())
2815             || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey1, eckey1), 1))
2816         goto err;
2817     eckey1 = NULL; /* ownership passed to pkey1 */
2818     if(!TEST_ptr(pkey2 = EVP_PKEY_new())
2819             || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey2, eckey2), 1))
2820         goto err;
2821     eckey2 = NULL; /* ownership passed to pkey2 */
2822
2823     /* Compute keyexchange in both directions */
2824     if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
2825             || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
2826             || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
2827             || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &sslen), 1)
2828             || !TEST_int_gt(bsize, sslen)
2829             || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &sslen), 1))
2830         goto err;
2831     if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new(pkey2, NULL))
2832             || !TEST_int_eq(EVP_PKEY_derive_init(pctx2), 1)
2833             || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx2, pkey1), 1)
2834             || !TEST_int_eq(EVP_PKEY_derive(pctx2, NULL, &t), 1)
2835             || !TEST_int_gt(bsize, t)
2836             || !TEST_int_le(sslen, t)
2837             || !TEST_int_eq(EVP_PKEY_derive(pctx2, buf2, &t), 1))
2838         goto err;
2839
2840     /* Both sides should expect the same shared secret */
2841     if (!TEST_mem_eq(buf1, sslen, buf2, t))
2842         goto err;
2843
2844     /* Build parameters for provider-native keys */
2845     if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new())
2846             || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld,
2847                                                           OSSL_PKEY_PARAM_GROUP_NAME,
2848                                                           curve_name, 0))
2849             || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld,
2850                                                            OSSL_PKEY_PARAM_PUB_KEY,
2851                                                            pub1, bsize))
2852             || !TEST_true(OSSL_PARAM_BLD_push_BN(param_bld,
2853                                                  OSSL_PKEY_PARAM_PRIV_KEY,
2854                                                  priv1))
2855             || !TEST_ptr(params1 = OSSL_PARAM_BLD_to_param(param_bld)))
2856         goto err;
2857
2858     OSSL_PARAM_BLD_free(param_bld);
2859     if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new())
2860             || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld,
2861                                                           OSSL_PKEY_PARAM_GROUP_NAME,
2862                                                           curve_name, 0))
2863             || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld,
2864                                                            OSSL_PKEY_PARAM_PUB_KEY,
2865                                                            pub2, bsize))
2866             || !TEST_ptr(params2 = OSSL_PARAM_BLD_to_param(param_bld)))
2867         goto err;
2868
2869     /* create two new provider-native `EVP_PKEY`s */
2870     EVP_PKEY_CTX_free(pctx2);
2871     if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL))
2872             || !TEST_true(EVP_PKEY_key_fromdata_init(pctx2))
2873             || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey1, params1))
2874             || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey2, params2)))
2875         goto err;
2876
2877     /* compute keyexchange once more using the provider keys */
2878     EVP_PKEY_CTX_free(pctx1);
2879     if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
2880             || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
2881             || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
2882             || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1)
2883             || !TEST_int_gt(bsize, t)
2884             || !TEST_int_le(sslen, t)
2885             || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1)
2886             /* compare with previous result */
2887             || !TEST_mem_eq(buf1, t, buf2, sslen))
2888         goto err;
2889
2890     ret = 1;
2891
2892  err:
2893     BN_CTX_end(ctx);
2894     BN_CTX_free(ctx);
2895     OSSL_PARAM_BLD_free(param_bld);
2896     OSSL_PARAM_BLD_free_params(params1);
2897     OSSL_PARAM_BLD_free_params(params2);
2898     EC_POINT_free(Q1);
2899     EC_POINT_free(Q2);
2900     EC_POINT_free(G2);
2901     EC_GROUP_free(group);
2902     EC_GROUP_free(altgroup);
2903     OPENSSL_free(buf1);
2904     OPENSSL_free(buf2);
2905     OPENSSL_free(pub1);
2906     OPENSSL_free(pub2);
2907     EC_KEY_free(eckey1);
2908     EC_KEY_free(eckey2);
2909     EVP_PKEY_free(pkey1);
2910     EVP_PKEY_free(pkey2);
2911     EVP_PKEY_CTX_free(pctx1);
2912     EVP_PKEY_CTX_free(pctx2);
2913
2914     return ret;
2915 }
2916
2917 int setup_tests(void)
2918 {
2919     crv_len = EC_get_builtin_curves(NULL, 0);
2920     if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2921         || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2922         return 0;
2923
2924     ADD_TEST(parameter_test);
2925     ADD_TEST(cofactor_range_test);
2926     ADD_ALL_TESTS(cardinality_test, crv_len);
2927     ADD_TEST(prime_field_tests);
2928 #ifndef OPENSSL_NO_EC2M
2929     ADD_TEST(char2_field_tests);
2930     ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2931 #endif
2932     ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2933     ADD_ALL_TESTS(internal_curve_test, crv_len);
2934     ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2935     ADD_TEST(group_field_test);
2936     ADD_ALL_TESTS(check_named_curve_test, crv_len);
2937     ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
2938     ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
2939     ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2940     ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2941     ADD_ALL_TESTS(custom_generator_test, crv_len);
2942     ADD_ALL_TESTS(custom_params_test, crv_len);
2943     return 1;
2944 }
2945
2946 void cleanup_tests(void)
2947 {
2948     OPENSSL_free(curves);
2949 }