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