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