/* crypto/ecdh/ech_lib.c */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
 * to the OpenSSL project.
 *
 * The ECC Code is licensed pursuant to the OpenSSL open source
 * license provided below.
 *
 * The ECDH software is originally written by Douglas Stebila of
 * Sun Microsystems Laboratories.
 *
 */
/* ====================================================================
 * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include "ech_locl.h"
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_SYS_STARBOARD)
#include <string.h>
#endif  // !defined(OPENSSL_SYS_STARBOARD)
#ifndef OPENSSL_NO_ENGINE
# include <openssl/engine.h>
#endif
#include <openssl/err.h>
#ifdef OPENSSL_FIPS
# include <openssl/fips.h>
#endif

const char ECDH_version[] = "ECDH" OPENSSL_VERSION_PTEXT;

static const ECDH_METHOD *default_ECDH_method = NULL;

static void *ecdh_data_new(void);
static void *ecdh_data_dup(void *);
static void ecdh_data_free(void *);

void ECDH_set_default_method(const ECDH_METHOD *meth)
{
    default_ECDH_method = meth;
}

const ECDH_METHOD *ECDH_get_default_method(void)
{
    if (!default_ECDH_method) {
#ifdef OPENSSL_FIPS
        if (FIPS_mode())
            return FIPS_ecdh_openssl();
        else
            return ECDH_OpenSSL();
#else
        default_ECDH_method = ECDH_OpenSSL();
#endif
    }
    return default_ECDH_method;
}

int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
{
    ECDH_DATA *ecdh;

    ecdh = ecdh_check(eckey);

    if (ecdh == NULL)
        return 0;

#if 0
    mtmp = ecdh->meth;
    if (mtmp->finish)
        mtmp->finish(eckey);
#endif
#ifndef OPENSSL_NO_ENGINE
    if (ecdh->engine) {
        ENGINE_finish(ecdh->engine);
        ecdh->engine = NULL;
    }
#endif
    ecdh->meth = meth;
#if 0
    if (meth->init)
        meth->init(eckey);
#endif
    return 1;
}

static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
{
    ECDH_DATA *ret;

    ret = (ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA));
    if (ret == NULL) {
        ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
        return (NULL);
    }

    ret->init = NULL;

    ret->meth = ECDH_get_default_method();
    ret->engine = engine;
#ifndef OPENSSL_NO_ENGINE
    if (!ret->engine)
        ret->engine = ENGINE_get_default_ECDH();
    if (ret->engine) {
        ret->meth = ENGINE_get_ECDH(ret->engine);
        if (!ret->meth) {
            ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
            ENGINE_finish(ret->engine);
            OPENSSL_free(ret);
            return NULL;
        }
    }
#endif

    ret->flags = ret->meth->flags;
    CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
#if 0
    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
        OPENSSL_free(ret);
        ret = NULL;
    }
#endif
    return (ret);
}

static void *ecdh_data_new(void)
{
    return (void *)ECDH_DATA_new_method(NULL);
}

static void *ecdh_data_dup(void *data)
{
    ECDH_DATA *r = (ECDH_DATA *)data;

    /* XXX: dummy operation */
    if (r == NULL)
        return NULL;

    return (void *)ecdh_data_new();
}

void ecdh_data_free(void *data)
{
    ECDH_DATA *r = (ECDH_DATA *)data;

#ifndef OPENSSL_NO_ENGINE
    if (r->engine)
        ENGINE_finish(r->engine);
#endif

    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data);

    OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA));

    OPENSSL_free(r);
}

ECDH_DATA *ecdh_check(EC_KEY *key)
{
    ECDH_DATA *ecdh_data;

    void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
                                            ecdh_data_free, ecdh_data_free);
    if (data == NULL) {
        ecdh_data = (ECDH_DATA *)ecdh_data_new();
        if (ecdh_data == NULL)
            return NULL;
        data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
                                             ecdh_data_dup, ecdh_data_free,
                                             ecdh_data_free);
        if (data != NULL) {
            /*
             * Another thread raced us to install the key_method data and
             * won.
             */
            ecdh_data_free(ecdh_data);
            ecdh_data = (ECDH_DATA *)data;
        }
    } else
        ecdh_data = (ECDH_DATA *)data;
#ifdef OPENSSL_FIPS
    if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD)
        && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) {
        ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD);
        return NULL;
    }
#endif

    return ecdh_data;
}

int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp,
                                   new_func, dup_func, free_func);
}

int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg)
{
    ECDH_DATA *ecdh;
    ecdh = ecdh_check(d);
    if (ecdh == NULL)
        return 0;
    return (CRYPTO_set_ex_data(&ecdh->ex_data, idx, arg));
}

void *ECDH_get_ex_data(EC_KEY *d, int idx)
{
    ECDH_DATA *ecdh;
    ecdh = ecdh_check(d);
    if (ecdh == NULL)
        return NULL;
    return (CRYPTO_get_ex_data(&ecdh->ex_data, idx));
}
