Blame test/ec_internal_test.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the Apache License 2.0 (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
#include <openssl/ec.h>
Packit c4476c
#include "ec_local.h"
Packit c4476c
#include <openssl/objects.h>
Packit c4476c
Packit c4476c
static size_t crv_len = 0;
Packit c4476c
static EC_builtin_curve *curves = NULL;
Packit c4476c
Packit c4476c
/* sanity checks field_inv function pointer in EC_METHOD */
Packit c4476c
static int group_field_tests(const EC_GROUP *group, BN_CTX *ctx)
Packit c4476c
{
Packit c4476c
    BIGNUM *a = NULL, *b = NULL, *c = NULL;
Packit c4476c
    int ret = 0;
Packit c4476c
Packit c4476c
    if (group->meth->field_inv == NULL || group->meth->field_mul == NULL)
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    BN_CTX_start(ctx);
Packit c4476c
    a = BN_CTX_get(ctx);
Packit c4476c
    b = BN_CTX_get(ctx);
Packit c4476c
    if (!TEST_ptr(c = BN_CTX_get(ctx))
Packit c4476c
        /* 1/1 = 1 */
Packit c4476c
        || !TEST_true(group->meth->field_inv(group, b, BN_value_one(), ctx))
Packit c4476c
        || !TEST_true(BN_is_one(b))
Packit c4476c
        /* (1/a)*a = 1 */
Packit c4476c
        || !TEST_true(BN_pseudo_rand(a, BN_num_bits(group->field) - 1,
Packit c4476c
                                     BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
Packit c4476c
        || !TEST_true(group->meth->field_inv(group, b, a, ctx))
Packit c4476c
        || (group->meth->field_encode &&
Packit c4476c
            !TEST_true(group->meth->field_encode(group, a, a, ctx)))
Packit c4476c
        || (group->meth->field_encode &&
Packit c4476c
            !TEST_true(group->meth->field_encode(group, b, b, ctx)))
Packit c4476c
        || !TEST_true(group->meth->field_mul(group, c, a, b, ctx))
Packit c4476c
        || (group->meth->field_decode &&
Packit c4476c
            !TEST_true(group->meth->field_decode(group, c, c, ctx)))
Packit c4476c
        || !TEST_true(BN_is_one(c)))
Packit c4476c
        goto err;
Packit c4476c
Packit c4476c
    /* 1/0 = error */
Packit c4476c
    BN_zero(a);
Packit c4476c
    if (!TEST_false(group->meth->field_inv(group, b, a, ctx))
Packit c4476c
        || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
Packit c4476c
        || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
Packit c4476c
                      EC_R_CANNOT_INVERT)
Packit c4476c
        /* 1/p = error */
Packit c4476c
        || !TEST_false(group->meth->field_inv(group, b, group->field, ctx))
Packit c4476c
        || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
Packit c4476c
        || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
Packit c4476c
                      EC_R_CANNOT_INVERT))
Packit c4476c
        goto err;
Packit c4476c
Packit c4476c
    ERR_clear_error();
Packit c4476c
    ret = 1;
Packit c4476c
 err:
Packit c4476c
    BN_CTX_end(ctx);
Packit c4476c
    return ret;
Packit c4476c
}
Packit c4476c
Packit c4476c
/* wrapper for group_field_tests for explicit curve params and EC_METHOD */
Packit c4476c
static int field_tests(const EC_METHOD *meth, const unsigned char *params,
Packit c4476c
                       int len)
Packit c4476c
{
Packit c4476c
    BN_CTX *ctx = NULL;
Packit c4476c
    BIGNUM *p = NULL, *a = NULL, *b = NULL;
Packit c4476c
    EC_GROUP *group = NULL;
Packit c4476c
    int ret = 0;
Packit c4476c
Packit c4476c
    if (!TEST_ptr(ctx = BN_CTX_new()))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    BN_CTX_start(ctx);
Packit c4476c
    p = BN_CTX_get(ctx);
Packit c4476c
    a = BN_CTX_get(ctx);
Packit c4476c
    if (!TEST_ptr(b = BN_CTX_get(ctx))
Packit c4476c
        || !TEST_ptr(group = EC_GROUP_new(meth))
Packit c4476c
        || !TEST_true(BN_bin2bn(params, len, p))
Packit c4476c
        || !TEST_true(BN_bin2bn(params + len, len, a))
Packit c4476c
        || !TEST_true(BN_bin2bn(params + 2 * len, len, b))
Packit c4476c
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Packit c4476c
        || !group_field_tests(group, ctx))
Packit c4476c
        goto err;
Packit c4476c
    ret = 1;
Packit c4476c
Packit c4476c
 err:
Packit c4476c
    BN_CTX_end(ctx);
Packit c4476c
    BN_CTX_free(ctx);
Packit c4476c
    if (group != NULL)
Packit c4476c
        EC_GROUP_free(group);
Packit c4476c
    return ret;
Packit c4476c
}
Packit c4476c
Packit c4476c
/* NIST prime curve P-256 */
Packit c4476c
static const unsigned char params_p256[] = {
Packit c4476c
    /* p */
Packit c4476c
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
Packit c4476c
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
Packit c4476c
    /* a */
Packit c4476c
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
Packit c4476c
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
Packit c4476c
    /* b */
Packit c4476c
    0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
Packit c4476c
    0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
Packit c4476c
    0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
Packit c4476c
};
Packit c4476c
Packit c4476c
#ifndef OPENSSL_NO_EC2M
Packit c4476c
/* NIST binary curve B-283 */
Packit c4476c
static const unsigned char params_b283[] = {
Packit c4476c
    /* p */
Packit c4476c
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
Packit c4476c
    /* a */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
Packit c4476c
    /* b */
Packit c4476c
    0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A,
Packit c4476c
    0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2,
Packit c4476c
    0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5
Packit c4476c
};
Packit c4476c
#endif
Packit c4476c
Packit c4476c
/* test EC_GFp_simple_method directly */
Packit c4476c
static int field_tests_ecp_simple(void)
Packit c4476c
{
Packit c4476c
    TEST_info("Testing EC_GFp_simple_method()\n");
Packit c4476c
    return field_tests(EC_GFp_simple_method(), params_p256,
Packit c4476c
                       sizeof(params_p256) / 3);
Packit c4476c
}
Packit c4476c
Packit c4476c
/* test EC_GFp_mont_method directly */
Packit c4476c
static int field_tests_ecp_mont(void)
Packit c4476c
{
Packit c4476c
    TEST_info("Testing EC_GFp_mont_method()\n");
Packit c4476c
    return field_tests(EC_GFp_mont_method(), params_p256,
Packit c4476c
                       sizeof(params_p256) / 3);
Packit c4476c
}
Packit c4476c
Packit c4476c
#ifndef OPENSSL_NO_EC2M
Packit c4476c
/* test EC_GF2m_simple_method directly */
Packit c4476c
static int field_tests_ec2_simple(void)
Packit c4476c
{
Packit c4476c
    TEST_info("Testing EC_GF2m_simple_method()\n");
Packit c4476c
    return field_tests(EC_GF2m_simple_method(), params_b283,
Packit c4476c
                       sizeof(params_b283) / 3);
Packit c4476c
}
Packit c4476c
#endif
Packit c4476c
Packit c4476c
/* test default method for a named curve */
Packit c4476c
static int field_tests_default(int n)
Packit c4476c
{
Packit c4476c
    BN_CTX *ctx = NULL;
Packit c4476c
    EC_GROUP *group = NULL;
Packit c4476c
    int nid = curves[n].nid;
Packit c4476c
    int ret = 0;
Packit c4476c
Packit c4476c
    TEST_info("Testing curve %s\n", OBJ_nid2sn(nid));
Packit c4476c
Packit c4476c
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
Packit c4476c
        || !TEST_ptr(ctx = BN_CTX_new())
Packit c4476c
        || !group_field_tests(group, ctx))
Packit c4476c
        goto err;
Packit c4476c
Packit c4476c
    ret = 1;
Packit c4476c
 err:
Packit c4476c
    if (group != NULL)
Packit c4476c
        EC_GROUP_free(group);
Packit c4476c
    if (ctx != NULL)
Packit c4476c
        BN_CTX_free(ctx);
Packit c4476c
    return ret;
Packit c4476c
}
Packit c4476c
Packit c4476c
int setup_tests(void)
Packit c4476c
{
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(field_tests_ecp_simple);
Packit c4476c
    ADD_TEST(field_tests_ecp_mont);
Packit c4476c
#ifndef OPENSSL_NO_EC2M
Packit c4476c
    ADD_TEST(field_tests_ec2_simple);
Packit c4476c
#endif
Packit c4476c
    ADD_ALL_TESTS(field_tests_default, crv_len);
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
void cleanup_tests(void)
Packit c4476c
{
Packit c4476c
    OPENSSL_free(curves);
Packit c4476c
}