/* 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 <string.h>
#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));
	}
