Blame SOURCES/ectest.c

9b88be
/*
9b88be
 * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
9b88be
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
9b88be
 *
9b88be
 * Licensed under the OpenSSL license (the "License").  You may not use
9b88be
 * this file except in compliance with the License.  You can obtain a copy
9b88be
 * in the file LICENSE in the source distribution or at
9b88be
 * https://www.openssl.org/source/license.html
9b88be
 */
9b88be
9b88be
#include "internal/nelem.h"
9b88be
#include "testutil.h"
9b88be
9b88be
#ifndef OPENSSL_NO_EC
9b88be
# include <openssl/ec.h>
9b88be
# ifndef OPENSSL_NO_ENGINE
9b88be
#  include <openssl/engine.h>
9b88be
# endif
9b88be
# include <openssl/err.h>
9b88be
# include <openssl/obj_mac.h>
9b88be
# include <openssl/objects.h>
9b88be
# include <openssl/rand.h>
9b88be
# include <openssl/bn.h>
9b88be
# include <openssl/opensslconf.h>
9b88be
9b88be
static size_t crv_len = 0;
9b88be
static EC_builtin_curve *curves = NULL;
9b88be
9b88be
/* test multiplication with group order, long and negative scalars */
9b88be
static int group_order_tests(EC_GROUP *group)
9b88be
{
9b88be
    BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
9b88be
    EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
9b88be
    const EC_POINT *G = NULL;
9b88be
    BN_CTX *ctx = NULL;
9b88be
    int i = 0, r = 0;
9b88be
9b88be
    if (!TEST_ptr(n1 = BN_new())
9b88be
        || !TEST_ptr(n2 = BN_new())
9b88be
        || !TEST_ptr(order = BN_new())
9b88be
        || !TEST_ptr(ctx = BN_CTX_new())
9b88be
        || !TEST_ptr(G = EC_GROUP_get0_generator(group))
9b88be
        || !TEST_ptr(P = EC_POINT_new(group))
9b88be
        || !TEST_ptr(Q = EC_POINT_new(group))
9b88be
        || !TEST_ptr(R = EC_POINT_new(group))
9b88be
        || !TEST_ptr(S = EC_POINT_new(group)))
9b88be
        goto err;
9b88be
9b88be
    if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
9b88be
        || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
9b88be
        || !TEST_true(EC_POINT_is_at_infinity(group, Q))
9b88be
        || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
9b88be
        || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
9b88be
        || !TEST_true(EC_POINT_is_at_infinity(group, Q))
9b88be
        || !TEST_true(EC_POINT_copy(P, G))
9b88be
        || !TEST_true(BN_one(n1))
9b88be
        || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
9b88be
        || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
9b88be
        || !TEST_true(BN_sub(n1, order, n1))
9b88be
        || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
9b88be
        || !TEST_true(EC_POINT_invert(group, Q, ctx))
9b88be
        || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
9b88be
        goto err;
9b88be
9b88be
    for (i = 1; i <= 2; i++) {
9b88be
        const BIGNUM *scalars[6];
9b88be
        const EC_POINT *points[6];
9b88be
9b88be
        if (!TEST_true(BN_set_word(n1, i))
9b88be
            /*
9b88be
             * If i == 1, P will be the predefined generator for which
9b88be
             * EC_GROUP_precompute_mult has set up precomputation.
9b88be
             */
9b88be
            || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
9b88be
            || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
9b88be
            || !TEST_true(BN_one(n1))
9b88be
            /* n1 = 1 - order */
9b88be
            || !TEST_true(BN_sub(n1, n1, order))
9b88be
            || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
9b88be
            || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
9b88be
9b88be
            /* n2 = 1 + order */
9b88be
            || !TEST_true(BN_add(n2, order, BN_value_one()))
9b88be
            || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
9b88be
            || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
9b88be
9b88be
            /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
9b88be
            || !TEST_true(BN_mul(n2, n1, n2, ctx))
9b88be
            || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
9b88be
            || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
9b88be
            goto err;
9b88be
9b88be
        /* n2 = order^2 - 1 */
9b88be
        BN_set_negative(n2, 0);
9b88be
        if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
9b88be
            /* Add P to verify the result. */
9b88be
            || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
9b88be
            || !TEST_true(EC_POINT_is_at_infinity(group, Q))
9b88be
9b88be
            /* Exercise EC_POINTs_mul, including corner cases. */
9b88be
            || !TEST_false(EC_POINT_is_at_infinity(group, P)))
9b88be
            goto err;
9b88be
9b88be
        scalars[0] = scalars[1] = BN_value_one();
9b88be
        points[0]  = points[1]  = P;
9b88be
9b88be
        if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
9b88be
            || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
9b88be
            || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
9b88be
            goto err;
9b88be
9b88be
        scalars[0] = n1;
9b88be
        points[0] = Q;          /* => infinity */
9b88be
        scalars[1] = n2;
9b88be
        points[1] = P;          /* => -P */
9b88be
        scalars[2] = n1;
9b88be
        points[2] = Q;          /* => infinity */
9b88be
        scalars[3] = n2;
9b88be
        points[3] = Q;          /* => infinity */
9b88be
        scalars[4] = n1;
9b88be
        points[4] = P;          /* => P */
9b88be
        scalars[5] = n2;
9b88be
        points[5] = Q;          /* => infinity */
9b88be
        if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
9b88be
            || !TEST_true(EC_POINT_is_at_infinity(group, P)))
9b88be
            goto err;
9b88be
    }
9b88be
9b88be
    r = 1;
9b88be
err:
9b88be
    if (r == 0 && i != 0)
9b88be
        TEST_info(i == 1 ? "allowing precomputation" :
9b88be
                           "without precomputation");
9b88be
    EC_POINT_free(P);
9b88be
    EC_POINT_free(Q);
9b88be
    EC_POINT_free(R);
9b88be
    EC_POINT_free(S);
9b88be
    BN_free(n1);
9b88be
    BN_free(n2);
9b88be
    BN_free(order);
9b88be
    BN_CTX_free(ctx);
9b88be
    return r;
9b88be
}
9b88be
9b88be
static int prime_field_tests(void)
9b88be
{
9b88be
    BN_CTX *ctx = NULL;
9b88be
    BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
9b88be
    EC_GROUP *group = NULL, *tmp = NULL;
9b88be
    EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
9b88be
             *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
9b88be
    EC_POINT *P = NULL, *Q = NULL, *R = NULL;
9b88be
    BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
9b88be
    const EC_POINT *points[4];
9b88be
    const BIGNUM *scalars[4];
9b88be
    unsigned char buf[100];
9b88be
    size_t len, r = 0;
9b88be
    int k;
9b88be
9b88be
    if (!TEST_ptr(ctx = BN_CTX_new())
9b88be
        || !TEST_ptr(p = BN_new())
9b88be
        || !TEST_ptr(a = BN_new())
9b88be
        || !TEST_ptr(b = BN_new())
9b88be
        /*
9b88be
         * applications should use EC_GROUP_new_curve_GFp so
9b88be
         * that the library gets to choose the EC_METHOD
9b88be
         */
9b88be
        || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
9b88be
        || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
9b88be
        || !TEST_true(EC_GROUP_copy(tmp, group)))
9b88be
        goto err;
9b88be
    EC_GROUP_free(group);
9b88be
    group = tmp;
9b88be
    tmp = NULL;
9b88be
9b88be
    buf[0] = 0;
9b88be
    if (!TEST_ptr(P = EC_POINT_new(group))
9b88be
        || !TEST_ptr(Q = EC_POINT_new(group))
9b88be
        || !TEST_ptr(R = EC_POINT_new(group))
9b88be
        || !TEST_ptr(x = BN_new())
9b88be
        || !TEST_ptr(y = BN_new())
9b88be
        || !TEST_ptr(z = BN_new())
9b88be
        || !TEST_ptr(yplusone = BN_new()))
9b88be
        goto err;
9b88be
9b88be
    /* Curve P-224 (FIPS PUB 186-2, App. 6) */
9b88be
9b88be
    if (!TEST_true(BN_hex2bn(&p,         "FFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFF000000000000000000000001"))
9b88be
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9b88be
        || !TEST_true(BN_hex2bn(&a,         "FFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
9b88be
        || !TEST_true(BN_hex2bn(&b,         "B4050A850C04B3ABF5413256"
9b88be
                                    "5044B0B7D7BFD8BA270B39432355FFB4"))
9b88be
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9b88be
        || !TEST_true(BN_hex2bn(&x,         "B70E0CBD6BB4BF7F321390B9"
9b88be
                                    "4A03C1D356C21122343280D6115C1D21"))
9b88be
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
9b88be
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9b88be
        || !TEST_true(BN_hex2bn(&z,         "FFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
9b88be
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
9b88be
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9b88be
        goto err;
9b88be
9b88be
    TEST_info("NIST curve P-224 -- Generator");
9b88be
    test_output_bignum("x", x);
9b88be
    test_output_bignum("y", y);
9b88be
    /* G_y value taken from the standard: */
9b88be
    if (!TEST_true(BN_hex2bn(&z,         "BD376388B5F723FB4C22DFE6"
9b88be
                                 "CD4375A05A07476444D5819985007E34"))
9b88be
        || !TEST_BN_eq(y, z)
9b88be
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
9b88be
    /*
9b88be
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
9b88be
     * and therefore setting the coordinates should fail.
9b88be
     */
9b88be
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
9b88be
                                                       ctx))
9b88be
        || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
9b88be
        || !group_order_tests(group)
9b88be
        || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
9b88be
        || !TEST_true(EC_GROUP_copy(P_224, group))
9b88be
9b88be
    /* Curve P-256 (FIPS PUB 186-2, App. 6) */
9b88be
9b88be
        || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
9b88be
                                    "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
9b88be
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9b88be
        || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
9b88be
                                    "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
9b88be
        || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
9b88be
                                    "651D06B0CC53B0F63BCE3C3E27D2604B"))
9b88be
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9b88be
9b88be
        || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
9b88be
                                    "77037D812DEB33A0F4A13945D898C296"))
9b88be
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
9b88be
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9b88be
        || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
9b88be
                                    "BCE6FAADA7179E84F3B9CAC2FC632551"))
9b88be
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
9b88be
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9b88be
        goto err;
9b88be
9b88be
    TEST_info("NIST curve P-256 -- Generator");
9b88be
    test_output_bignum("x", x);
9b88be
    test_output_bignum("y", y);
9b88be
    /* G_y value taken from the standard: */
9b88be
    if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
9b88be
                                 "2BCE33576B315ECECBB6406837BF51F5"))
9b88be
        || !TEST_BN_eq(y, z)
9b88be
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
9b88be
    /*
9b88be
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
9b88be
     * and therefore setting the coordinates should fail.
9b88be
     */
9b88be
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
9b88be
                                                       ctx))
9b88be
        || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
9b88be
        || !group_order_tests(group)
9b88be
        || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
9b88be
        || !TEST_true(EC_GROUP_copy(P_256, group))
9b88be
9b88be
    /* Curve P-384 (FIPS PUB 186-2, App. 6) */
9b88be
9b88be
        || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
9b88be
                                    "FFFFFFFF0000000000000000FFFFFFFF"))
9b88be
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9b88be
        || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
9b88be
                                    "FFFFFFFF0000000000000000FFFFFFFC"))
9b88be
        || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
9b88be
                                    "181D9C6EFE8141120314088F5013875A"
9b88be
                                    "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
9b88be
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9b88be
9b88be
        || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
9b88be
                                    "6E1D3B628BA79B9859F741E082542A38"
9b88be
                                    "5502F25DBF55296C3A545E3872760AB7"))
9b88be
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
9b88be
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9b88be
        || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
9b88be
                                    "581A0DB248B0A77AECEC196ACCC52973"))
9b88be
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
9b88be
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9b88be
        goto err;
9b88be
9b88be
    TEST_info("NIST curve P-384 -- Generator");
9b88be
    test_output_bignum("x", x);
9b88be
    test_output_bignum("y", y);
9b88be
    /* G_y value taken from the standard: */
9b88be
    if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
9b88be
                                 "F8F41DBD289A147CE9DA3113B5F0B8C0"
9b88be
                                 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
9b88be
        || !TEST_BN_eq(y, z)
9b88be
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
9b88be
    /*
9b88be
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
9b88be
     * and therefore setting the coordinates should fail.
9b88be
     */
9b88be
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
9b88be
                                                       ctx))
9b88be
        || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
9b88be
        || !group_order_tests(group)
9b88be
        || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
9b88be
        || !TEST_true(EC_GROUP_copy(P_384, group))
9b88be
9b88be
    /* Curve P-521 (FIPS PUB 186-2, App. 6) */
9b88be
        || !TEST_true(BN_hex2bn(&p,                              "1FF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
9b88be
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9b88be
        || !TEST_true(BN_hex2bn(&a,                              "1FF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
9b88be
        || !TEST_true(BN_hex2bn(&b,                              "051"
9b88be
                                    "953EB9618E1C9A1F929A21A0B68540EE"
9b88be
                                    "A2DA725B99B315F3B8B489918EF109E1"
9b88be
                                    "56193951EC7E937B1652C0BD3BB1BF07"
9b88be
                                    "3573DF883D2C34F1EF451FD46B503F00"))
9b88be
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9b88be
        || !TEST_true(BN_hex2bn(&x,                               "C6"
9b88be
                                    "858E06B70404E9CD9E3ECB662395B442"
9b88be
                                    "9C648139053FB521F828AF606B4D3DBA"
9b88be
                                    "A14B5E77EFE75928FE1DC127A2FFA8DE"
9b88be
                                    "3348B3C1856A429BF97E7E31C2E5BD66"))
9b88be
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
9b88be
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9b88be
        || !TEST_true(BN_hex2bn(&z,                              "1FF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9b88be
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
9b88be
                                    "51868783BF2F966B7FCC0148F709A5D0"
9b88be
                                    "3BB5C9B8899C47AEBB6FB71E91386409"))
9b88be
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
9b88be
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9b88be
        goto err;
9b88be
9b88be
    TEST_info("NIST curve P-521 -- Generator");
9b88be
    test_output_bignum("x", x);
9b88be
    test_output_bignum("y", y);
9b88be
    /* G_y value taken from the standard: */
9b88be
    if (!TEST_true(BN_hex2bn(&z,                              "118"
9b88be
                                 "39296A789A3BC0045C8A5FB42C7D1BD9"
9b88be
                                 "98F54449579B446817AFBD17273E662C"
9b88be
                                 "97EE72995EF42640C550B9013FAD0761"
9b88be
                                 "353C7086A272C24088BE94769FD16650"))
9b88be
        || !TEST_BN_eq(y, z)
9b88be
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
9b88be
    /*
9b88be
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
9b88be
     * and therefore setting the coordinates should fail.
9b88be
     */
9b88be
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
9b88be
                                                       ctx))
9b88be
        || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
9b88be
        || !group_order_tests(group)
9b88be
        || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
9b88be
        || !TEST_true(EC_GROUP_copy(P_521, group))
9b88be
9b88be
    /* more tests using the last curve */
9b88be
9b88be
    /* Restore the point that got mangled in the (x, y + 1) test. */
9b88be
        || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
9b88be
        || !TEST_true(EC_POINT_copy(Q, P))
9b88be
        || !TEST_false(EC_POINT_is_at_infinity(group, Q))
9b88be
        || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
9b88be
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9b88be
        || !TEST_true(EC_POINT_invert(group, Q, ctx))       /* P = -2Q */
9b88be
        || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
9b88be
        || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
9b88be
        || !TEST_true(EC_POINT_is_at_infinity(group, R))    /* R = P + 2Q */
9b88be
        || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
9b88be
        goto err;
9b88be
    points[0] = Q;
9b88be
    points[1] = Q;
9b88be
    points[2] = Q;
9b88be
    points[3] = Q;
9b88be
9b88be
    if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
9b88be
        || !TEST_true(BN_add(y, z, BN_value_one()))
9b88be
        || !TEST_BN_even(y)
9b88be
        || !TEST_true(BN_rshift1(y, y)))
9b88be
        goto err;
9b88be
    scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
9b88be
    scalars[1] = y;
9b88be
9b88be
    TEST_note("combined multiplication ...");
9b88be
9b88be
    /* z is still the group order */
9b88be
    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
9b88be
        || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
9b88be
        || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
9b88be
        || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
9b88be
        || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
9b88be
        || !TEST_true(BN_add(z, z, y)))
9b88be
        goto err;
9b88be
    BN_set_negative(z, 1);
9b88be
    scalars[0] = y;
9b88be
    scalars[1] = z;         /* z = -(order + y) */
9b88be
9b88be
    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
9b88be
        || !TEST_true(EC_POINT_is_at_infinity(group, P))
9b88be
        || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
9b88be
        || !TEST_true(BN_add(z, x, y)))
9b88be
        goto err;
9b88be
    BN_set_negative(z, 1);
9b88be
    scalars[0] = x;
9b88be
    scalars[1] = y;
9b88be
    scalars[2] = z;         /* z = -(x+y) */
9b88be
9b88be
    if (!TEST_ptr(scalar3 = BN_new()))
9b88be
        goto err;
9b88be
    BN_zero(scalar3);
9b88be
    scalars[3] = scalar3;
9b88be
9b88be
    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
9b88be
        || !TEST_true(EC_POINT_is_at_infinity(group, P)))
9b88be
        goto err;
9b88be
9b88be
    TEST_note(" ok\n");
9b88be
9b88be
9b88be
    r = 1;
9b88be
err:
9b88be
    BN_CTX_free(ctx);
9b88be
    BN_free(p);
9b88be
    BN_free(a);
9b88be
    BN_free(b);
9b88be
    EC_GROUP_free(group);
9b88be
    EC_GROUP_free(tmp);
9b88be
    EC_POINT_free(P);
9b88be
    EC_POINT_free(Q);
9b88be
    EC_POINT_free(R);
9b88be
    BN_free(x);
9b88be
    BN_free(y);
9b88be
    BN_free(z);
9b88be
    BN_free(yplusone);
9b88be
    BN_free(scalar3);
9b88be
9b88be
    EC_GROUP_free(P_224);
9b88be
    EC_GROUP_free(P_256);
9b88be
    EC_GROUP_free(P_384);
9b88be
    EC_GROUP_free(P_521);
9b88be
    return r;
9b88be
}
9b88be
9b88be
static int internal_curve_test(int n)
9b88be
{
9b88be
    EC_GROUP *group = NULL;
9b88be
    int nid = curves[n].nid;
9b88be
9b88be
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
9b88be
        TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
9b88be
                  OBJ_nid2sn(nid));
9b88be
        return 0;
9b88be
    }
9b88be
    if (!TEST_true(EC_GROUP_check(group, NULL))) {
9b88be
        TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
9b88be
        EC_GROUP_free(group);
9b88be
        return 0;
9b88be
    }
9b88be
    EC_GROUP_free(group);
9b88be
    return 1;
9b88be
}
9b88be
9b88be
static int internal_curve_test_method(int n)
9b88be
{
9b88be
    int r, nid = curves[n].nid;
9b88be
    EC_GROUP *group;
9b88be
9b88be
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
9b88be
        TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
9b88be
        return 0;
9b88be
    }
9b88be
    r = group_order_tests(group);
9b88be
    EC_GROUP_free(group);
9b88be
    return r;
9b88be
}
9b88be
9b88be
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
9b88be
/*
9b88be
 * nistp_test_params contains magic numbers for testing our optimized
9b88be
 * implementations of several NIST curves with characteristic > 3.
9b88be
 */
9b88be
struct nistp_test_params {
9b88be
    const EC_METHOD *(*meth) (void);
9b88be
    int degree;
9b88be
    /*
9b88be
     * Qx, Qy and D are taken from
9b88be
     * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
9b88be
     * Otherwise, values are standard curve parameters from FIPS 180-3
9b88be
     */
9b88be
    const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
9b88be
};
9b88be
9b88be
static const struct nistp_test_params nistp_tests_params[] = {
9b88be
    {
9b88be
     /* P-224 */
9b88be
     EC_GFp_nistp224_method,
9b88be
     224,
9b88be
     /* p */
9b88be
     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
9b88be
     /* a */
9b88be
     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
9b88be
     /* b */
9b88be
     "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
9b88be
     /* Qx */
9b88be
     "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
9b88be
     /* Qy */
9b88be
     "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
9b88be
     /* Gx */
9b88be
     "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
9b88be
     /* Gy */
9b88be
     "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
9b88be
     /* order */
9b88be
     "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
9b88be
     /* d */
9b88be
     "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
9b88be
     },
9b88be
    {
9b88be
     /* P-256 */
9b88be
     EC_GFp_nistp256_method,
9b88be
     256,
9b88be
     /* p */
9b88be
     "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
9b88be
     /* a */
9b88be
     "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
9b88be
     /* b */
9b88be
     "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
9b88be
     /* Qx */
9b88be
     "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
9b88be
     /* Qy */
9b88be
     "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
9b88be
     /* Gx */
9b88be
     "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
9b88be
     /* Gy */
9b88be
     "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
9b88be
     /* order */
9b88be
     "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
9b88be
     /* d */
9b88be
     "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
9b88be
     },
9b88be
    {
9b88be
     /* P-521 */
9b88be
     EC_GFp_nistp521_method,
9b88be
     521,
9b88be
     /* p */
9b88be
                                                                  "1ff"
9b88be
     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
9b88be
     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
9b88be
     /* a */
9b88be
                                                                  "1ff"
9b88be
     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
9b88be
     "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
9b88be
     /* b */
9b88be
                                                                  "051"
9b88be
     "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
9b88be
     "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
9b88be
     /* Qx */
9b88be
                                                                 "0098"
9b88be
     "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
9b88be
     "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
9b88be
     /* Qy */
9b88be
                                                                 "0164"
9b88be
     "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
9b88be
     "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
9b88be
     /* Gx */
9b88be
                                                                   "c6"
9b88be
     "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
9b88be
     "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
9b88be
     /* Gy */
9b88be
                                                                  "118"
9b88be
     "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
9b88be
     "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
9b88be
     /* order */
9b88be
                                                                  "1ff"
9b88be
     "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
9b88be
     "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
9b88be
     /* d */
9b88be
                                                                 "0100"
9b88be
     "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
9b88be
     "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
9b88be
     },
9b88be
};
9b88be
9b88be
static int nistp_single_test(int idx)
9b88be
{
9b88be
    const struct nistp_test_params *test = nistp_tests_params + idx;
9b88be
    BN_CTX *ctx = NULL;
9b88be
    BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
9b88be
    BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
9b88be
    EC_GROUP *NISTP = NULL;
9b88be
    EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
9b88be
    int r = 0;
9b88be
9b88be
    TEST_note("NIST curve P-%d (optimised implementation):",
9b88be
              test->degree);
9b88be
    if (!TEST_ptr(ctx = BN_CTX_new())
9b88be
        || !TEST_ptr(p = BN_new())
9b88be
        || !TEST_ptr(a = BN_new())
9b88be
        || !TEST_ptr(b = BN_new())
9b88be
        || !TEST_ptr(x = BN_new())
9b88be
        || !TEST_ptr(y = BN_new())
9b88be
        || !TEST_ptr(m = BN_new())
9b88be
        || !TEST_ptr(n = BN_new())
9b88be
        || !TEST_ptr(order = BN_new())
9b88be
        || !TEST_ptr(yplusone = BN_new())
9b88be
9b88be
        || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
9b88be
        || !TEST_true(BN_hex2bn(&p, test->p))
9b88be
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9b88be
        || !TEST_true(BN_hex2bn(&a, test->a))
9b88be
        || !TEST_true(BN_hex2bn(&b, test->b))
9b88be
        || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
9b88be
        || !TEST_ptr(G = EC_POINT_new(NISTP))
9b88be
        || !TEST_ptr(P = EC_POINT_new(NISTP))
9b88be
        || !TEST_ptr(Q = EC_POINT_new(NISTP))
9b88be
        || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
9b88be
        || !TEST_true(BN_hex2bn(&x, test->Qx))
9b88be
        || !TEST_true(BN_hex2bn(&y, test->Qy))
9b88be
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
9b88be
    /*
9b88be
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
9b88be
     * and therefore setting the coordinates should fail.
9b88be
     */
9b88be
        || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
9b88be
                                                       yplusone, ctx))
9b88be
        || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
9b88be
                                                      ctx))
9b88be
        || !TEST_true(BN_hex2bn(&x, test->Gx))
9b88be
        || !TEST_true(BN_hex2bn(&y, test->Gy))
9b88be
        || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
9b88be
        || !TEST_true(BN_hex2bn(&order, test->order))
9b88be
        || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
9b88be
        || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
9b88be
        goto err;
9b88be
9b88be
    TEST_note("NIST test vectors ... ");
9b88be
    if (!TEST_true(BN_hex2bn(&n, test->d)))
9b88be
        goto err;
9b88be
    /* fixed point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9b88be
        goto err;
9b88be
    /* random point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
9b88be
9b88be
        /* set generator to P = 2*G, where G is the standard generator */
9b88be
        || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
9b88be
        || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
9b88be
        /* set the scalar to m=n/2, where n is the NIST test scalar */
9b88be
        || !TEST_true(BN_rshift(m, n, 1)))
9b88be
        goto err;
9b88be
9b88be
    /* test the non-standard generator */
9b88be
    /* fixed point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9b88be
        goto err;
9b88be
    /* random point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
9b88be
9b88be
    /*
9b88be
     * We have not performed precomputation so have_precompute mult should be
9b88be
     * false
9b88be
     */
9b88be
        || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
9b88be
9b88be
    /* now repeat all tests with precomputation */
9b88be
        || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
9b88be
        || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
9b88be
        goto err;
9b88be
9b88be
    /* fixed point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9b88be
        goto err;
9b88be
    /* random point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
9b88be
9b88be
    /* reset generator */
9b88be
        || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
9b88be
        goto err;
9b88be
    /* fixed point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9b88be
        goto err;
9b88be
    /* random point multiplication */
9b88be
    EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
9b88be
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9b88be
        goto err;
9b88be
9b88be
    /* regression test for felem_neg bug */
9b88be
    if (!TEST_true(BN_set_word(m, 32))
9b88be
        || !TEST_true(BN_set_word(n, 31))
9b88be
        || !TEST_true(EC_POINT_copy(P, G))
9b88be
        || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
9b88be
        || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
9b88be
        || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
9b88be
      goto err;
9b88be
9b88be
    r = group_order_tests(NISTP);
9b88be
err:
9b88be
    EC_GROUP_free(NISTP);
9b88be
    EC_POINT_free(G);
9b88be
    EC_POINT_free(P);
9b88be
    EC_POINT_free(Q);
9b88be
    EC_POINT_free(Q_CHECK);
9b88be
    BN_free(n);
9b88be
    BN_free(m);
9b88be
    BN_free(p);
9b88be
    BN_free(a);
9b88be
    BN_free(b);
9b88be
    BN_free(x);
9b88be
    BN_free(y);
9b88be
    BN_free(order);
9b88be
    BN_free(yplusone);
9b88be
    BN_CTX_free(ctx);
9b88be
    return r;
9b88be
}
9b88be
9b88be
/*
9b88be
 * Tests a point known to cause an incorrect underflow in an old version of
9b88be
 * ecp_nist521.c
9b88be
 */
9b88be
static int underflow_test(void)
9b88be
{
9b88be
    BN_CTX *ctx = NULL;
9b88be
    EC_GROUP *grp = NULL;
9b88be
    EC_POINT *P = NULL, *Q = NULL, *R = NULL;
9b88be
    BIGNUM *x1 = NULL, *y1 = NULL, *z1 = NULL, *x2 = NULL, *y2 = NULL;
9b88be
    BIGNUM *k = NULL;
9b88be
    int testresult = 0;
9b88be
    const char *x1str =
9b88be
        "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4"
9b88be
        "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004";
9b88be
    const char *p521m1 =
9b88be
        "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
9b88be
        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
9b88be
9b88be
    ctx = BN_CTX_new();
9b88be
    if (!TEST_ptr(ctx))
9b88be
        return 0;
9b88be
9b88be
    BN_CTX_start(ctx);
9b88be
    x1 = BN_CTX_get(ctx);
9b88be
    y1 = BN_CTX_get(ctx);
9b88be
    z1 = BN_CTX_get(ctx);
9b88be
    x2 = BN_CTX_get(ctx);
9b88be
    y2 = BN_CTX_get(ctx);
9b88be
    k = BN_CTX_get(ctx);
9b88be
    if (!TEST_ptr(k))
9b88be
        goto err;
9b88be
9b88be
    grp = EC_GROUP_new_by_curve_name(NID_secp521r1);
9b88be
    P = EC_POINT_new(grp);
9b88be
    Q = EC_POINT_new(grp);
9b88be
    R = EC_POINT_new(grp);
9b88be
    if (!TEST_ptr(grp) || !TEST_ptr(P) || !TEST_ptr(Q) || !TEST_ptr(R))
9b88be
        goto err;
9b88be
9b88be
    if (!TEST_int_gt(BN_hex2bn(&x1, x1str), 0)
9b88be
            || !TEST_int_gt(BN_hex2bn(&y1, p521m1), 0)
9b88be
            || !TEST_int_gt(BN_hex2bn(&z1, p521m1), 0)
9b88be
            || !TEST_int_gt(BN_hex2bn(&k, "02"), 0)
9b88be
            || !TEST_true(EC_POINT_set_Jprojective_coordinates_GFp(grp, P, x1,
9b88be
                                                                   y1, z1, ctx))
9b88be
            || !TEST_true(EC_POINT_mul(grp, Q, NULL, P, k, ctx))
9b88be
            || !TEST_true(EC_POINT_get_affine_coordinates(grp, Q, x1, y1, ctx))
9b88be
            || !TEST_true(EC_POINT_dbl(grp, R, P, ctx))
9b88be
            || !TEST_true(EC_POINT_get_affine_coordinates(grp, R, x2, y2, ctx)))
9b88be
        goto err;
9b88be
9b88be
    if (!TEST_int_eq(BN_cmp(x1, x2), 0)
9b88be
            || !TEST_int_eq(BN_cmp(y1, y2), 0))
9b88be
        goto err;
9b88be
9b88be
    testresult = 1;
9b88be
9b88be
 err:
9b88be
    BN_CTX_end(ctx);
9b88be
    EC_POINT_free(P);
9b88be
    EC_POINT_free(Q);
9b88be
    EC_POINT_free(R);
9b88be
    EC_GROUP_free(grp);
9b88be
    BN_CTX_free(ctx);
9b88be
9b88be
    return testresult;
9b88be
}
9b88be
# endif
9b88be
9b88be
static const unsigned char p521_named[] = {
9b88be
    0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
9b88be
};
9b88be
9b88be
static const unsigned char p521_explicit[] = {
9b88be
    0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
9b88be
    0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
9b88be
    0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
9b88be
    0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
9b88be
    0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
9b88be
    0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
9b88be
    0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
9b88be
    0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
9b88be
    0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
9b88be
    0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
9b88be
    0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
9b88be
    0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
9b88be
    0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
9b88be
    0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
9b88be
    0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
9b88be
    0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
9b88be
    0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
9b88be
    0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
9b88be
    0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
9b88be
    0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
9b88be
    0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9b88be
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
9b88be
    0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
9b88be
    0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
9b88be
    0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
9b88be
};
9b88be
9b88be
/*
9b88be
 * Sometime we cannot compare nids for equality, as the built-in curve table
9b88be
 * includes aliases with different names for the same curve.
9b88be
 *
9b88be
 * This function returns TRUE (1) if the checked nids are identical, or if they
9b88be
 * alias to the same curve. FALSE (0) otherwise.
9b88be
 */
9b88be
static ossl_inline
9b88be
int are_ec_nids_compatible(int n1d, int n2d)
9b88be
{
9b88be
    int ret = 0;
9b88be
    switch (n1d) {
9b88be
# ifndef OPENSSL_NO_EC2M
9b88be
        case NID_sect113r1:
9b88be
        case NID_wap_wsg_idm_ecid_wtls4:
9b88be
            ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
9b88be
            break;
9b88be
        case NID_sect163k1:
9b88be
        case NID_wap_wsg_idm_ecid_wtls3:
9b88be
            ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
9b88be
            break;
9b88be
        case NID_sect233k1:
9b88be
        case NID_wap_wsg_idm_ecid_wtls10:
9b88be
            ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
9b88be
            break;
9b88be
        case NID_sect233r1:
9b88be
        case NID_wap_wsg_idm_ecid_wtls11:
9b88be
            ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
9b88be
            break;
9b88be
        case NID_X9_62_c2pnb163v1:
9b88be
        case NID_wap_wsg_idm_ecid_wtls5:
9b88be
            ret = (n2d == NID_X9_62_c2pnb163v1
9b88be
                   || n2d == NID_wap_wsg_idm_ecid_wtls5);
9b88be
            break;
9b88be
# endif /* OPENSSL_NO_EC2M */
9b88be
        case NID_secp112r1:
9b88be
        case NID_wap_wsg_idm_ecid_wtls6:
9b88be
            ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
9b88be
            break;
9b88be
        case NID_secp160r2:
9b88be
        case NID_wap_wsg_idm_ecid_wtls7:
9b88be
            ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
9b88be
            break;
9b88be
# ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
9b88be
        case NID_secp224r1:
9b88be
        case NID_wap_wsg_idm_ecid_wtls12:
9b88be
            ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
9b88be
            break;
9b88be
# else
9b88be
        /*
9b88be
         * For SEC P-224 we want to ensure that the SECP nid is returned, as
9b88be
         * that is associated with a specialized method.
9b88be
         */
9b88be
        case NID_wap_wsg_idm_ecid_wtls12:
9b88be
            ret = (n2d == NID_secp224r1);
9b88be
            break;
9b88be
# endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
9b88be
9b88be
        default:
9b88be
            ret = (n1d == n2d);
9b88be
    }
9b88be
    return ret;
9b88be
}
9b88be
9b88be
/*
9b88be
 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
9b88be
 * EC_GROUP for built-in curves.
9b88be
 *
9b88be
 * Note that it is possible to retrieve an alternative alias that does not match
9b88be
 * the original nid.
9b88be
 *
9b88be
 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
9b88be
 */
9b88be
static int check_named_curve_from_ecparameters(int id)
9b88be
{
9b88be
    int ret = 0, nid, tnid;
9b88be
    EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
9b88be
    const EC_POINT *group_gen = NULL;
9b88be
    EC_POINT *other_gen = NULL;
9b88be
    BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
9b88be
    BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
9b88be
    const BIGNUM *group_order = NULL;
9b88be
    BIGNUM *other_order = NULL;
9b88be
    BN_CTX *bn_ctx = NULL;
9b88be
    static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
9b88be
    static size_t invalid_seed_len = sizeof(invalid_seed);
9b88be
    ECPARAMETERS *params = NULL, *other_params = NULL;
9b88be
    EC_GROUP *g_ary[8] = {NULL};
9b88be
    EC_GROUP **g_next = &g_ary[0];
9b88be
    ECPARAMETERS *p_ary[8] = {NULL};
9b88be
    ECPARAMETERS **p_next = &p_ary[0];
9b88be
9b88be
    /* Do some setup */
9b88be
    nid = curves[id].nid;
9b88be
    TEST_note("Curve %s", OBJ_nid2sn(nid));
9b88be
    if (!TEST_ptr(bn_ctx = BN_CTX_new()))
9b88be
        return ret;
9b88be
    BN_CTX_start(bn_ctx);
9b88be
9b88be
    if (/* Allocations */
9b88be
        !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
9b88be
        || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
9b88be
        || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
9b88be
        || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
9b88be
        || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
9b88be
        /* Generate reference group and params */
9b88be
        || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
9b88be
        || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
9b88be
        || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
9b88be
        || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
9b88be
        || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
9b88be
        /* compute `other_*` values */
9b88be
        || !TEST_ptr(tmpg = EC_GROUP_dup(group))
9b88be
        || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
9b88be
        || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
9b88be
        || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
9b88be
                      other_gen_x, other_gen_y, bn_ctx))
9b88be
        || !TEST_true(BN_copy(other_order, group_order))
9b88be
        || !TEST_true(BN_add_word(other_order, 1))
9b88be
        || !TEST_true(BN_copy(other_cofactor, group_cofactor))
9b88be
        || !TEST_true(BN_add_word(other_cofactor, 1)))
9b88be
        goto err;
9b88be
9b88be
    EC_POINT_free(other_gen);
9b88be
    other_gen = NULL;
9b88be
9b88be
    if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
9b88be
        || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
9b88be
                                                      other_gen_x, other_gen_y,
9b88be
                                                      bn_ctx)))
9b88be
        goto err;
9b88be
9b88be
    /*
9b88be
     * ###########################
9b88be
     * # Actual tests start here #
9b88be
     * ###########################
9b88be
     */
9b88be
9b88be
    /*
9b88be
     * Creating a group from built-in explicit parameters returns a
9b88be
     * "named" EC_GROUP
9b88be
     */
9b88be
    if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
9b88be
        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
9b88be
        goto err;
9b88be
    /*
9b88be
     * We cannot always guarantee the names match, as the built-in table
9b88be
     * contains aliases for the same curve with different names.
9b88be
     */
9b88be
    if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
9b88be
        TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
9b88be
        goto err;
9b88be
    }
9b88be
    /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
9b88be
    if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
9b88be
        goto err;
9b88be
9b88be
    /*
9b88be
     * An invalid seed in the parameters should be ignored: expect a "named"
9b88be
     * group.
9b88be
     */
9b88be
    if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
9b88be
                     invalid_seed_len)
9b88be
            || !TEST_ptr(other_params = *p_next++ =
9b88be
                         EC_GROUP_get_ecparameters(tmpg, NULL))
9b88be
            || !TEST_ptr(tgroup = *g_next++ =
9b88be
                          EC_GROUP_new_from_ecparameters(other_params))
9b88be
            || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
9b88be
            || !TEST_true(are_ec_nids_compatible(nid, tnid))
9b88be
            || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
9b88be
                            OPENSSL_EC_EXPLICIT_CURVE)) {
9b88be
        TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
9b88be
        goto err;
9b88be
    }
9b88be
9b88be
    /*
9b88be
     * A null seed in the parameters should be ignored, as it is optional:
9b88be
     * expect a "named" group.
9b88be
     */
9b88be
    if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
9b88be
            || !TEST_ptr(other_params = *p_next++ =
9b88be
                         EC_GROUP_get_ecparameters(tmpg, NULL))
9b88be
            || !TEST_ptr(tgroup = *g_next++ =
9b88be
                          EC_GROUP_new_from_ecparameters(other_params))
9b88be
            || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
9b88be
            || !TEST_true(are_ec_nids_compatible(nid, tnid))
9b88be
            || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
9b88be
                            OPENSSL_EC_EXPLICIT_CURVE)) {
9b88be
        TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
9b88be
        goto err;
9b88be
    }
9b88be
9b88be
    /*
9b88be
     * Check that changing any of the generator parameters does not yield a
9b88be
     * match with the built-in curves
9b88be
     */
9b88be
    if (/* Other gen, same group order & cofactor */
9b88be
        !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
9b88be
                                          group_cofactor))
9b88be
        || !TEST_ptr(other_params = *p_next++ =
9b88be
                     EC_GROUP_get_ecparameters(tmpg, NULL))
9b88be
        || !TEST_ptr(tgroup = *g_next++ =
9b88be
                      EC_GROUP_new_from_ecparameters(other_params))
9b88be
        || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
9b88be
        /* Same gen & cofactor, different order */
9b88be
        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
9b88be
                                             group_cofactor))
9b88be
        || !TEST_ptr(other_params = *p_next++ =
9b88be
                     EC_GROUP_get_ecparameters(tmpg, NULL))
9b88be
        || !TEST_ptr(tgroup = *g_next++ =
9b88be
                      EC_GROUP_new_from_ecparameters(other_params))
9b88be
        || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
9b88be
        /* The order is not an optional field, so this should fail */
9b88be
        || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
9b88be
                                              group_cofactor))
9b88be
        /* Check that a wrong cofactor is ignored, and we still match */
9b88be
        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
9b88be
                                             other_cofactor))
9b88be
        || !TEST_ptr(other_params = *p_next++ =
9b88be
                     EC_GROUP_get_ecparameters(tmpg, NULL))
9b88be
        || !TEST_ptr(tgroup = *g_next++ =
9b88be
                      EC_GROUP_new_from_ecparameters(other_params))
9b88be
        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
9b88be
        || !TEST_true(are_ec_nids_compatible(nid, tnid))
9b88be
        || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
9b88be
                        OPENSSL_EC_EXPLICIT_CURVE)
9b88be
        /* Check that if the cofactor is not set then it still matches */
9b88be
        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
9b88be
                                             NULL))
9b88be
        || !TEST_ptr(other_params = *p_next++ =
9b88be
                     EC_GROUP_get_ecparameters(tmpg, NULL))
9b88be
        || !TEST_ptr(tgroup = *g_next++ =
9b88be
                      EC_GROUP_new_from_ecparameters(other_params))
9b88be
        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
9b88be
        || !TEST_true(are_ec_nids_compatible(nid, tnid))
9b88be
        || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
9b88be
                        OPENSSL_EC_EXPLICIT_CURVE)
9b88be
        /* check that restoring the generator passes */
9b88be
        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
9b88be
                                             group_cofactor))
9b88be
        || !TEST_ptr(other_params = *p_next++ =
9b88be
                     EC_GROUP_get_ecparameters(tmpg, NULL))
9b88be
        || !TEST_ptr(tgroup = *g_next++ =
9b88be
                      EC_GROUP_new_from_ecparameters(other_params))
9b88be
        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
9b88be
        || !TEST_true(are_ec_nids_compatible(nid, tnid))
9b88be
        || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
9b88be
                        OPENSSL_EC_EXPLICIT_CURVE))
9b88be
        goto err;
9b88be
9b88be
    ret = 1;
9b88be
err:
9b88be
    for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
9b88be
        EC_GROUP_free(*g_next);
9b88be
    for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
9b88be
        ECPARAMETERS_free(*p_next);
9b88be
    ECPARAMETERS_free(params);
9b88be
    EC_POINT_free(other_gen);
9b88be
    EC_GROUP_free(tmpg);
9b88be
    EC_GROUP_free(group);
9b88be
    BN_CTX_end(bn_ctx);
9b88be
    BN_CTX_free(bn_ctx);
9b88be
    return ret;
9b88be
}
9b88be
9b88be
static int parameter_test(void)
9b88be
{
9b88be
    EC_GROUP *group = NULL, *group2 = NULL;
9b88be
    ECPARAMETERS *ecparameters = NULL;
9b88be
    unsigned char *buf = NULL;
9b88be
    int r = 0, len;
9b88be
9b88be
    /* must use a curve without a special group method */
9b88be
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp256k1))
9b88be
        || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
9b88be
        || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
9b88be
        || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
9b88be
        goto err;
9b88be
9b88be
    EC_GROUP_free(group);
9b88be
    group = NULL;
9b88be
9b88be
    /* Test the named curve encoding, which should be default. */
9b88be
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
9b88be
        || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
9b88be
        || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
9b88be
        goto err;
9b88be
9b88be
    OPENSSL_free(buf);
9b88be
    buf = NULL;
9b88be
9b88be
    /*
9b88be
     * Test the explicit encoding. P-521 requires correctly zero-padding the
9b88be
     * curve coefficients.
9b88be
     */
9b88be
    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
9b88be
    if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
9b88be
        || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
9b88be
        goto err;
9b88be
9b88be
    r = 1;
9b88be
err:
9b88be
    EC_GROUP_free(group);
9b88be
    EC_GROUP_free(group2);
9b88be
    ECPARAMETERS_free(ecparameters);
9b88be
    OPENSSL_free(buf);
9b88be
    return r;
9b88be
}
9b88be
9b88be
/*-
9b88be
 * random 256-bit explicit parameters curve, cofactor absent
9b88be
 * order:    0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
9b88be
 * cofactor:   0x12bc94785251297abfafddf1565100da (125 bit)
9b88be
 */
9b88be
static const unsigned char params_cf_pass[] = {
9b88be
    0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
9b88be
    0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
9b88be
    0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
9b88be
    0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
9b88be
    0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
9b88be
    0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
9b88be
    0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
9b88be
    0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
9b88be
    0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
9b88be
    0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
9b88be
    0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
9b88be
    0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
9b88be
    0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
9b88be
    0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
9b88be
    0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
9b88be
    0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
9b88be
    0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
9b88be
    0x14, 0xa8, 0x2f, 0x4f
9b88be
};
9b88be
9b88be
/*-
9b88be
 * random 256-bit explicit parameters curve, cofactor absent
9b88be
 * order:    0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
9b88be
 * cofactor:   0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
9b88be
 */
9b88be
static const unsigned char params_cf_fail[] = {
9b88be
    0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
9b88be
    0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
9b88be
    0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
9b88be
    0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
9b88be
    0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
9b88be
    0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
9b88be
    0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
9b88be
    0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
9b88be
    0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
9b88be
    0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
9b88be
    0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
9b88be
    0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
9b88be
    0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
9b88be
    0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
9b88be
    0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
9b88be
    0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
9b88be
    0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
9b88be
    0x34, 0xa2, 0x21, 0x01
9b88be
};
9b88be
9b88be
/*-
9b88be
 * Test two random 256-bit explicit parameters curves with absent cofactor.
9b88be
 * The two curves are chosen to roughly straddle the bounds at which the lib
9b88be
 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
9b88be
 *
9b88be
 * - params_cf_pass: order is sufficiently close to p to compute cofactor
9b88be
 * - params_cf_fail: order is too far away from p to compute cofactor
9b88be
 *
9b88be
 * For standards-compliant curves, cofactor is chosen as small as possible.
9b88be
 * So you can see neither of these curves are fit for cryptographic use.
9b88be
 *
9b88be
 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
9b88be
 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
9b88be
 * will always succeed in computing the cofactor. Neither of these curves
9b88be
 * conform to that -- this is just robustness testing.
9b88be
 */
9b88be
static int cofactor_range_test(void)
9b88be
{
9b88be
    EC_GROUP *group = NULL;
9b88be
    BIGNUM *cf = NULL;
9b88be
    int ret = 0;
9b88be
    const unsigned char *b1 = (const unsigned char *)params_cf_fail;
9b88be
    const unsigned char *b2 = (const unsigned char *)params_cf_pass;
9b88be
9b88be
    if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
9b88be
        || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
9b88be
        || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
9b88be
                                                sizeof(params_cf_pass)))
9b88be
        || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
9b88be
        || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
9b88be
        goto err;
9b88be
    ret = 1;
9b88be
 err:
9b88be
    BN_free(cf);
9b88be
    EC_GROUP_free(group);
9b88be
    return ret;
9b88be
}
9b88be
9b88be
/*-
9b88be
 * For named curves, test that:
9b88be
 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
9b88be
 * - a nonsensical cofactor throws an error (negative test)
9b88be
 * - nonsensical orders throw errors (negative tests)
9b88be
 */
9b88be
static int cardinality_test(int n)
9b88be
{
9b88be
    int ret = 0;
9b88be
    int nid = curves[n].nid;
9b88be
    BN_CTX *ctx = NULL;
9b88be
    EC_GROUP *g1 = NULL, *g2 = NULL;
9b88be
    EC_POINT *g2_gen = NULL;
9b88be
    BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
9b88be
           *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
9b88be
9b88be
    TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
9b88be
9b88be
    if (!TEST_ptr(ctx = BN_CTX_new())
9b88be
        || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
9b88be
        || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
9b88be
        EC_GROUP_free(g1);
9b88be
        EC_GROUP_free(g2);
9b88be
        BN_CTX_free(ctx);
9b88be
        return 0;
9b88be
    }
9b88be
9b88be
    BN_CTX_start(ctx);
9b88be
    g1_p = BN_CTX_get(ctx);
9b88be
    g1_a = BN_CTX_get(ctx);
9b88be
    g1_b = BN_CTX_get(ctx);
9b88be
    g1_x = BN_CTX_get(ctx);
9b88be
    g1_y = BN_CTX_get(ctx);
9b88be
    g1_order = BN_CTX_get(ctx);
9b88be
    g1_cf = BN_CTX_get(ctx);
9b88be
9b88be
    if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
9b88be
        /* pull out the explicit curve parameters */
9b88be
        || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
9b88be
        || !TEST_true(EC_POINT_get_affine_coordinates(g1,
9b88be
                      EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
9b88be
        || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
9b88be
        || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
9b88be
        /* construct g2 manually with g1 parameters */
9b88be
        || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
9b88be
        || !TEST_ptr(g2_gen = EC_POINT_new(g2))
9b88be
        || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
9b88be
        /* pass NULL cofactor: lib should compute it */
9b88be
        || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
9b88be
        || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
9b88be
        || !TEST_BN_eq(g1_cf, g2_cf)
9b88be
        /* pass zero cofactor: lib should compute it */
9b88be
        || !TEST_true(BN_set_word(g2_cf, 0))
9b88be
        || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
9b88be
        || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
9b88be
        || !TEST_BN_eq(g1_cf, g2_cf)
9b88be
        /* negative test for invalid cofactor */
9b88be
        || !TEST_true(BN_set_word(g2_cf, 0))
9b88be
        || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
9b88be
        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
9b88be
        /* negative test for NULL order */
9b88be
        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
9b88be
        /* negative test for zero order */
9b88be
        || !TEST_true(BN_set_word(g1_order, 0))
9b88be
        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
9b88be
        /* negative test for negative order */
9b88be
        || !TEST_true(BN_set_word(g2_cf, 0))
9b88be
        || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
9b88be
        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
9b88be
        /* negative test for too large order */
9b88be
        || !TEST_true(BN_lshift(g1_order, g1_p, 2))
9b88be
        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
9b88be
        goto err;
9b88be
    ret = 1;
9b88be
 err:
9b88be
    EC_POINT_free(g2_gen);
9b88be
    EC_GROUP_free(g1);
9b88be
    EC_GROUP_free(g2);
9b88be
    BN_CTX_end(ctx);
9b88be
    BN_CTX_free(ctx);
9b88be
    return ret;
9b88be
}
9b88be
9b88be
/*
9b88be
 * Helper for ec_point_hex2point_test
9b88be
 *
9b88be
 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
9b88be
 * (group,P) pair.
9b88be
 *
9b88be
 * If P is NULL use point at infinity.
9b88be
 */
9b88be
static ossl_inline
9b88be
int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
9b88be
                                   point_conversion_form_t form,
9b88be
                                   BN_CTX *bnctx)
9b88be
{
9b88be
    int ret = 0;
9b88be
    EC_POINT *Q = NULL, *Pinf = NULL;
9b88be
    char *hex = NULL;
9b88be
9b88be
    if (P == NULL) {
9b88be
        /* If P is NULL use point at infinity. */
9b88be
        if (!TEST_ptr(Pinf = EC_POINT_new(group))
9b88be
                || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
9b88be
            goto err;
9b88be
        P = Pinf;
9b88be
    }
9b88be
9b88be
    if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
9b88be
            || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
9b88be
            || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
9b88be
        goto err;
9b88be
9b88be
    /*
9b88be
     * The next check is most likely superfluous, as EC_POINT_cmp should already
9b88be
     * cover this.
9b88be
     * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
9b88be
     * so we include it anyway!
9b88be
     */
9b88be
    if (Pinf != NULL
9b88be
            && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
9b88be
        goto err;
9b88be
9b88be
    ret = 1;
9b88be
9b88be
 err:
9b88be
    EC_POINT_free(Pinf);
9b88be
    OPENSSL_free(hex);
9b88be
    EC_POINT_free(Q);
9b88be
9b88be
    return ret;
9b88be
}
9b88be
9b88be
/*
9b88be
 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
9b88be
 */
9b88be
static int ec_point_hex2point_test(int id)
9b88be
{
9b88be
    int ret = 0, nid;
9b88be
    EC_GROUP *group = NULL;
9b88be
    const EC_POINT *G = NULL;
9b88be
    EC_POINT *P = NULL;
9b88be
    BN_CTX * bnctx = NULL;
9b88be
9b88be
    /* Do some setup */
9b88be
    nid = curves[id].nid;
9b88be
    if (!TEST_ptr(bnctx = BN_CTX_new())
9b88be
            || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
9b88be
            || !TEST_ptr(G = EC_GROUP_get0_generator(group))
9b88be
            || !TEST_ptr(P = EC_POINT_dup(G, group)))
9b88be
        goto err;
9b88be
9b88be
    if (!TEST_true(ec_point_hex2point_test_helper(group, P,
9b88be
                                                  POINT_CONVERSION_COMPRESSED,
9b88be
                                                  bnctx))
9b88be
            || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
9b88be
                                                         POINT_CONVERSION_COMPRESSED,
9b88be
                                                         bnctx))
9b88be
            || !TEST_true(ec_point_hex2point_test_helper(group, P,
9b88be
                                                         POINT_CONVERSION_UNCOMPRESSED,
9b88be
                                                         bnctx))
9b88be
            || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
9b88be
                                                         POINT_CONVERSION_UNCOMPRESSED,
9b88be
                                                         bnctx))
9b88be
            || !TEST_true(ec_point_hex2point_test_helper(group, P,
9b88be
                                                         POINT_CONVERSION_HYBRID,
9b88be
                                                         bnctx))
9b88be
            || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
9b88be
                                                         POINT_CONVERSION_HYBRID,
9b88be
                                                         bnctx)))
9b88be
        goto err;
9b88be
9b88be
    ret = 1;
9b88be
9b88be
 err:
9b88be
    EC_POINT_free(P);
9b88be
    EC_GROUP_free(group);
9b88be
    BN_CTX_free(bnctx);
9b88be
9b88be
    return ret;
9b88be
}
9b88be
9b88be
/*
9b88be
 * check the EC_METHOD respects the supplied EC_GROUP_set_generator G
9b88be
 */
9b88be
static int custom_generator_test(int id)
9b88be
{
9b88be
    int ret = 0, nid, bsize;
9b88be
    EC_GROUP *group = NULL;
9b88be
    EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
9b88be
    BN_CTX *ctx = NULL;
9b88be
    BIGNUM *k = NULL;
9b88be
    unsigned char *b1 = NULL, *b2 = NULL;
9b88be
9b88be
    /* Do some setup */
9b88be
    nid = curves[id].nid;
9b88be
    TEST_note("Curve %s", OBJ_nid2sn(nid));
9b88be
    if (!TEST_ptr(ctx = BN_CTX_new()))
9b88be
        return 0;
9b88be
9b88be
    BN_CTX_start(ctx);
9b88be
9b88be
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
9b88be
        goto err;
9b88be
9b88be
    /* expected byte length of encoded points */
9b88be
    bsize = (EC_GROUP_get_degree(group) + 7) / 8;
9b88be
    bsize = 2 * bsize + 1;
9b88be
9b88be
    if (!TEST_ptr(k = BN_CTX_get(ctx))
9b88be
        /* fetch a testing scalar k != 0,1 */
9b88be
        || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
9b88be
                              BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
9b88be
        /* make k even */
9b88be
        || !TEST_true(BN_clear_bit(k, 0))
9b88be
        || !TEST_ptr(G2 = EC_POINT_new(group))
9b88be
        || !TEST_ptr(Q1 = EC_POINT_new(group))
9b88be
        /* Q1 := kG */
9b88be
        || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
9b88be
        /* pull out the bytes of that */
9b88be
        || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
9b88be
                                           POINT_CONVERSION_UNCOMPRESSED, NULL,
9b88be
                                           0, ctx), bsize)
9b88be
        || !TEST_ptr(b1 = OPENSSL_malloc(bsize))
9b88be
        || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
9b88be
                                           POINT_CONVERSION_UNCOMPRESSED, b1,
9b88be
                                           bsize, ctx), bsize)
9b88be
        /* new generator is G2 := 2G */
9b88be
        || !TEST_true(EC_POINT_dbl(group, G2, EC_GROUP_get0_generator(group),
9b88be
                                   ctx))
9b88be
        || !TEST_true(EC_GROUP_set_generator(group, G2,
9b88be
                                             EC_GROUP_get0_order(group),
9b88be
                                             EC_GROUP_get0_cofactor(group)))
9b88be
        || !TEST_ptr(Q2 = EC_POINT_new(group))
9b88be
        || !TEST_true(BN_rshift1(k, k))
9b88be
        /* Q2 := k/2 G2 */
9b88be
        || !TEST_true(EC_POINT_mul(group, Q2, k, NULL, NULL, ctx))
9b88be
        || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
9b88be
                                           POINT_CONVERSION_UNCOMPRESSED, NULL,
9b88be
                                           0, ctx), bsize)
9b88be
        || !TEST_ptr(b2 = OPENSSL_malloc(bsize))
9b88be
        || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
9b88be
                                           POINT_CONVERSION_UNCOMPRESSED, b2,
9b88be
                                           bsize, ctx), bsize)
9b88be
        /* Q1 = kG = k/2 G2 = Q2 should hold */
9b88be
        || !TEST_int_eq(CRYPTO_memcmp(b1, b2, bsize), 0))
9b88be
        goto err;
9b88be
9b88be
    ret = 1;
9b88be
9b88be
 err:
9b88be
    BN_CTX_end(ctx);
9b88be
    EC_POINT_free(Q1);
9b88be
    EC_POINT_free(Q2);
9b88be
    EC_POINT_free(G2);
9b88be
    EC_GROUP_free(group);
9b88be
    BN_CTX_free(ctx);
9b88be
    OPENSSL_free(b1);
9b88be
    OPENSSL_free(b2);
9b88be
9b88be
    return ret;
9b88be
}
9b88be
9b88be
#endif /* OPENSSL_NO_EC */
9b88be
9b88be
int setup_tests(void)
9b88be
{
9b88be
#ifndef OPENSSL_NO_EC
9b88be
    crv_len = EC_get_builtin_curves(NULL, 0);
9b88be
    if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
9b88be
        || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
9b88be
        return 0;
9b88be
9b88be
    ADD_TEST(parameter_test);
9b88be
    ADD_TEST(cofactor_range_test);
9b88be
    ADD_ALL_TESTS(cardinality_test, crv_len);
9b88be
    ADD_TEST(prime_field_tests);
9b88be
# ifndef OPENSSL_NO_EC2M
9b88be
    ADD_TEST(char2_field_tests);
9b88be
    ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
9b88be
# endif
9b88be
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
9b88be
    ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
9b88be
    ADD_TEST(underflow_test);
9b88be
# endif
9b88be
    ADD_ALL_TESTS(internal_curve_test, crv_len);
9b88be
    ADD_ALL_TESTS(internal_curve_test_method, crv_len);
9b88be
9b88be
    ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
9b88be
    ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
9b88be
    ADD_ALL_TESTS(custom_generator_test, crv_len);
9b88be
#endif /* OPENSSL_NO_EC */
9b88be
    return 1;
9b88be
}
9b88be
9b88be
void cleanup_tests(void)
9b88be
{
9b88be
#ifndef OPENSSL_NO_EC
9b88be
    OPENSSL_free(curves);
9b88be
#endif
9b88be
}