Blame SPECS/ectest.c

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