/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 2007.
 */
/* ====================================================================
 * Copyright (c) 2007 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
 *    licensing@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 <stdio.h>
#include "cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include "evp_locl.h"

/* HMAC pkey context structure */

typedef struct
	{
	const EVP_MD *md;	/* MD for HMAC use */
	ASN1_OCTET_STRING ktmp; /* Temp storage for key */
	HMAC_CTX ctx;
	} HMAC_PKEY_CTX;

static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
	{
	HMAC_PKEY_CTX *hctx;
	hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX));
	if (!hctx)
		return 0;
	hctx->md = NULL;
	hctx->ktmp.data = NULL;
	hctx->ktmp.length = 0;
	hctx->ktmp.flags = 0;
	hctx->ktmp.type = V_ASN1_OCTET_STRING;
	HMAC_CTX_init(&hctx->ctx);

	ctx->data = hctx;
	ctx->keygen_info_count = 0;

	return 1;
	}

static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
	{
	HMAC_PKEY_CTX *sctx, *dctx;
	if (!pkey_hmac_init(dst))
		return 0;
       	sctx = src->data;
	dctx = dst->data;
	dctx->md = sctx->md;
	HMAC_CTX_init(&dctx->ctx);
	HMAC_CTX_copy(&dctx->ctx, &sctx->ctx);
	if (sctx->ktmp.data)
		{
		if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
					sctx->ktmp.data, sctx->ktmp.length))
			return 0;
		}
	return 1;
	}

static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
	{
	HMAC_PKEY_CTX *hctx = ctx->data;
	HMAC_CTX_cleanup(&hctx->ctx);
	if (hctx->ktmp.data)
		{
		if (hctx->ktmp.length)
			OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
		OPENSSL_free(hctx->ktmp.data);
		hctx->ktmp.data = NULL;
		}
	OPENSSL_free(hctx);
	}

static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
	ASN1_OCTET_STRING *hkey = NULL;
	HMAC_PKEY_CTX *hctx = ctx->data;
	if (!hctx->ktmp.data)
		return 0;
	hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
	if (!hkey)
		return 0;
	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
	
	return 1;
	}

static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
	{
	HMAC_PKEY_CTX *hctx = ctx->pctx->data;
	HMAC_Update(&hctx->ctx, data, count);
	return 1;
	}

static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
	{
	HMAC_PKEY_CTX *hctx = ctx->data;
	HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT);
	EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
	mctx->update = int_update;
	return 1;
	}

static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
					EVP_MD_CTX *mctx)
	{
	unsigned int hlen;
	HMAC_PKEY_CTX *hctx = ctx->data;
	int l = EVP_MD_CTX_size(mctx);

	if (l < 0)
		return 0;
	*siglen = l;
	if (!sig)
		return 1;

	HMAC_Final(&hctx->ctx, sig, &hlen);
	*siglen = (size_t)hlen;
	return 1;
	}

static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
	{
	HMAC_PKEY_CTX *hctx = ctx->data;
	ASN1_OCTET_STRING *key;
	switch (type)
		{

		case EVP_PKEY_CTRL_SET_MAC_KEY:
		if ((!p2 && p1 > 0) || (p1 < -1))
			return 0;
		if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
			return 0;
		break;

		case EVP_PKEY_CTRL_MD:
		hctx->md = p2;
		break;

		case EVP_PKEY_CTRL_DIGESTINIT:
		key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
		HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
				ctx->engine);
		break;

		default:
		return -2;

		}
	return 1;
	}

static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
			const char *type, const char *value)
	{
	if (!value)
		{
		return 0;
		}
	if (!strcmp(type, "key"))
		{
		void *p = (void *)value;
		return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
				-1, p);
		}
	if (!strcmp(type, "hexkey"))
		{
		unsigned char *key;
		int r;
		long keylen;
		key = string_to_hex(value, &keylen);
		if (!key)
			return 0;
		r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
		OPENSSL_free(key);
		return r;
		}
	return -2;
	}

const EVP_PKEY_METHOD hmac_pkey_meth = 
	{
	EVP_PKEY_HMAC,
	0,
	pkey_hmac_init,
	pkey_hmac_copy,
	pkey_hmac_cleanup,

	0, 0,

	0,
	pkey_hmac_keygen,

	0, 0,

	0, 0,

	0,0,

	hmac_signctx_init,
	hmac_signctx,

	0,0,

	0,0,

	0,0,

	0,0,

	pkey_hmac_ctrl,
	pkey_hmac_ctrl_str

	};
