/*
 * px-hmac.c
 *		HMAC implementation.
 *
 * Copyright (c) 2001 Marko Kreen
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS 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 AUTHOR OR 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.
 *
 * contrib/pgcrypto/px-hmac.c
 */

#include "postgres.h"

#include "px.h"

#define HMAC_IPAD 0x36
#define HMAC_OPAD 0x5C

static unsigned
hmac_result_size(PX_HMAC *h)
{
	return px_md_result_size(h->md);
}

static unsigned
hmac_block_size(PX_HMAC *h)
{
	return px_md_block_size(h->md);
}

static void
hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen)
{
	unsigned	bs,
				i;
	uint8	   *keybuf;
	PX_MD	   *md = h->md;

	bs = px_md_block_size(md);
	keybuf = px_alloc(bs);
	memset(keybuf, 0, bs);

	if (klen > bs)
	{
		px_md_update(md, key, klen);
		px_md_finish(md, keybuf);
		px_md_reset(md);
	}
	else
		memcpy(keybuf, key, klen);

	for (i = 0; i < bs; i++)
	{
		h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD;
		h->p.opad[i] = keybuf[i] ^ HMAC_OPAD;
	}

	memset(keybuf, 0, bs);
	px_free(keybuf);

	px_md_update(md, h->p.ipad, bs);
}

static void
hmac_reset(PX_HMAC *h)
{
	PX_MD	   *md = h->md;
	unsigned	bs = px_md_block_size(md);

	px_md_reset(md);
	px_md_update(md, h->p.ipad, bs);
}

static void
hmac_update(PX_HMAC *h, const uint8 *data, unsigned dlen)
{
	px_md_update(h->md, data, dlen);
}

static void
hmac_finish(PX_HMAC *h, uint8 *dst)
{
	PX_MD	   *md = h->md;
	unsigned	bs,
				hlen;
	uint8	   *buf;

	bs = px_md_block_size(md);
	hlen = px_md_result_size(md);

	buf = px_alloc(hlen);

	px_md_finish(md, buf);

	px_md_reset(md);
	px_md_update(md, h->p.opad, bs);
	px_md_update(md, buf, hlen);
	px_md_finish(md, dst);

	memset(buf, 0, hlen);
	px_free(buf);
}

static void
hmac_free(PX_HMAC *h)
{
	unsigned	bs;

	bs = px_md_block_size(h->md);
	px_md_free(h->md);

	memset(h->p.ipad, 0, bs);
	memset(h->p.opad, 0, bs);
	px_free(h->p.ipad);
	px_free(h->p.opad);
	px_free(h);
}


/* PUBLIC FUNCTIONS */

int
px_find_hmac(const char *name, PX_HMAC **res)
{
	int			err;
	PX_MD	   *md;
	PX_HMAC    *h;
	unsigned	bs;

	err = px_find_digest(name, &md);
	if (err)
		return err;

	bs = px_md_block_size(md);
	if (bs < 2)
	{
		px_md_free(md);
		return PXE_HASH_UNUSABLE_FOR_HMAC;
	}

	h = px_alloc(sizeof(*h));
	h->p.ipad = px_alloc(bs);
	h->p.opad = px_alloc(bs);
	h->md = md;

	h->result_size = hmac_result_size;
	h->block_size = hmac_block_size;
	h->reset = hmac_reset;
	h->update = hmac_update;
	h->finish = hmac_finish;
	h->free = hmac_free;
	h->init = hmac_init;

	*res = h;

	return 0;
}
