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