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