/* 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>

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) 
		default_ECDH_method = ECDH_OpenSSL();
	return default_ECDH_method;
	}

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

	ecdh = ecdh_check(eckey);

	if (ecdh == NULL)
		return 0;

        mtmp = ecdh->meth;
#if 0
        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;
		EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
			ecdh_data_dup, ecdh_data_free, ecdh_data_free);
	}
	else
		ecdh_data = (ECDH_DATA *)data;
	

	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));
	}
