1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/*
11e1051a39Sopenharmony_ci * Low level APIs are deprecated for public use, but still ok for internal use.
12e1051a39Sopenharmony_ci */
13e1051a39Sopenharmony_ci#include "internal/deprecated.h"
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_ci#include "internal/nelem.h"
16e1051a39Sopenharmony_ci#include "testutil.h"
17e1051a39Sopenharmony_ci#include <openssl/ec.h>
18e1051a39Sopenharmony_ci#include "ec_local.h"
19e1051a39Sopenharmony_ci#include <openssl/objects.h>
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_cistatic size_t crv_len = 0;
22e1051a39Sopenharmony_cistatic EC_builtin_curve *curves = NULL;
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci/* sanity checks field_inv function pointer in EC_METHOD */
25e1051a39Sopenharmony_cistatic int group_field_tests(const EC_GROUP *group, BN_CTX *ctx)
26e1051a39Sopenharmony_ci{
27e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL;
28e1051a39Sopenharmony_ci    int ret = 0;
29e1051a39Sopenharmony_ci
30e1051a39Sopenharmony_ci    if (group->meth->field_inv == NULL || group->meth->field_mul == NULL)
31e1051a39Sopenharmony_ci        return 1;
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
34e1051a39Sopenharmony_ci    a = BN_CTX_get(ctx);
35e1051a39Sopenharmony_ci    b = BN_CTX_get(ctx);
36e1051a39Sopenharmony_ci    if (!TEST_ptr(c = BN_CTX_get(ctx))
37e1051a39Sopenharmony_ci        /* 1/1 = 1 */
38e1051a39Sopenharmony_ci        || !TEST_true(group->meth->field_inv(group, b, BN_value_one(), ctx))
39e1051a39Sopenharmony_ci        || !TEST_true(BN_is_one(b))
40e1051a39Sopenharmony_ci        /* (1/a)*a = 1 */
41e1051a39Sopenharmony_ci        || !TEST_true(BN_rand(a, BN_num_bits(group->field) - 1,
42e1051a39Sopenharmony_ci                              BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
43e1051a39Sopenharmony_ci        || !TEST_true(group->meth->field_inv(group, b, a, ctx))
44e1051a39Sopenharmony_ci        || (group->meth->field_encode &&
45e1051a39Sopenharmony_ci            !TEST_true(group->meth->field_encode(group, a, a, ctx)))
46e1051a39Sopenharmony_ci        || (group->meth->field_encode &&
47e1051a39Sopenharmony_ci            !TEST_true(group->meth->field_encode(group, b, b, ctx)))
48e1051a39Sopenharmony_ci        || !TEST_true(group->meth->field_mul(group, c, a, b, ctx))
49e1051a39Sopenharmony_ci        || (group->meth->field_decode &&
50e1051a39Sopenharmony_ci            !TEST_true(group->meth->field_decode(group, c, c, ctx)))
51e1051a39Sopenharmony_ci        || !TEST_true(BN_is_one(c)))
52e1051a39Sopenharmony_ci        goto err;
53e1051a39Sopenharmony_ci
54e1051a39Sopenharmony_ci    /* 1/0 = error */
55e1051a39Sopenharmony_ci    BN_zero(a);
56e1051a39Sopenharmony_ci    if (!TEST_false(group->meth->field_inv(group, b, a, ctx))
57e1051a39Sopenharmony_ci        || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
58e1051a39Sopenharmony_ci        || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
59e1051a39Sopenharmony_ci                      EC_R_CANNOT_INVERT)
60e1051a39Sopenharmony_ci        /* 1/p = error */
61e1051a39Sopenharmony_ci        || !TEST_false(group->meth->field_inv(group, b, group->field, ctx))
62e1051a39Sopenharmony_ci        || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
63e1051a39Sopenharmony_ci        || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
64e1051a39Sopenharmony_ci                      EC_R_CANNOT_INVERT))
65e1051a39Sopenharmony_ci        goto err;
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_ci    ERR_clear_error();
68e1051a39Sopenharmony_ci    ret = 1;
69e1051a39Sopenharmony_ci err:
70e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
71e1051a39Sopenharmony_ci    return ret;
72e1051a39Sopenharmony_ci}
73e1051a39Sopenharmony_ci
74e1051a39Sopenharmony_ci/* wrapper for group_field_tests for explicit curve params and EC_METHOD */
75e1051a39Sopenharmony_cistatic int field_tests(const EC_METHOD *meth, const unsigned char *params,
76e1051a39Sopenharmony_ci                       int len)
77e1051a39Sopenharmony_ci{
78e1051a39Sopenharmony_ci    BN_CTX *ctx = NULL;
79e1051a39Sopenharmony_ci    BIGNUM *p = NULL, *a = NULL, *b = NULL;
80e1051a39Sopenharmony_ci    EC_GROUP *group = NULL;
81e1051a39Sopenharmony_ci    int ret = 0;
82e1051a39Sopenharmony_ci
83e1051a39Sopenharmony_ci    if (!TEST_ptr(ctx = BN_CTX_new()))
84e1051a39Sopenharmony_ci        return 0;
85e1051a39Sopenharmony_ci
86e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
87e1051a39Sopenharmony_ci    p = BN_CTX_get(ctx);
88e1051a39Sopenharmony_ci    a = BN_CTX_get(ctx);
89e1051a39Sopenharmony_ci    if (!TEST_ptr(b = BN_CTX_get(ctx))
90e1051a39Sopenharmony_ci        || !TEST_ptr(group = EC_GROUP_new(meth))
91e1051a39Sopenharmony_ci        || !TEST_true(BN_bin2bn(params, len, p))
92e1051a39Sopenharmony_ci        || !TEST_true(BN_bin2bn(params + len, len, a))
93e1051a39Sopenharmony_ci        || !TEST_true(BN_bin2bn(params + 2 * len, len, b))
94e1051a39Sopenharmony_ci        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
95e1051a39Sopenharmony_ci        || !group_field_tests(group, ctx))
96e1051a39Sopenharmony_ci        goto err;
97e1051a39Sopenharmony_ci    ret = 1;
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ci err:
100e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
101e1051a39Sopenharmony_ci    BN_CTX_free(ctx);
102e1051a39Sopenharmony_ci    if (group != NULL)
103e1051a39Sopenharmony_ci        EC_GROUP_free(group);
104e1051a39Sopenharmony_ci    return ret;
105e1051a39Sopenharmony_ci}
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ci/* NIST prime curve P-256 */
108e1051a39Sopenharmony_cistatic const unsigned char params_p256[] = {
109e1051a39Sopenharmony_ci    /* p */
110e1051a39Sopenharmony_ci    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
111e1051a39Sopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
112e1051a39Sopenharmony_ci    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113e1051a39Sopenharmony_ci    /* a */
114e1051a39Sopenharmony_ci    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
115e1051a39Sopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
116e1051a39Sopenharmony_ci    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
117e1051a39Sopenharmony_ci    /* b */
118e1051a39Sopenharmony_ci    0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
119e1051a39Sopenharmony_ci    0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
120e1051a39Sopenharmony_ci    0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
121e1051a39Sopenharmony_ci};
122e1051a39Sopenharmony_ci
123e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M
124e1051a39Sopenharmony_ci/* NIST binary curve B-283 */
125e1051a39Sopenharmony_cistatic const unsigned char params_b283[] = {
126e1051a39Sopenharmony_ci    /* p */
127e1051a39Sopenharmony_ci    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128e1051a39Sopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129e1051a39Sopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
130e1051a39Sopenharmony_ci    /* a */
131e1051a39Sopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132e1051a39Sopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133e1051a39Sopenharmony_ci    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
134e1051a39Sopenharmony_ci    /* b */
135e1051a39Sopenharmony_ci    0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A,
136e1051a39Sopenharmony_ci    0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2,
137e1051a39Sopenharmony_ci    0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5
138e1051a39Sopenharmony_ci};
139e1051a39Sopenharmony_ci#endif
140e1051a39Sopenharmony_ci
141e1051a39Sopenharmony_ci/* test EC_GFp_simple_method directly */
142e1051a39Sopenharmony_cistatic int field_tests_ecp_simple(void)
143e1051a39Sopenharmony_ci{
144e1051a39Sopenharmony_ci    TEST_info("Testing EC_GFp_simple_method()\n");
145e1051a39Sopenharmony_ci    return field_tests(EC_GFp_simple_method(), params_p256,
146e1051a39Sopenharmony_ci                       sizeof(params_p256) / 3);
147e1051a39Sopenharmony_ci}
148e1051a39Sopenharmony_ci
149e1051a39Sopenharmony_ci/* test EC_GFp_mont_method directly */
150e1051a39Sopenharmony_cistatic int field_tests_ecp_mont(void)
151e1051a39Sopenharmony_ci{
152e1051a39Sopenharmony_ci    TEST_info("Testing EC_GFp_mont_method()\n");
153e1051a39Sopenharmony_ci    return field_tests(EC_GFp_mont_method(), params_p256,
154e1051a39Sopenharmony_ci                       sizeof(params_p256) / 3);
155e1051a39Sopenharmony_ci}
156e1051a39Sopenharmony_ci
157e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M
158e1051a39Sopenharmony_ci/* Test that decoding of invalid GF2m field parameters fails. */
159e1051a39Sopenharmony_cistatic int ec2m_field_sanity(void)
160e1051a39Sopenharmony_ci{
161e1051a39Sopenharmony_ci    int ret = 0;
162e1051a39Sopenharmony_ci    BN_CTX *ctx = BN_CTX_new();
163e1051a39Sopenharmony_ci    BIGNUM *p, *a, *b;
164e1051a39Sopenharmony_ci    EC_GROUP *group1 = NULL, *group2 = NULL, *group3 = NULL;
165e1051a39Sopenharmony_ci
166e1051a39Sopenharmony_ci    TEST_info("Testing GF2m hardening\n");
167e1051a39Sopenharmony_ci
168e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
169e1051a39Sopenharmony_ci    p = BN_CTX_get(ctx);
170e1051a39Sopenharmony_ci    a = BN_CTX_get(ctx);
171e1051a39Sopenharmony_ci    if (!TEST_ptr(b = BN_CTX_get(ctx))
172e1051a39Sopenharmony_ci        || !TEST_true(BN_one(a))
173e1051a39Sopenharmony_ci        || !TEST_true(BN_one(b)))
174e1051a39Sopenharmony_ci        goto out;
175e1051a39Sopenharmony_ci
176e1051a39Sopenharmony_ci    /* Even pentanomial value should be rejected */
177e1051a39Sopenharmony_ci    if (!TEST_true(BN_set_word(p, 0xf2)))
178e1051a39Sopenharmony_ci        goto out;
179e1051a39Sopenharmony_ci    if (!TEST_ptr_null(group1 = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
180e1051a39Sopenharmony_ci        TEST_error("Zero constant term accepted in GF2m polynomial");
181e1051a39Sopenharmony_ci
182e1051a39Sopenharmony_ci    /* Odd hexanomial should also be rejected */
183e1051a39Sopenharmony_ci    if (!TEST_true(BN_set_word(p, 0xf3)))
184e1051a39Sopenharmony_ci        goto out;
185e1051a39Sopenharmony_ci    if (!TEST_ptr_null(group2 = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
186e1051a39Sopenharmony_ci        TEST_error("Hexanomial accepted as GF2m polynomial");
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ci    /* Excessive polynomial degree should also be rejected */
189e1051a39Sopenharmony_ci    if (!TEST_true(BN_set_word(p, 0x71))
190e1051a39Sopenharmony_ci        || !TEST_true(BN_set_bit(p, OPENSSL_ECC_MAX_FIELD_BITS + 1)))
191e1051a39Sopenharmony_ci        goto out;
192e1051a39Sopenharmony_ci    if (!TEST_ptr_null(group3 = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
193e1051a39Sopenharmony_ci        TEST_error("GF2m polynomial degree > %d accepted",
194e1051a39Sopenharmony_ci                   OPENSSL_ECC_MAX_FIELD_BITS);
195e1051a39Sopenharmony_ci
196e1051a39Sopenharmony_ci    ret = group1 == NULL && group2 == NULL && group3 == NULL;
197e1051a39Sopenharmony_ci
198e1051a39Sopenharmony_ci out:
199e1051a39Sopenharmony_ci    EC_GROUP_free(group1);
200e1051a39Sopenharmony_ci    EC_GROUP_free(group2);
201e1051a39Sopenharmony_ci    EC_GROUP_free(group3);
202e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
203e1051a39Sopenharmony_ci    BN_CTX_free(ctx);
204e1051a39Sopenharmony_ci
205e1051a39Sopenharmony_ci    return ret;
206e1051a39Sopenharmony_ci}
207e1051a39Sopenharmony_ci
208e1051a39Sopenharmony_ci/* test EC_GF2m_simple_method directly */
209e1051a39Sopenharmony_cistatic int field_tests_ec2_simple(void)
210e1051a39Sopenharmony_ci{
211e1051a39Sopenharmony_ci    TEST_info("Testing EC_GF2m_simple_method()\n");
212e1051a39Sopenharmony_ci    return field_tests(EC_GF2m_simple_method(), params_b283,
213e1051a39Sopenharmony_ci                       sizeof(params_b283) / 3);
214e1051a39Sopenharmony_ci}
215e1051a39Sopenharmony_ci#endif
216e1051a39Sopenharmony_ci
217e1051a39Sopenharmony_ci/* test default method for a named curve */
218e1051a39Sopenharmony_cistatic int field_tests_default(int n)
219e1051a39Sopenharmony_ci{
220e1051a39Sopenharmony_ci    BN_CTX *ctx = NULL;
221e1051a39Sopenharmony_ci    EC_GROUP *group = NULL;
222e1051a39Sopenharmony_ci    int nid = curves[n].nid;
223e1051a39Sopenharmony_ci    int ret = 0;
224e1051a39Sopenharmony_ci
225e1051a39Sopenharmony_ci    TEST_info("Testing curve %s\n", OBJ_nid2sn(nid));
226e1051a39Sopenharmony_ci
227e1051a39Sopenharmony_ci    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
228e1051a39Sopenharmony_ci        || !TEST_ptr(ctx = BN_CTX_new())
229e1051a39Sopenharmony_ci        || !group_field_tests(group, ctx))
230e1051a39Sopenharmony_ci        goto err;
231e1051a39Sopenharmony_ci
232e1051a39Sopenharmony_ci    ret = 1;
233e1051a39Sopenharmony_ci err:
234e1051a39Sopenharmony_ci    if (group != NULL)
235e1051a39Sopenharmony_ci        EC_GROUP_free(group);
236e1051a39Sopenharmony_ci    if (ctx != NULL)
237e1051a39Sopenharmony_ci        BN_CTX_free(ctx);
238e1051a39Sopenharmony_ci    return ret;
239e1051a39Sopenharmony_ci}
240e1051a39Sopenharmony_ci
241e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
242e1051a39Sopenharmony_ci/*
243e1051a39Sopenharmony_ci * Tests a point known to cause an incorrect underflow in an old version of
244e1051a39Sopenharmony_ci * ecp_nist521.c
245e1051a39Sopenharmony_ci */
246e1051a39Sopenharmony_cistatic int underflow_test(void)
247e1051a39Sopenharmony_ci{
248e1051a39Sopenharmony_ci    BN_CTX *ctx = NULL;
249e1051a39Sopenharmony_ci    EC_GROUP *grp = NULL;
250e1051a39Sopenharmony_ci    EC_POINT *P = NULL, *Q = NULL, *R = NULL;
251e1051a39Sopenharmony_ci    BIGNUM *x1 = NULL, *y1 = NULL, *z1 = NULL, *x2 = NULL, *y2 = NULL;
252e1051a39Sopenharmony_ci    BIGNUM *k = NULL;
253e1051a39Sopenharmony_ci    int testresult = 0;
254e1051a39Sopenharmony_ci    const char *x1str =
255e1051a39Sopenharmony_ci        "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4"
256e1051a39Sopenharmony_ci        "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004";
257e1051a39Sopenharmony_ci    const char *p521m1 =
258e1051a39Sopenharmony_ci        "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
259e1051a39Sopenharmony_ci        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
260e1051a39Sopenharmony_ci
261e1051a39Sopenharmony_ci    ctx = BN_CTX_new();
262e1051a39Sopenharmony_ci    if (!TEST_ptr(ctx))
263e1051a39Sopenharmony_ci        return 0;
264e1051a39Sopenharmony_ci
265e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
266e1051a39Sopenharmony_ci    x1 = BN_CTX_get(ctx);
267e1051a39Sopenharmony_ci    y1 = BN_CTX_get(ctx);
268e1051a39Sopenharmony_ci    z1 = BN_CTX_get(ctx);
269e1051a39Sopenharmony_ci    x2 = BN_CTX_get(ctx);
270e1051a39Sopenharmony_ci    y2 = BN_CTX_get(ctx);
271e1051a39Sopenharmony_ci    k = BN_CTX_get(ctx);
272e1051a39Sopenharmony_ci    if (!TEST_ptr(k))
273e1051a39Sopenharmony_ci        goto err;
274e1051a39Sopenharmony_ci
275e1051a39Sopenharmony_ci    grp = EC_GROUP_new_by_curve_name(NID_secp521r1);
276e1051a39Sopenharmony_ci    P = EC_POINT_new(grp);
277e1051a39Sopenharmony_ci    Q = EC_POINT_new(grp);
278e1051a39Sopenharmony_ci    R = EC_POINT_new(grp);
279e1051a39Sopenharmony_ci    if (!TEST_ptr(grp) || !TEST_ptr(P) || !TEST_ptr(Q) || !TEST_ptr(R))
280e1051a39Sopenharmony_ci        goto err;
281e1051a39Sopenharmony_ci
282e1051a39Sopenharmony_ci    if (!TEST_int_gt(BN_hex2bn(&x1, x1str), 0)
283e1051a39Sopenharmony_ci            || !TEST_int_gt(BN_hex2bn(&y1, p521m1), 0)
284e1051a39Sopenharmony_ci            || !TEST_int_gt(BN_hex2bn(&z1, p521m1), 0)
285e1051a39Sopenharmony_ci            || !TEST_int_gt(BN_hex2bn(&k, "02"), 0)
286e1051a39Sopenharmony_ci            || !TEST_true(ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(grp, P, x1,
287e1051a39Sopenharmony_ci                                                                             y1, z1, ctx))
288e1051a39Sopenharmony_ci            || !TEST_true(EC_POINT_mul(grp, Q, NULL, P, k, ctx))
289e1051a39Sopenharmony_ci            || !TEST_true(EC_POINT_get_affine_coordinates(grp, Q, x1, y1, ctx))
290e1051a39Sopenharmony_ci            || !TEST_true(EC_POINT_dbl(grp, R, P, ctx))
291e1051a39Sopenharmony_ci            || !TEST_true(EC_POINT_get_affine_coordinates(grp, R, x2, y2, ctx)))
292e1051a39Sopenharmony_ci        goto err;
293e1051a39Sopenharmony_ci
294e1051a39Sopenharmony_ci    if (!TEST_int_eq(BN_cmp(x1, x2), 0)
295e1051a39Sopenharmony_ci            || !TEST_int_eq(BN_cmp(y1, y2), 0))
296e1051a39Sopenharmony_ci        goto err;
297e1051a39Sopenharmony_ci
298e1051a39Sopenharmony_ci    testresult = 1;
299e1051a39Sopenharmony_ci
300e1051a39Sopenharmony_ci err:
301e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
302e1051a39Sopenharmony_ci    EC_POINT_free(P);
303e1051a39Sopenharmony_ci    EC_POINT_free(Q);
304e1051a39Sopenharmony_ci    EC_POINT_free(R);
305e1051a39Sopenharmony_ci    EC_GROUP_free(grp);
306e1051a39Sopenharmony_ci    BN_CTX_free(ctx);
307e1051a39Sopenharmony_ci
308e1051a39Sopenharmony_ci    return testresult;
309e1051a39Sopenharmony_ci}
310e1051a39Sopenharmony_ci#endif
311e1051a39Sopenharmony_ci
312e1051a39Sopenharmony_ci/*
313e1051a39Sopenharmony_ci * Tests behavior of the EC_KEY_set_private_key
314e1051a39Sopenharmony_ci */
315e1051a39Sopenharmony_cistatic int set_private_key(void)
316e1051a39Sopenharmony_ci{
317e1051a39Sopenharmony_ci    EC_KEY *key = NULL, *aux_key = NULL;
318e1051a39Sopenharmony_ci    int testresult = 0;
319e1051a39Sopenharmony_ci
320e1051a39Sopenharmony_ci    key = EC_KEY_new_by_curve_name(NID_secp224r1);
321e1051a39Sopenharmony_ci    aux_key = EC_KEY_new_by_curve_name(NID_secp224r1);
322e1051a39Sopenharmony_ci    if (!TEST_ptr(key)
323e1051a39Sopenharmony_ci        || !TEST_ptr(aux_key)
324e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_KEY_generate_key(key), 1)
325e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_KEY_generate_key(aux_key), 1))
326e1051a39Sopenharmony_ci        goto err;
327e1051a39Sopenharmony_ci
328e1051a39Sopenharmony_ci    /* Test setting a valid private key */
329e1051a39Sopenharmony_ci    if (!TEST_int_eq(EC_KEY_set_private_key(key, aux_key->priv_key), 1))
330e1051a39Sopenharmony_ci        goto err;
331e1051a39Sopenharmony_ci
332e1051a39Sopenharmony_ci    /* Test compliance with legacy behavior for NULL private keys */
333e1051a39Sopenharmony_ci    if (!TEST_int_eq(EC_KEY_set_private_key(key, NULL), 0)
334e1051a39Sopenharmony_ci        || !TEST_ptr_null(key->priv_key))
335e1051a39Sopenharmony_ci        goto err;
336e1051a39Sopenharmony_ci
337e1051a39Sopenharmony_ci    testresult = 1;
338e1051a39Sopenharmony_ci
339e1051a39Sopenharmony_ci err:
340e1051a39Sopenharmony_ci    EC_KEY_free(key);
341e1051a39Sopenharmony_ci    EC_KEY_free(aux_key);
342e1051a39Sopenharmony_ci    return testresult;
343e1051a39Sopenharmony_ci}
344e1051a39Sopenharmony_ci
345e1051a39Sopenharmony_ci/*
346e1051a39Sopenharmony_ci * Tests behavior of the decoded_from_explicit_params flag and API
347e1051a39Sopenharmony_ci */
348e1051a39Sopenharmony_cistatic int decoded_flag_test(void)
349e1051a39Sopenharmony_ci{
350e1051a39Sopenharmony_ci    EC_GROUP *grp;
351e1051a39Sopenharmony_ci    EC_GROUP *grp_copy = NULL;
352e1051a39Sopenharmony_ci    ECPARAMETERS *ecparams = NULL;
353e1051a39Sopenharmony_ci    ECPKPARAMETERS *ecpkparams = NULL;
354e1051a39Sopenharmony_ci    EC_KEY *key = NULL;
355e1051a39Sopenharmony_ci    unsigned char *encodedparams = NULL;
356e1051a39Sopenharmony_ci    const unsigned char *encp;
357e1051a39Sopenharmony_ci    int encodedlen;
358e1051a39Sopenharmony_ci    int testresult = 0;
359e1051a39Sopenharmony_ci
360e1051a39Sopenharmony_ci    /* Test EC_GROUP_new not setting the flag */
361e1051a39Sopenharmony_ci    grp = EC_GROUP_new(EC_GFp_simple_method());
362e1051a39Sopenharmony_ci    if (!TEST_ptr(grp)
363e1051a39Sopenharmony_ci        || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
364e1051a39Sopenharmony_ci        goto err;
365e1051a39Sopenharmony_ci    EC_GROUP_free(grp);
366e1051a39Sopenharmony_ci
367e1051a39Sopenharmony_ci    /* Test EC_GROUP_new_by_curve_name not setting the flag */
368e1051a39Sopenharmony_ci    grp = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
369e1051a39Sopenharmony_ci    if (!TEST_ptr(grp)
370e1051a39Sopenharmony_ci        || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
371e1051a39Sopenharmony_ci        goto err;
372e1051a39Sopenharmony_ci
373e1051a39Sopenharmony_ci    /* Test EC_GROUP_new_from_ecparameters not setting the flag */
374e1051a39Sopenharmony_ci    if (!TEST_ptr(ecparams = EC_GROUP_get_ecparameters(grp, NULL))
375e1051a39Sopenharmony_ci        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecparameters(ecparams))
376e1051a39Sopenharmony_ci        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
377e1051a39Sopenharmony_ci        goto err;
378e1051a39Sopenharmony_ci    EC_GROUP_free(grp_copy);
379e1051a39Sopenharmony_ci    grp_copy = NULL;
380e1051a39Sopenharmony_ci    ECPARAMETERS_free(ecparams);
381e1051a39Sopenharmony_ci    ecparams = NULL;
382e1051a39Sopenharmony_ci
383e1051a39Sopenharmony_ci    /* Test EC_GROUP_new_from_ecpkparameters not setting the flag */
384e1051a39Sopenharmony_ci    if (!TEST_int_eq(EC_GROUP_get_asn1_flag(grp), OPENSSL_EC_NAMED_CURVE)
385e1051a39Sopenharmony_ci        || !TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
386e1051a39Sopenharmony_ci        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
387e1051a39Sopenharmony_ci        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)
388e1051a39Sopenharmony_ci        || !TEST_ptr(key = EC_KEY_new())
389e1051a39Sopenharmony_ci    /* Test EC_KEY_decoded_from_explicit_params on key without a group */
390e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), -1)
391e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
392e1051a39Sopenharmony_ci    /* Test EC_KEY_decoded_from_explicit_params negative case */
393e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 0))
394e1051a39Sopenharmony_ci        goto err;
395e1051a39Sopenharmony_ci    EC_GROUP_free(grp_copy);
396e1051a39Sopenharmony_ci    grp_copy = NULL;
397e1051a39Sopenharmony_ci    ECPKPARAMETERS_free(ecpkparams);
398e1051a39Sopenharmony_ci    ecpkparams = NULL;
399e1051a39Sopenharmony_ci
400e1051a39Sopenharmony_ci    /* Test d2i_ECPKParameters with named params not setting the flag */
401e1051a39Sopenharmony_ci    if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
402e1051a39Sopenharmony_ci        || !TEST_ptr(encp = encodedparams)
403e1051a39Sopenharmony_ci        || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
404e1051a39Sopenharmony_ci        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
405e1051a39Sopenharmony_ci        goto err;
406e1051a39Sopenharmony_ci    EC_GROUP_free(grp_copy);
407e1051a39Sopenharmony_ci    grp_copy = NULL;
408e1051a39Sopenharmony_ci    OPENSSL_free(encodedparams);
409e1051a39Sopenharmony_ci    encodedparams = NULL;
410e1051a39Sopenharmony_ci
411e1051a39Sopenharmony_ci    /* Asn1 flag stays set to explicit with EC_GROUP_new_from_ecpkparameters */
412e1051a39Sopenharmony_ci    EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_EXPLICIT_CURVE);
413e1051a39Sopenharmony_ci    if (!TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
414e1051a39Sopenharmony_ci        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
415e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
416e1051a39Sopenharmony_ci        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
417e1051a39Sopenharmony_ci        goto err;
418e1051a39Sopenharmony_ci    EC_GROUP_free(grp_copy);
419e1051a39Sopenharmony_ci    grp_copy = NULL;
420e1051a39Sopenharmony_ci
421e1051a39Sopenharmony_ci    /* Test d2i_ECPKParameters with explicit params setting the flag */
422e1051a39Sopenharmony_ci    if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
423e1051a39Sopenharmony_ci        || !TEST_ptr(encp = encodedparams)
424e1051a39Sopenharmony_ci        || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
425e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
426e1051a39Sopenharmony_ci        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 1)
427e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
428e1051a39Sopenharmony_ci    /* Test EC_KEY_decoded_from_explicit_params positive case */
429e1051a39Sopenharmony_ci        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 1))
430e1051a39Sopenharmony_ci        goto err;
431e1051a39Sopenharmony_ci
432e1051a39Sopenharmony_ci    testresult = 1;
433e1051a39Sopenharmony_ci
434e1051a39Sopenharmony_ci err:
435e1051a39Sopenharmony_ci    EC_KEY_free(key);
436e1051a39Sopenharmony_ci    EC_GROUP_free(grp);
437e1051a39Sopenharmony_ci    EC_GROUP_free(grp_copy);
438e1051a39Sopenharmony_ci    ECPARAMETERS_free(ecparams);
439e1051a39Sopenharmony_ci    ECPKPARAMETERS_free(ecpkparams);
440e1051a39Sopenharmony_ci    OPENSSL_free(encodedparams);
441e1051a39Sopenharmony_ci
442e1051a39Sopenharmony_ci    return testresult;
443e1051a39Sopenharmony_ci}
444e1051a39Sopenharmony_ci
445e1051a39Sopenharmony_cistatic
446e1051a39Sopenharmony_ciint ecpkparams_i2d2i_test(int n)
447e1051a39Sopenharmony_ci{
448e1051a39Sopenharmony_ci    EC_GROUP *g1 = NULL, *g2 = NULL;
449e1051a39Sopenharmony_ci    FILE *fp = NULL;
450e1051a39Sopenharmony_ci    int nid = curves[n].nid;
451e1051a39Sopenharmony_ci    int testresult = 0;
452e1051a39Sopenharmony_ci
453e1051a39Sopenharmony_ci    /* create group */
454e1051a39Sopenharmony_ci    if (!TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid)))
455e1051a39Sopenharmony_ci        goto end;
456e1051a39Sopenharmony_ci
457e1051a39Sopenharmony_ci    /* encode params to file */
458e1051a39Sopenharmony_ci    if (!TEST_ptr(fp = fopen("params.der", "wb"))
459e1051a39Sopenharmony_ci            || !TEST_true(i2d_ECPKParameters_fp(fp, g1)))
460e1051a39Sopenharmony_ci        goto end;
461e1051a39Sopenharmony_ci
462e1051a39Sopenharmony_ci    /* flush and close file */
463e1051a39Sopenharmony_ci    if (!TEST_int_eq(fclose(fp), 0)) {
464e1051a39Sopenharmony_ci        fp = NULL;
465e1051a39Sopenharmony_ci        goto end;
466e1051a39Sopenharmony_ci    }
467e1051a39Sopenharmony_ci    fp = NULL;
468e1051a39Sopenharmony_ci
469e1051a39Sopenharmony_ci    /* decode params from file */
470e1051a39Sopenharmony_ci    if (!TEST_ptr(fp = fopen("params.der", "rb"))
471e1051a39Sopenharmony_ci            || !TEST_ptr(g2 = d2i_ECPKParameters_fp(fp, NULL)))
472e1051a39Sopenharmony_ci        goto end;
473e1051a39Sopenharmony_ci
474e1051a39Sopenharmony_ci    testresult = 1; /* PASS */
475e1051a39Sopenharmony_ci
476e1051a39Sopenharmony_ciend:
477e1051a39Sopenharmony_ci    if (fp != NULL)
478e1051a39Sopenharmony_ci        fclose(fp);
479e1051a39Sopenharmony_ci
480e1051a39Sopenharmony_ci    EC_GROUP_free(g1);
481e1051a39Sopenharmony_ci    EC_GROUP_free(g2);
482e1051a39Sopenharmony_ci
483e1051a39Sopenharmony_ci    return testresult;
484e1051a39Sopenharmony_ci}
485e1051a39Sopenharmony_ci
486e1051a39Sopenharmony_ciint setup_tests(void)
487e1051a39Sopenharmony_ci{
488e1051a39Sopenharmony_ci    crv_len = EC_get_builtin_curves(NULL, 0);
489e1051a39Sopenharmony_ci    if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
490e1051a39Sopenharmony_ci        || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
491e1051a39Sopenharmony_ci        return 0;
492e1051a39Sopenharmony_ci
493e1051a39Sopenharmony_ci    ADD_TEST(field_tests_ecp_simple);
494e1051a39Sopenharmony_ci    ADD_TEST(field_tests_ecp_mont);
495e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M
496e1051a39Sopenharmony_ci    ADD_TEST(ec2m_field_sanity);
497e1051a39Sopenharmony_ci    ADD_TEST(field_tests_ec2_simple);
498e1051a39Sopenharmony_ci#endif
499e1051a39Sopenharmony_ci    ADD_ALL_TESTS(field_tests_default, crv_len);
500e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
501e1051a39Sopenharmony_ci    ADD_TEST(underflow_test);
502e1051a39Sopenharmony_ci#endif
503e1051a39Sopenharmony_ci    ADD_TEST(set_private_key);
504e1051a39Sopenharmony_ci    ADD_TEST(decoded_flag_test);
505e1051a39Sopenharmony_ci    ADD_ALL_TESTS(ecpkparams_i2d2i_test, crv_len);
506e1051a39Sopenharmony_ci
507e1051a39Sopenharmony_ci    return 1;
508e1051a39Sopenharmony_ci}
509e1051a39Sopenharmony_ci
510e1051a39Sopenharmony_civoid cleanup_tests(void)
511e1051a39Sopenharmony_ci{
512e1051a39Sopenharmony_ci    OPENSSL_free(curves);
513e1051a39Sopenharmony_ci}
514