
/* ****************************************************************************

 * eID Middleware Project.
 * Copyright (C) 2008-2012 FedICT.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version
 * 3.0 as published by the Free Software Foundation.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, see
 * http://www.gnu.org/licenses/.

**************************************************************************** */
#include "bytearray.h"
#include "eiderrors.h"
#include "hash.h"
#include "beid_p11.h"
#include "phash.h"

using namespace eIDMW;

#define WHERE "hash_init()"
int hash_init(CK_MECHANISM_PTR pMechanism, void **pphashinfo,
	      unsigned int *size)
{
	int ret = CKR_OK;
	CHash *oHash = new CHash();
	tHashAlgo algo;

	switch (pMechanism->mechanism)
	{
		case CKM_MD5:
		case CKM_MD5_RSA_PKCS:
			algo = ALGO_MD5;
			*size = 16;
			break;
		case CKM_SHA_1:
		case CKM_SHA1_RSA_PKCS_PSS:
		case CKM_SHA1_RSA_PKCS:
			algo = ALGO_SHA1;
			*size = 20;
			break;
		case CKM_SHA256:
		case CKM_SHA256_RSA_PKCS_PSS:
		case CKM_SHA256_RSA_PKCS:
		case CKM_ECDSA_SHA256:
			algo = ALGO_SHA256;
			*size = 32;
			break;
		case CKM_SHA384:
		case CKM_SHA384_RSA_PKCS:
		case CKM_ECDSA_SHA384:
			algo = ALGO_SHA384;
			*size = 48;
			break;
		case CKM_SHA512:
		case CKM_SHA512_RSA_PKCS:
		case CKM_ECDSA_SHA512:
			algo = ALGO_SHA512;
			*size = 64;
			break;
		case CKM_RIPEMD160:
		case CKM_RIPEMD160_RSA_PKCS:
			algo = ALGO_RIPEMD160;
			*size = 20;
			break;

		default:
			ret = CKR_MECHANISM_INVALID;
			delete oHash;
			goto cleanup;
	}

	oHash->Init(algo);

	*pphashinfo = oHash;

      cleanup:
	return (ret);
}

#undef WHERE



#define WHERE "hash_update()"
int hash_update(void *phashinfo, char *p, unsigned long l)
{
	int ret = CKR_OK;
	CHash *oHash = (CHash *) phashinfo;
	CByteArray data((unsigned char *) p, l);

	oHash->Update(data);

	return (ret);
}

#undef WHERE


#define WHERE "hash_final()"
int hash_final(void *phashinfo, unsigned char *p, unsigned long *l)
{
	int ret = CKR_OK;

	if (phashinfo == NULL)
		return (CKR_FUNCTION_FAILED);

	CHash *oHash = (CHash *) phashinfo;
	CByteArray data;

	data = oHash->GetHash();

	memcpy(p, data.GetBytes(), data.Size());

	*l = data.Size();

	delete(oHash);

	return (ret);
}

#undef WHERE
