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