Blame test/ec_internal_test.c

Packit Service 084de1
/*
Packit Service 084de1
 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
 *
Packit Service 084de1
 * Licensed under the Apache License 2.0 (the "License").  You may not use
Packit Service 084de1
 * this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
 * in the file LICENSE in the source distribution or at
Packit Service 084de1
 * https://www.openssl.org/source/license.html
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
#include "internal/nelem.h"
Packit Service 084de1
#include "testutil.h"
Packit Service 084de1
#include <openssl/ec.h>
Packit Service 084de1
#include "ec_local.h"
Packit Service 084de1
#include <openssl/objects.h>
Packit Service 084de1
Packit Service 084de1
static size_t crv_len = 0;
Packit Service 084de1
static EC_builtin_curve *curves = NULL;
Packit Service 084de1
Packit Service 084de1
/* sanity checks field_inv function pointer in EC_METHOD */
Packit Service 084de1
static int group_field_tests(const EC_GROUP *group, BN_CTX *ctx)
Packit Service 084de1
{
Packit Service 084de1
    BIGNUM *a = NULL, *b = NULL, *c = NULL;
Packit Service 084de1
    int ret = 0;
Packit Service 084de1
Packit Service 084de1
    if (group->meth->field_inv == NULL || group->meth->field_mul == NULL)
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    BN_CTX_start(ctx);
Packit Service 084de1
    a = BN_CTX_get(ctx);
Packit Service 084de1
    b = BN_CTX_get(ctx);
Packit Service 084de1
    if (!TEST_ptr(c = BN_CTX_get(ctx))
Packit Service 084de1
        /* 1/1 = 1 */
Packit Service 084de1
        || !TEST_true(group->meth->field_inv(group, b, BN_value_one(), ctx))
Packit Service 084de1
        || !TEST_true(BN_is_one(b))
Packit Service 084de1
        /* (1/a)*a = 1 */
Packit Service 084de1
        || !TEST_true(BN_pseudo_rand(a, BN_num_bits(group->field) - 1,
Packit Service 084de1
                                     BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
Packit Service 084de1
        || !TEST_true(group->meth->field_inv(group, b, a, ctx))
Packit Service 084de1
        || (group->meth->field_encode &&
Packit Service 084de1
            !TEST_true(group->meth->field_encode(group, a, a, ctx)))
Packit Service 084de1
        || (group->meth->field_encode &&
Packit Service 084de1
            !TEST_true(group->meth->field_encode(group, b, b, ctx)))
Packit Service 084de1
        || !TEST_true(group->meth->field_mul(group, c, a, b, ctx))
Packit Service 084de1
        || (group->meth->field_decode &&
Packit Service 084de1
            !TEST_true(group->meth->field_decode(group, c, c, ctx)))
Packit Service 084de1
        || !TEST_true(BN_is_one(c)))
Packit Service 084de1
        goto err;
Packit Service 084de1
Packit Service 084de1
    /* 1/0 = error */
Packit Service 084de1
    BN_zero(a);
Packit Service 084de1
    if (!TEST_false(group->meth->field_inv(group, b, a, ctx))
Packit Service 084de1
        || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
Packit Service 084de1
        || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
Packit Service 084de1
                      EC_R_CANNOT_INVERT)
Packit Service 084de1
        /* 1/p = error */
Packit Service 084de1
        || !TEST_false(group->meth->field_inv(group, b, group->field, ctx))
Packit Service 084de1
        || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
Packit Service 084de1
        || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
Packit Service 084de1
                      EC_R_CANNOT_INVERT))
Packit Service 084de1
        goto err;
Packit Service 084de1
Packit Service 084de1
    ERR_clear_error();
Packit Service 084de1
    ret = 1;
Packit Service 084de1
 err:
Packit Service 084de1
    BN_CTX_end(ctx);
Packit Service 084de1
    return ret;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
/* wrapper for group_field_tests for explicit curve params and EC_METHOD */
Packit Service 084de1
static int field_tests(const EC_METHOD *meth, const unsigned char *params,
Packit Service 084de1
                       int len)
Packit Service 084de1
{
Packit Service 084de1
    BN_CTX *ctx = NULL;
Packit Service 084de1
    BIGNUM *p = NULL, *a = NULL, *b = NULL;
Packit Service 084de1
    EC_GROUP *group = NULL;
Packit Service 084de1
    int ret = 0;
Packit Service 084de1
Packit Service 084de1
    if (!TEST_ptr(ctx = BN_CTX_new()))
Packit Service 084de1
        return 0;
Packit Service 084de1
Packit Service 084de1
    BN_CTX_start(ctx);
Packit Service 084de1
    p = BN_CTX_get(ctx);
Packit Service 084de1
    a = BN_CTX_get(ctx);
Packit Service 084de1
    if (!TEST_ptr(b = BN_CTX_get(ctx))
Packit Service 084de1
        || !TEST_ptr(group = EC_GROUP_new(meth))
Packit Service 084de1
        || !TEST_true(BN_bin2bn(params, len, p))
Packit Service 084de1
        || !TEST_true(BN_bin2bn(params + len, len, a))
Packit Service 084de1
        || !TEST_true(BN_bin2bn(params + 2 * len, len, b))
Packit Service 084de1
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Packit Service 084de1
        || !group_field_tests(group, ctx))
Packit Service 084de1
        goto err;
Packit Service 084de1
    ret = 1;
Packit Service 084de1
Packit Service 084de1
 err:
Packit Service 084de1
    BN_CTX_end(ctx);
Packit Service 084de1
    BN_CTX_free(ctx);
Packit Service 084de1
    if (group != NULL)
Packit Service 084de1
        EC_GROUP_free(group);
Packit Service 084de1
    return ret;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
/* NIST prime curve P-256 */
Packit Service 084de1
static const unsigned char params_p256[] = {
Packit Service 084de1
    /* p */
Packit Service 084de1
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
Packit Service 084de1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
Packit Service 084de1
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
Packit Service 084de1
    /* a */
Packit Service 084de1
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
Packit Service 084de1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
Packit Service 084de1
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
Packit Service 084de1
    /* b */
Packit Service 084de1
    0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
Packit Service 084de1
    0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
Packit Service 084de1
    0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
#ifndef OPENSSL_NO_EC2M
Packit Service 084de1
/* NIST binary curve B-283 */
Packit Service 084de1
static const unsigned char params_b283[] = {
Packit Service 084de1
    /* p */
Packit Service 084de1
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 084de1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 084de1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
Packit Service 084de1
    /* a */
Packit Service 084de1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 084de1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 084de1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
Packit Service 084de1
    /* b */
Packit Service 084de1
    0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A,
Packit Service 084de1
    0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2,
Packit Service 084de1
    0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5
Packit Service 084de1
};
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
/* test EC_GFp_simple_method directly */
Packit Service 084de1
static int field_tests_ecp_simple(void)
Packit Service 084de1
{
Packit Service 084de1
    TEST_info("Testing EC_GFp_simple_method()\n");
Packit Service 084de1
    return field_tests(EC_GFp_simple_method(), params_p256,
Packit Service 084de1
                       sizeof(params_p256) / 3);
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
/* test EC_GFp_mont_method directly */
Packit Service 084de1
static int field_tests_ecp_mont(void)
Packit Service 084de1
{
Packit Service 084de1
    TEST_info("Testing EC_GFp_mont_method()\n");
Packit Service 084de1
    return field_tests(EC_GFp_mont_method(), params_p256,
Packit Service 084de1
                       sizeof(params_p256) / 3);
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
#ifndef OPENSSL_NO_EC2M
Packit Service 084de1
/* test EC_GF2m_simple_method directly */
Packit Service 084de1
static int field_tests_ec2_simple(void)
Packit Service 084de1
{
Packit Service 084de1
    TEST_info("Testing EC_GF2m_simple_method()\n");
Packit Service 084de1
    return field_tests(EC_GF2m_simple_method(), params_b283,
Packit Service 084de1
                       sizeof(params_b283) / 3);
Packit Service 084de1
}
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
/* test default method for a named curve */
Packit Service 084de1
static int field_tests_default(int n)
Packit Service 084de1
{
Packit Service 084de1
    BN_CTX *ctx = NULL;
Packit Service 084de1
    EC_GROUP *group = NULL;
Packit Service 084de1
    int nid = curves[n].nid;
Packit Service 084de1
    int ret = 0;
Packit Service 084de1
Packit Service 084de1
    TEST_info("Testing curve %s\n", OBJ_nid2sn(nid));
Packit Service 084de1
Packit Service 084de1
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
Packit Service 084de1
        || !TEST_ptr(ctx = BN_CTX_new())
Packit Service 084de1
        || !group_field_tests(group, ctx))
Packit Service 084de1
        goto err;
Packit Service 084de1
Packit Service 084de1
    ret = 1;
Packit Service 084de1
 err:
Packit Service 084de1
    if (group != NULL)
Packit Service 084de1
        EC_GROUP_free(group);
Packit Service 084de1
    if (ctx != NULL)
Packit Service 084de1
        BN_CTX_free(ctx);
Packit Service 084de1
    return ret;
Packit Service 084de1
}
Packit Service 084de1
Packit Service dd46e1
/*
Packit Service dd46e1
 * Tests behavior of the decoded_from_explicit_params flag and API
Packit Service dd46e1
 */
Packit Service dd46e1
static int decoded_flag_test(void)
Packit Service dd46e1
{
Packit Service dd46e1
    EC_GROUP *grp;
Packit Service dd46e1
    EC_GROUP *grp_copy = NULL;
Packit Service dd46e1
    ECPARAMETERS *ecparams = NULL;
Packit Service dd46e1
    ECPKPARAMETERS *ecpkparams = NULL;
Packit Service dd46e1
    EC_KEY *key = NULL;
Packit Service dd46e1
    unsigned char *encodedparams = NULL;
Packit Service dd46e1
    const unsigned char *encp;
Packit Service dd46e1
    int encodedlen;
Packit Service dd46e1
    int testresult = 0;
Packit Service dd46e1
Packit Service dd46e1
    /* Test EC_GROUP_new not setting the flag */
Packit Service dd46e1
    grp = EC_GROUP_new(EC_GFp_simple_method());
Packit Service dd46e1
    if (!TEST_ptr(grp)
Packit Service dd46e1
        || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
Packit Service dd46e1
        goto err;
Packit Service dd46e1
    EC_GROUP_free(grp);
Packit Service dd46e1
Packit Service dd46e1
    /* Test EC_GROUP_new_by_curve_name not setting the flag */
Packit Service dd46e1
    grp = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
Packit Service dd46e1
    if (!TEST_ptr(grp)
Packit Service dd46e1
        || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
Packit Service dd46e1
        goto err;
Packit Service dd46e1
Packit Service dd46e1
    /* Test EC_GROUP_new_from_ecparameters not setting the flag */
Packit Service dd46e1
    if (!TEST_ptr(ecparams = EC_GROUP_get_ecparameters(grp, NULL))
Packit Service dd46e1
        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecparameters(ecparams))
Packit Service dd46e1
        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
Packit Service dd46e1
        goto err;
Packit Service dd46e1
    EC_GROUP_free(grp_copy);
Packit Service dd46e1
    grp_copy = NULL;
Packit Service dd46e1
    ECPARAMETERS_free(ecparams);
Packit Service dd46e1
    ecparams = NULL;
Packit Service dd46e1
Packit Service dd46e1
    /* Test EC_GROUP_new_from_ecpkparameters not setting the flag */
Packit Service dd46e1
    if (!TEST_int_eq(EC_GROUP_get_asn1_flag(grp), OPENSSL_EC_NAMED_CURVE)
Packit Service dd46e1
        || !TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
Packit Service dd46e1
        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
Packit Service dd46e1
        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)
Packit Service dd46e1
        || !TEST_ptr(key = EC_KEY_new())
Packit Service dd46e1
    /* Test EC_KEY_decoded_from_explicit_params on key without a group */
Packit Service dd46e1
        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), -1)
Packit Service dd46e1
        || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
Packit Service dd46e1
    /* Test EC_KEY_decoded_from_explicit_params negative case */
Packit Service dd46e1
        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 0))
Packit Service dd46e1
        goto err;
Packit Service dd46e1
    EC_GROUP_free(grp_copy);
Packit Service dd46e1
    grp_copy = NULL;
Packit Service dd46e1
    ECPKPARAMETERS_free(ecpkparams);
Packit Service dd46e1
    ecpkparams = NULL;
Packit Service dd46e1
Packit Service dd46e1
    /* Test d2i_ECPKParameters with named params not setting the flag */
Packit Service dd46e1
    if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
Packit Service dd46e1
        || !TEST_ptr(encp = encodedparams)
Packit Service dd46e1
        || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
Packit Service dd46e1
        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
Packit Service dd46e1
        goto err;
Packit Service dd46e1
    EC_GROUP_free(grp_copy);
Packit Service dd46e1
    grp_copy = NULL;
Packit Service dd46e1
    OPENSSL_free(encodedparams);
Packit Service dd46e1
    encodedparams = NULL;
Packit Service dd46e1
Packit Service dd46e1
    /* Asn1 flag stays set to explicit with EC_GROUP_new_from_ecpkparameters */
Packit Service dd46e1
    EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_EXPLICIT_CURVE);
Packit Service dd46e1
    if (!TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
Packit Service dd46e1
        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
Packit Service dd46e1
        || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
Packit Service dd46e1
        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
Packit Service dd46e1
        goto err;
Packit Service dd46e1
    EC_GROUP_free(grp_copy);
Packit Service dd46e1
    grp_copy = NULL;
Packit Service dd46e1
Packit Service dd46e1
    /* Test d2i_ECPKParameters with explicit params setting the flag */
Packit Service dd46e1
    if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
Packit Service dd46e1
        || !TEST_ptr(encp = encodedparams)
Packit Service dd46e1
        || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
Packit Service dd46e1
        || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
Packit Service dd46e1
        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 1)
Packit Service dd46e1
        || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
Packit Service dd46e1
    /* Test EC_KEY_decoded_from_explicit_params positive case */
Packit Service dd46e1
        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 1))
Packit Service dd46e1
        goto err;
Packit Service dd46e1
Packit Service dd46e1
    testresult = 1;
Packit Service dd46e1
Packit Service dd46e1
 err:
Packit Service dd46e1
    EC_KEY_free(key);
Packit Service dd46e1
    EC_GROUP_free(grp);
Packit Service dd46e1
    EC_GROUP_free(grp_copy);
Packit Service dd46e1
    ECPARAMETERS_free(ecparams);
Packit Service dd46e1
    ECPKPARAMETERS_free(ecpkparams);
Packit Service dd46e1
    OPENSSL_free(encodedparams);
Packit Service dd46e1
Packit Service dd46e1
    return testresult;
Packit Service dd46e1
}
Packit Service dd46e1
Packit Service 084de1
int setup_tests(void)
Packit Service 084de1
{
Packit Service 084de1
    crv_len = EC_get_builtin_curves(NULL, 0);
Packit Service 084de1
    if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
Packit Service 084de1
        || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
Packit Service 084de1
        return 0;
Packit Service 084de1
Packit Service 084de1
    ADD_TEST(field_tests_ecp_simple);
Packit Service 084de1
    ADD_TEST(field_tests_ecp_mont);
Packit Service 084de1
#ifndef OPENSSL_NO_EC2M
Packit Service 084de1
    ADD_TEST(field_tests_ec2_simple);
Packit Service 084de1
#endif
Packit Service 084de1
    ADD_ALL_TESTS(field_tests_default, crv_len);
Packit Service dd46e1
    ADD_TEST(decoded_flag_test);
Packit Service 084de1
    return 1;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
void cleanup_tests(void)
Packit Service 084de1
{
Packit Service 084de1
    OPENSSL_free(curves);
Packit Service 084de1
}