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