#include "cose/cose.h"
#include "cose/cose_configure.h"
#include "cose_int.h"
#include "cose_crypto.h"

#include <assert.h>
#ifdef __MBED__
#include <string.h>
#else
#include <memory.h>
#endif
#include <stdbool.h>

#ifdef COSE_C_USE_OPENSSL

#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/cmac.h>
#include <openssl/hmac.h>
#include <openssl/ecdsa.h>
#include <openssl/ecdh.h>
#include <openssl/rand.h>
#include <openssl/bn.h>

static bool FUseCompressed = true;

#if (OPENSSL_VERSION_NUMBER < 0x10100000)

HMAC_CTX *HMAC_CTX_new()
{
	HMAC_CTX *foo = (HMAC_CTX *) malloc(sizeof(HMAC_CTX));
	if (foo != nullptr) {
		HMAC_CTX_init(foo);
	}
	return foo;
}

void HMAC_CTX_free(HMAC_CTX *foo)
{
	if (foo != nullptr)
		free(foo);
}

void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
	if (pr != nullptr)
		*pr = sig->r;
	if (ps != nullptr)
		*ps = sig->s;
}

int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
	if (r == nullptr || s == nullptr)
		return 0;
	BN_clear_free(sig->r);
	BN_clear_free(sig->s);
	sig->r = r;
	sig->s = s;
	return 1;
}
#endif

bool AES_CCM_Decrypt(COSE_Enveloped *pcose,
	int TSize,
	int LSize,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbCrypto,
	size_t cbCrypto,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	EVP_CIPHER_CTX *ctx;
	int cbOut;
	byte *rgbOut = nullptr;
	size_t NSize = 15 - (LSize / 8);
	int outl = 0;
	byte rgbIV[15] = {0};
	const cn_cbor *pIV = nullptr;
	const EVP_CIPHER *cipher;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif

	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(ctx != nullptr, COSE_ERR_OUT_OF_MEMORY);

	//  Setup the IV/Nonce and put it into the message

	pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, nullptr);
	if ((pIV == nullptr) || (pIV->type != CN_CBOR_BYTES)) {
		if (perr != nullptr) {
			perr->err = COSE_ERR_INVALID_PARAMETER;
		}

	errorReturn:
		if (rgbOut != nullptr) {
			COSE_FREE(rgbOut, context);
		}
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	CHECK_CONDITION(pIV->length == NSize, COSE_ERR_INVALID_PARAMETER);
	memcpy(rgbIV, pIV->v.str, pIV->length);

	//  Setup and run the OpenSSL code

	switch (cbKey) {
		case 128 / 8:
			cipher = EVP_aes_128_ccm();
			break;

		case 192 / 8:
			cipher = EVP_aes_192_ccm();
			break;

		case 256 / 8:
			cipher = EVP_aes_256_ccm();
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
			break;
	}
	CHECK_CONDITION(EVP_DecryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr),
		COSE_ERR_DECRYPT_FAILED);

	TSize /= 8;	 // Comes in in bits not bytes.
	CHECK_CONDITION(
		EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (LSize / 8), 0),
		COSE_ERR_DECRYPT_FAILED);
	// CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, NSize,
	// 0), COSE_ERR_DECRYPT_FAILED);
	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, TSize,
						(void *)&pbCrypto[cbCrypto - TSize]),
		COSE_ERR_DECRYPT_FAILED);

	CHECK_CONDITION(EVP_DecryptInit_ex(ctx, 0, nullptr, pbKey, rgbIV),
		COSE_ERR_DECRYPT_FAILED);

	CHECK_CONDITION(
		EVP_DecryptUpdate(ctx, nullptr, &cbOut, nullptr, (int)cbCrypto - TSize),
		COSE_ERR_DECRYPT_FAILED);

	cbOut = (int)cbCrypto - TSize;
	rgbOut = (byte *)COSE_CALLOC(cbOut, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(
		EVP_DecryptUpdate(ctx, nullptr, &outl, pbAuthData, (int)cbAuthData),
		COSE_ERR_DECRYPT_FAILED);

	CHECK_CONDITION(
		EVP_DecryptUpdate(ctx, rgbOut, &cbOut, pbCrypto, (int)cbCrypto - TSize),
		COSE_ERR_DECRYPT_FAILED);

	EVP_CIPHER_CTX_free(ctx);

	pcose->pbContent = rgbOut;
	pcose->cbContent = cbOut;

	return true;
}

bool AES_CCM_Encrypt(COSE_Enveloped *pcose,
	int TSize,
	int LSize,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	EVP_CIPHER_CTX *ctx;
	int cbOut;
	byte *rgbOut = nullptr;
	size_t NSize = 15 - (LSize / 8);
	int outl = 0;
	const cn_cbor *cbor_iv = nullptr;
	cn_cbor *cbor_iv_t = nullptr;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif
	cn_cbor *cnTmp = nullptr;
	const EVP_CIPHER *cipher;
	byte rgbIV[16];
	byte *pbIV = nullptr;
	cn_cbor_errback cbor_error;

	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);

	switch (cbKey * 8) {
		case 128:
			cipher = EVP_aes_128_ccm();
			break;

		case 192:
			cipher = EVP_aes_192_ccm();
			break;

		case 256:
			cipher = EVP_aes_256_ccm();
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	//  Setup the IV/Nonce and put it into the message

	cbor_iv =
		_COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, perr);
	if (cbor_iv == nullptr) {
		pbIV = (byte *) COSE_CALLOC(NSize, 1, context);
		CHECK_CONDITION(pbIV != nullptr, COSE_ERR_OUT_OF_MEMORY);
		rand_bytes(pbIV, NSize);
		memcpy(rgbIV, pbIV, NSize);
		cbor_iv_t = cn_cbor_data_create2(
			pbIV, NSize, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(cbor_iv_t != nullptr, cbor_error);
		pbIV = nullptr;

		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t,
				COSE_UNPROTECT_ONLY, perr)) {
			goto errorReturn;
		}
		cbor_iv_t = nullptr;
	}
	else {
		CHECK_CONDITION(
			cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION(cbor_iv->length == NSize, COSE_ERR_INVALID_PARAMETER);
		memcpy(rgbIV, cbor_iv->v.str, cbor_iv->length);
	}

	//  Setup and run the OpenSSL code

	CHECK_CONDITION(EVP_EncryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr),
		COSE_ERR_CRYPTO_FAIL);

	TSize /= 8;	 // Comes in in bits not bytes.
	CHECK_CONDITION(
		EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (LSize / 8), 0),
		COSE_ERR_CRYPTO_FAIL);
	// CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, NSize,
	// 0), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, TSize, nullptr),
		COSE_ERR_CRYPTO_FAIL);	// Say we are doing an 8 byte tag

	CHECK_CONDITION(
		EVP_EncryptInit_ex(ctx, 0, nullptr, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(EVP_EncryptUpdate(ctx, 0, &cbOut, 0, (int)pcose->cbContent),
		COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(
		EVP_EncryptUpdate(ctx, nullptr, &outl, pbAuthData, (int)cbAuthData),
		COSE_ERR_CRYPTO_FAIL);

	rgbOut = (byte *)COSE_CALLOC(cbOut + TSize, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(EVP_EncryptUpdate(ctx, rgbOut, &cbOut, pcose->pbContent,
						(int)pcose->cbContent),
		COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(
		EVP_EncryptFinal_ex(ctx, &rgbOut[cbOut], &cbOut), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, TSize,
						&rgbOut[pcose->cbContent]),
		COSE_ERR_CRYPTO_FAIL);

	cnTmp = cn_cbor_data_create2(
		rgbOut, (int)pcose->cbContent + TSize, 0, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_CONDITION(cnTmp != nullptr, COSE_ERR_CBOR);
	rgbOut = nullptr;

	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cnTmp, INDEX_BODY,
						CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_CBOR);
	cnTmp = nullptr;
	EVP_CIPHER_CTX_free(ctx);
	return true;

errorReturn:
	if (pbIV != nullptr) {
		COSE_FREE(pbIV, context);
	}
	if (cbor_iv_t != nullptr) {
		COSE_FREE(cbor_iv_t, context);
	}
	if (rgbOut != nullptr) {
		COSE_FREE(rgbOut, context);
	}
	if (cnTmp != nullptr) {
		COSE_FREE(cnTmp, context);
	}
	EVP_CIPHER_CTX_free(ctx);
	return false;
}

bool AES_GCM_Decrypt(COSE_Enveloped *pcose,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbCrypto,
	size_t cbCrypto,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	EVP_CIPHER_CTX *ctx;
	int cbOut;
	byte *rgbOut = nullptr;
	int outl = 0;
	byte rgbIV[15] = {0};
	const cn_cbor *pIV = nullptr;
	const EVP_CIPHER *cipher;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif
	int TSize = 128 / 8;

	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);

	//  Setup the IV/Nonce and put it into the message

	pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, nullptr);
	if ((pIV == nullptr) || (pIV->type != CN_CBOR_BYTES)) {
		if (perr != nullptr) {
			perr->err = COSE_ERR_INVALID_PARAMETER;
		}

	errorReturn:
		if (rgbOut != nullptr) {
			COSE_FREE(rgbOut, context);
		}
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	CHECK_CONDITION(pIV->length == 96 / 8, COSE_ERR_INVALID_PARAMETER);
	memcpy(rgbIV, pIV->v.str, pIV->length);

	//  Setup and run the OpenSSL code

	switch (cbKey) {
		case 128 / 8:
			cipher = EVP_aes_128_gcm();
			break;

		case 192 / 8:
			cipher = EVP_aes_192_gcm();
			break;

		case 256 / 8:
			cipher = EVP_aes_256_gcm();
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
			break;
	}

	//  Do the setup for OpenSSL

	CHECK_CONDITION(EVP_DecryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr),
		COSE_ERR_DECRYPT_FAILED);

	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, TSize,
						(void *)&pbCrypto[cbCrypto - TSize]),
		COSE_ERR_DECRYPT_FAILED);

	CHECK_CONDITION(EVP_DecryptInit_ex(ctx, 0, nullptr, pbKey, rgbIV),
		COSE_ERR_DECRYPT_FAILED);

	//  Pus in the AAD

	CHECK_CONDITION(
		EVP_DecryptUpdate(ctx, nullptr, &outl, pbAuthData, (int)cbAuthData),
		COSE_ERR_DECRYPT_FAILED);

	//

	cbOut = (int)cbCrypto - TSize;
	rgbOut = (byte *)COSE_CALLOC(cbOut, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	//  Process content

	CHECK_CONDITION(
		EVP_DecryptUpdate(ctx, rgbOut, &cbOut, pbCrypto, (int)cbCrypto - TSize),
		COSE_ERR_DECRYPT_FAILED);

	//  Process Tag

	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TSize,
						(byte *)pbCrypto + cbCrypto - TSize),
		COSE_ERR_DECRYPT_FAILED);

	//  Check the result

	CHECK_CONDITION(
		EVP_DecryptFinal(ctx, rgbOut + cbOut, &cbOut), COSE_ERR_DECRYPT_FAILED);

	EVP_CIPHER_CTX_free(ctx);

	pcose->pbContent = rgbOut;
	pcose->cbContent = cbOut;

	return true;
}

bool AES_GCM_Encrypt(COSE_Enveloped *pcose,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	EVP_CIPHER_CTX *ctx;
	int cbOut;
	byte *rgbOut = nullptr;
	int outl = 0;
	byte rgbIV[16] = {0};
	byte *pbIV = nullptr;
	const cn_cbor *cbor_iv = nullptr;
	cn_cbor *cbor_iv_t = nullptr;
	const EVP_CIPHER *cipher;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif
	cn_cbor_errback cbor_error;

	if (false) {
	errorReturn:
		if (pbIV != nullptr) {
			COSE_FREE(pbIV, context);
		}
		if (cbor_iv_t != nullptr) {
			COSE_FREE(cbor_iv_t, context);
		}
		if (rgbOut != nullptr) {
			COSE_FREE(rgbOut, context);
		}
		EVP_CIPHER_CTX_free(ctx);
		return false;		
	}
	
	// Make it first so we can clean it up
	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);

	//  Setup the IV/Nonce and put it into the message

	cbor_iv =
		_COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, perr);
	if (cbor_iv == nullptr) {
		pbIV = (byte *) COSE_CALLOC(96, 1, context);
		CHECK_CONDITION(pbIV != nullptr, COSE_ERR_OUT_OF_MEMORY);
		rand_bytes(pbIV, 96 / 8);
		memcpy(rgbIV, pbIV, 96 / 8);
		cbor_iv_t = cn_cbor_data_create2(
			pbIV, 96 / 8, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(cbor_iv_t != nullptr, cbor_error);
		pbIV = nullptr;

		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t,
				COSE_UNPROTECT_ONLY, perr)) {
			goto errorReturn;
		}
		cbor_iv_t = nullptr;
	}
	else {
		CHECK_CONDITION(
			cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION(cbor_iv->length == 96 / 8, COSE_ERR_INVALID_PARAMETER);
		memcpy(rgbIV, cbor_iv->v.str, cbor_iv->length);
	}

	switch (cbKey * 8) {
		case 128:
			cipher = EVP_aes_128_gcm();
			break;

		case 192:
			cipher = EVP_aes_192_gcm();
			break;

		case 256:
			cipher = EVP_aes_256_gcm();
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
			break;
	}

	//  Setup and run the OpenSSL code

	CHECK_CONDITION(EVP_EncryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr),
		COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(
		EVP_EncryptInit_ex(ctx, 0, nullptr, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(
		EVP_EncryptUpdate(ctx, nullptr, &outl, pbAuthData, (int)cbAuthData),
		COSE_ERR_CRYPTO_FAIL);

	rgbOut = (byte *)COSE_CALLOC(pcose->cbContent + 128 / 8, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(EVP_EncryptUpdate(ctx, rgbOut, &cbOut, pcose->pbContent,
						(int)pcose->cbContent),
		COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(
		EVP_EncryptFinal_ex(ctx, &rgbOut[cbOut], &cbOut), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 128 / 8,
						&rgbOut[pcose->cbContent]),
		COSE_ERR_CRYPTO_FAIL);

	cn_cbor *cnTmp = cn_cbor_data_create2(
		rgbOut, (int)pcose->cbContent + 128 / 8, 0, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_CONDITION(cnTmp != nullptr, COSE_ERR_CBOR);
	rgbOut = nullptr;
	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cnTmp, INDEX_BODY,
						CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_CBOR);

	EVP_CIPHER_CTX_free(ctx);

	if (pbIV != nullptr) {
		COSE_FREE(pbIV, context);
	}
	return true;
}

bool AES_CBC_MAC_Create(COSE_MacMessage *pcose,
	int TSize,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	const EVP_CIPHER *pcipher = nullptr;
	EVP_CIPHER_CTX *ctx;
	int cbOut;
	byte rgbIV[16] = {0};
	byte *rgbOut = nullptr;
	bool f = false;
	unsigned int i;
	cn_cbor *cn = nullptr;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif

	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);

	rgbOut = (byte *) COSE_CALLOC(16, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	switch (cbKey * 8) {
		case 128:
			pcipher = EVP_aes_128_cbc();
			break;

		case 256:
			pcipher = EVP_aes_256_cbc();
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	//  Setup and run the OpenSSL code

	CHECK_CONDITION(EVP_EncryptInit_ex(ctx, pcipher, nullptr, pbKey, rgbIV),
		COSE_ERR_CRYPTO_FAIL);

	for (i = 0; i < (unsigned int)cbAuthData / 16; i++) {
		CHECK_CONDITION(
			EVP_EncryptUpdate(ctx, rgbOut, &cbOut, pbAuthData + (i * 16), 16),
			COSE_ERR_CRYPTO_FAIL);
	}
	if (cbAuthData % 16 != 0) {
		CHECK_CONDITION(EVP_EncryptUpdate(ctx, rgbOut, &cbOut,
							pbAuthData + (i * 16), cbAuthData % 16),
			COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(EVP_EncryptUpdate(
							ctx, rgbOut, &cbOut, rgbIV, 16 - (cbAuthData % 16)),
			COSE_ERR_CRYPTO_FAIL);
	}

	cn = cn_cbor_data_create2(rgbOut, TSize / 8, 0, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_CONDITION(cn != nullptr, COSE_ERR_OUT_OF_MEMORY);
	rgbOut = nullptr;

	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cn, INDEX_MAC_TAG,
						CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_CBOR);
	cn = nullptr;

	EVP_CIPHER_CTX_free(ctx);
	return !f;

errorReturn:
	if (rgbOut != nullptr) {
		COSE_FREE(rgbOut, context);
	}
	if (cn != nullptr) {
		CN_CBOR_FREE(cn, context);
	}
	EVP_CIPHER_CTX_free(ctx);
	return false;
}

bool AES_CBC_MAC_Validate(COSE_MacMessage *pcose,
	int TSize,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	const EVP_CIPHER *pcipher = nullptr;
	EVP_CIPHER_CTX *ctx = nullptr;
	int cbOut;
	byte rgbIV[16] = {0};
	byte rgbTag[16] = {0};
	bool f = false;
	unsigned int i;

	if (false) {
	errorReturn:
		EVP_CIPHER_CTX_free(ctx);
		return false;		
	}
	switch (cbKey * 8) {
		case 128:
			pcipher = EVP_aes_128_cbc();
			break;

		case 256:
			pcipher = EVP_aes_256_cbc();
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	//  Setup and run the OpenSSL code

	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(EVP_EncryptInit_ex(ctx, pcipher, nullptr, pbKey, rgbIV),
		COSE_ERR_CRYPTO_FAIL);

	TSize /= 8;

	for (i = 0; i < (unsigned int)cbAuthData / 16; i++) {
		CHECK_CONDITION(
			EVP_EncryptUpdate(ctx, rgbTag, &cbOut, pbAuthData + (i * 16), 16),
			COSE_ERR_CRYPTO_FAIL);
	}
	if (cbAuthData % 16 != 0) {
		CHECK_CONDITION(EVP_EncryptUpdate(ctx, rgbTag, &cbOut,
							pbAuthData + (i * 16), cbAuthData % 16),
			COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(EVP_EncryptUpdate(
							ctx, rgbTag, &cbOut, rgbIV, 16 - (cbAuthData % 16)),
			COSE_ERR_CRYPTO_FAIL);
	}

	cn_cbor *cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != nullptr, COSE_ERR_CBOR);

	for (i = 0; i < (unsigned int)TSize; i++) {
		f |= (cn->v.bytes[i] != rgbTag[i]);
	}

	EVP_CIPHER_CTX_free(ctx);
	return !f;
}

#if 0
//  We are doing CBC-MAC not CMAC at this time
bool AES_CMAC_Validate(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
{
	CMAC_CTX * pctx = nullptr;
	const EVP_CIPHER * pcipher = nullptr;
	byte * rgbOut = nullptr;
	size_t cbOut;
	bool f = false;
	unsigned int i;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	pctx = CMAC_CTX_new();


	switch (KeySize) {
	case 128: pcipher = EVP_aes_128_cbc(); break;
	case 256: pcipher = EVP_aes_256_cbc(); break;
	default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
	}

	rgbOut = COSE_CALLOC(128/8, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(CMAC_Init(pctx, pcose->pbKey, pcose->cbKey, pcipher, nullptr /*impl*/) == 1, COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(CMAC_Update(pctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(CMAC_Final(pctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);

	cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != nullptr, COSE_ERR_CBOR);

	for (i = 0; i < (unsigned int)TagSize / 8; i++) f |= (cn->v.bytes[i] != rgbOut[i]);

	COSE_FREE(rgbOut, context);
	CMAC_CTX_cleanup(pctx);
	CMAC_CTX_free(pctx);
	return !f;

errorReturn:
	COSE_FREE(rgbOut, context);
	CMAC_CTX_cleanup(pctx);
	CMAC_CTX_free(pctx);
	return false;

}
#endif

bool HKDF_AES_Expand(COSE *pcose,
	size_t cbitKey,
	const byte *pbPRK,
	size_t cbPRK,
	const byte *pbInfo,
	size_t cbInfo,
	byte *pbOutput,
	size_t cbOutput,
	cose_errback *perr)
{
	const EVP_CIPHER *pcipher = nullptr;
	EVP_CIPHER_CTX *ctx;
	int cbOut;
	byte rgbIV[16] = {0};
	byte bCount = 1;
	size_t ib;
	byte rgbDigest[128 / 8];
	int cbDigest = 0;
	byte rgbOut[16];

	UNUSED(pcose);

	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);

	switch (cbitKey) {
		case 128:
			pcipher = EVP_aes_128_cbc();
			break;

		case 256:
			pcipher = EVP_aes_256_cbc();
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	CHECK_CONDITION(cbPRK == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);

	//  Setup and run the OpenSSL code

	for (ib = 0; ib < cbOutput; ib += 16, bCount += 1) {
		size_t ib2;

		CHECK_CONDITION(EVP_EncryptInit_ex(ctx, pcipher, nullptr, pbPRK, rgbIV),
			COSE_ERR_CRYPTO_FAIL);

		CHECK_CONDITION(
			EVP_EncryptUpdate(ctx, rgbOut, &cbOut, rgbDigest, cbDigest),
			COSE_ERR_CRYPTO_FAIL);
		for (ib2 = 0; ib2 < cbInfo; ib2 += 16) {
			CHECK_CONDITION(EVP_EncryptUpdate(ctx, rgbOut, &cbOut, pbInfo + ib2,
								(int)COSE_MIN(16, cbInfo - ib2)),
				COSE_ERR_CRYPTO_FAIL);
		}
		CHECK_CONDITION(EVP_EncryptUpdate(ctx, rgbOut, &cbOut, &bCount, 1),
			COSE_ERR_CRYPTO_FAIL);
		if ((cbInfo + 1) % 16 != 0) {
			CHECK_CONDITION(EVP_EncryptUpdate(ctx, rgbOut, &cbOut, rgbIV,
								(int)16 - (cbInfo + 1) % 16),
				COSE_ERR_CRYPTO_FAIL);
		}
		memcpy(rgbDigest, rgbOut, cbOut);
		cbDigest = cbOut;
		memcpy(pbOutput + ib, rgbDigest, COSE_MIN(16, cbOutput - ib));
	}

	EVP_CIPHER_CTX_free(ctx);
	return true;

errorReturn:
	EVP_CIPHER_CTX_free(ctx);
	return false;
}

bool HKDF_Extract(COSE *pcose,
	const byte *pbKey,
	size_t cbKey,
	size_t cbitDigest,
	byte *rgbDigest,
	size_t *pcbDigest,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
#ifdef USE_CBOR_CONTEXT
	UNUSED(context);
#endif
	byte rgbSalt[EVP_MAX_MD_SIZE] = {0};
	int cbSalt;
	cn_cbor *cnSalt;
	HMAC_CTX *ctx;
	const EVP_MD *pmd = nullptr;
	unsigned int cbDigest;

	ctx = HMAC_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);

	if (0) {
	errorReturn:
		HMAC_CTX_free(ctx);
		return false;
	}

	switch (cbitDigest) {
		case 256:
			pmd = EVP_sha256();
			cbSalt = 256 / 8;
			break;
		case 384:
			pmd = EVP_sha384();
			cbSalt = 384 / 8;
			break;
		case 512:
			pmd = EVP_sha512();
			cbSalt = 512 / 8;
			break;
		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
			break;
	}

	cnSalt = _COSE_map_get_int(pcose, COSE_Header_HKDF_salt, COSE_BOTH, perr);

	if (cnSalt != nullptr) {
		CHECK_CONDITION(
			HMAC_Init_ex(ctx, cnSalt->v.bytes, (int)cnSalt->length, pmd, nullptr),
			COSE_ERR_CRYPTO_FAIL);
	}
	else {
		CHECK_CONDITION(HMAC_Init_ex(ctx, rgbSalt, cbSalt, pmd, nullptr),
			COSE_ERR_CRYPTO_FAIL);
	}
	CHECK_CONDITION(HMAC_Update(ctx, pbKey, (int)cbKey), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(
		HMAC_Final(ctx, rgbDigest, &cbDigest), COSE_ERR_CRYPTO_FAIL);
	*pcbDigest = cbDigest;
	HMAC_CTX_free(ctx);
	return true;
}

bool HKDF_Expand(COSE *pcose,
	size_t cbitDigest,
	const byte *pbPRK,
	size_t cbPRK,
	const byte *pbInfo,
	size_t cbInfo,
	byte *pbOutput,
	size_t cbOutput,
	cose_errback *perr)
{
	HMAC_CTX *ctx;
	const EVP_MD *pmd = nullptr;
	size_t ib;
	unsigned int cbDigest = 0;
	byte rgbDigest[EVP_MAX_MD_SIZE];
	byte bCount = 1;

	UNUSED(pcose);

	ctx = HMAC_CTX_new();
	CHECK_CONDITION(ctx != nullptr, COSE_ERR_OUT_OF_MEMORY);

	if (0) {
	errorReturn:
		HMAC_CTX_free(ctx);
		return false;
	}

	switch (cbitDigest) {
		case 256:
			pmd = EVP_sha256();
			break;
		case 384:
			pmd = EVP_sha384();
			break;
		case 512:
			pmd = EVP_sha512();
			break;
		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
			break;
	}

	for (ib = 0; ib < cbOutput; ib += cbDigest, bCount += 1) {
		CHECK_CONDITION(HMAC_Init_ex(ctx, pbPRK, (int)cbPRK, pmd, nullptr),
			COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(
			HMAC_Update(ctx, rgbDigest, cbDigest), COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(HMAC_Update(ctx, pbInfo, cbInfo), COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(HMAC_Update(ctx, &bCount, 1), COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(
			HMAC_Final(ctx, rgbDigest, &cbDigest), COSE_ERR_CRYPTO_FAIL);

		memcpy(pbOutput + ib, rgbDigest, COSE_MIN(cbDigest, cbOutput - ib));
	}

	HMAC_CTX_free(ctx);
	return true;
}

bool HMAC_Create(COSE_MacMessage *pcose,
	int HSize,
	int TSize,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	HMAC_CTX *ctx;
	const EVP_MD *pmd = nullptr;
	byte *rgbOut = nullptr;
	unsigned int cbOut;
	cn_cbor *cbor = nullptr;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif

	ctx = HMAC_CTX_new();
	CHECK_CONDITION(nullptr != ctx, COSE_ERR_OUT_OF_MEMORY);

	if (0) {
	errorReturn:
		COSE_FREE(rgbOut, context);
		if (cbor != nullptr) {
			COSE_FREE(cbor, context);
		}
		HMAC_CTX_free(ctx);
		return false;
	}

	switch (HSize) {
		case 256:
			pmd = EVP_sha256();
			break;
		case 384:
			pmd = EVP_sha384();
			break;
		case 512:
			pmd = EVP_sha512();
			break;
		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
			break;
	}

	rgbOut = (byte *) COSE_CALLOC(EVP_MAX_MD_SIZE, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(
		HMAC_Init_ex(ctx, pbKey, (int)cbKey, pmd, nullptr), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(
		HMAC_Update(ctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(HMAC_Final(ctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);

cbor =							cn_cbor_data_create2(rgbOut, TSize / 8, 0, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_CONDITION(cbor != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cbor,
						INDEX_MAC_TAG, CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_CBOR);

	HMAC_CTX_free(ctx);
	return true;
}

bool HMAC_Validate(COSE_MacMessage *pcose,
	int HSize,
	int TSize,
	const byte *pbKey,
	size_t cbKey,
	const byte *pbAuthData,
	size_t cbAuthData,
	cose_errback *perr)
{
	HMAC_CTX *ctx = nullptr;
	const EVP_MD *pmd = nullptr;
	byte *rgbOut = nullptr;
	unsigned int cbOut = 0 ;
	bool f = false;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif

	if (false) {
	errorReturn:
		if (rgbOut != nullptr) {
			COSE_FREE(rgbOut, context);
		}
		HMAC_CTX_free(ctx);
		return false;		
	}
	ctx = HMAC_CTX_new();
	CHECK_CONDITION(ctx != nullptr, COSE_ERR_OUT_OF_MEMORY);

	switch (HSize) {
		case 256:
			pmd = EVP_sha256();
			break;
		case 384:
			pmd = EVP_sha384();
			break;
		case 512:
			pmd = EVP_sha512();
			break;
		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
			break;
	}

	rgbOut = (byte *) COSE_CALLOC(EVP_MAX_MD_SIZE, 1, context);
	CHECK_CONDITION(rgbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(
		HMAC_Init_ex(ctx, pbKey, (int)cbKey, pmd, nullptr), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(
		HMAC_Update(ctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(HMAC_Final(ctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);

	cn_cbor *cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != nullptr, COSE_ERR_CBOR);

	if (cn->length > cbOut) {
		return false;
	}
	for (unsigned int i = 0; i < (unsigned int)TSize / 8; i++) {
		f |= (cn->v.bytes[i] != rgbOut[i]);
	}

	COSE_FREE(rgbOut, context);
	HMAC_CTX_free(ctx);
	return !f;
}

#define COSE_Key_EC_Curve -1
#define COSE_Key_EC_X -2
#define COSE_Key_EC_Y -3
#define COSE_Key_EC_d -4

EC_KEY *ECKey_From(COSE_KEY *pKey, int *cbGroup, cose_errback *perr)
{
	EC_KEY *pNewKey = nullptr;

	if (false) {
	errorReturn:
		if (pNewKey != nullptr) {
			EC_KEY_free(pNewKey);
		}
		return nullptr;		
	}

	if (pKey->m_opensslKey != nullptr) {
		EC_KEY *pKeyNew = EVP_PKEY_get1_EC_KEY(pKey->m_opensslKey);
		CHECK_CONDITION(pKeyNew != nullptr, COSE_ERR_INVALID_PARAMETER);
		return pKeyNew;
	}
	
	byte rgbKey[512 + 1];
	int cbKey;
	const cn_cbor *p;
	int nidGroup = -1;
	EC_POINT *pPoint = nullptr;

	pNewKey = EC_KEY_new();
	CHECK_CONDITION(pNewKey != nullptr, COSE_ERR_OUT_OF_MEMORY);
	
	p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_EC_Curve);
	CHECK_CONDITION(p != nullptr, COSE_ERR_INVALID_PARAMETER);

	switch (p->v.sint) {
		case 1:	 // P-256
			nidGroup = NID_X9_62_prime256v1;
			*cbGroup = 256 / 8;
			break;

		case 2:	 // P-384
			nidGroup = NID_secp384r1;
			*cbGroup = 384 / 8;
			break;

		case 3:	 // P-521
			nidGroup = NID_secp521r1;
			*cbGroup = (521 + 7) / 8;
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	EC_GROUP *ecgroup = EC_GROUP_new_by_curve_name(nidGroup);
	CHECK_CONDITION(ecgroup != nullptr, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(
		EC_KEY_set_group(pNewKey, ecgroup) == 1, COSE_ERR_CRYPTO_FAIL);

	p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_EC_X);
	CHECK_CONDITION(
		(p != nullptr) && (p->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(p->length == (size_t)*cbGroup, COSE_ERR_INVALID_PARAMETER);
	memcpy(rgbKey + 1, p->v.str, p->length);

	p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_EC_Y);
	CHECK_CONDITION((p != nullptr), COSE_ERR_INVALID_PARAMETER);
	if (p->type == CN_CBOR_BYTES) {
		rgbKey[0] = POINT_CONVERSION_UNCOMPRESSED;
		cbKey = (*cbGroup * 2) + 1;
		CHECK_CONDITION(p->length == (size_t)*cbGroup, COSE_ERR_INVALID_PARAMETER);
		memcpy(rgbKey + p->length + 1, p->v.str, p->length);
	}
	else if (p->type == CN_CBOR_TRUE) {
		cbKey = (*cbGroup) + 1;
		rgbKey[0] = POINT_CONVERSION_COMPRESSED + 1;
	}
	else if (p->type == CN_CBOR_FALSE) {
		cbKey = (*cbGroup) + 1;
		rgbKey[0] = POINT_CONVERSION_COMPRESSED;
	}
	else
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);

	pPoint = EC_POINT_new(ecgroup);
	CHECK_CONDITION(pPoint != nullptr, COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(
		EC_POINT_oct2point(ecgroup, pPoint, rgbKey, cbKey, nullptr) == 1,
		COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(
		EC_KEY_set_public_key(pNewKey, pPoint) == 1, COSE_ERR_CRYPTO_FAIL);

	p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_EC_d);
	if (p != nullptr) {
		BIGNUM *pbn;

		pbn = BN_bin2bn(p->v.bytes, (int)p->length, nullptr);
		CHECK_CONDITION(pbn != nullptr, COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(
			EC_KEY_set_private_key(pNewKey, pbn) == 1, COSE_ERR_CRYPTO_FAIL);
	}

	pKey->m_opensslKey = EVP_PKEY_new();
	CHECK_CONDITION(pKey->m_opensslKey != nullptr, COSE_ERR_OUT_OF_MEMORY);
	
	CHECK_CONDITION(EVP_PKEY_set1_EC_KEY(pKey->m_opensslKey, pNewKey) == 1, COSE_ERR_CRYPTO_FAIL);

	return pNewKey;
}

COSE_KEY *EC_FromKey(const EC_KEY *pKey, CBOR_CONTEXT_COMMA cose_errback *perr)
{
	cn_cbor *pkey = nullptr;
	const EC_GROUP *pgroup;
	int cose_group;
	cn_cbor *p = nullptr;
	cn_cbor_errback cbor_error;
	const EC_POINT *pPoint;
	byte *pbPoint = nullptr;
	size_t cbSize;
	byte *pbOut = nullptr;
	COSE_KEY *coseKey = nullptr;

	pgroup = EC_KEY_get0_group(pKey);
	CHECK_CONDITION(pgroup != nullptr, COSE_ERR_INVALID_PARAMETER);

	switch (EC_GROUP_get_curve_name(pgroup)) {
		case NID_X9_62_prime256v1:
			cose_group = 1;
			break;
		case NID_secp384r1:
			cose_group = 2;
			break;
		case NID_secp521r1:
			cose_group = 3;
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	pkey = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(pkey != nullptr, cbor_error);

	p = cn_cbor_int_create(cose_group, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(p != nullptr, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Curve, p,
							 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
		cbor_error);
	p = nullptr;

	pPoint = EC_KEY_get0_public_key(pKey);
	CHECK_CONDITION(pPoint != nullptr, COSE_ERR_INVALID_PARAMETER);

	if (FUseCompressed) {
		cbSize = EC_POINT_point2oct(
			pgroup, pPoint, POINT_CONVERSION_COMPRESSED, nullptr, 0, nullptr);
		CHECK_CONDITION(cbSize > 0, COSE_ERR_CRYPTO_FAIL);
		pbPoint = (byte *) COSE_CALLOC(cbSize, 1, context);
		CHECK_CONDITION(pbPoint != nullptr, COSE_ERR_OUT_OF_MEMORY);
		CHECK_CONDITION(
			EC_POINT_point2oct(pgroup, pPoint, POINT_CONVERSION_COMPRESSED,
				pbPoint, cbSize, nullptr) == cbSize,
			COSE_ERR_CRYPTO_FAIL);
	}
	else {
		cbSize = EC_POINT_point2oct(
			pgroup, pPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
		CHECK_CONDITION(cbSize > 0, COSE_ERR_CRYPTO_FAIL);
		pbPoint = (byte *) COSE_CALLOC(cbSize, 1, context);
		CHECK_CONDITION(pbPoint != nullptr, COSE_ERR_OUT_OF_MEMORY);
		CHECK_CONDITION(
			EC_POINT_point2oct(pgroup, pPoint, POINT_CONVERSION_UNCOMPRESSED,
				pbPoint, cbSize, nullptr) == cbSize,
			COSE_ERR_CRYPTO_FAIL);
	}

	pbOut = (byte *) COSE_CALLOC((int)(cbSize / 2), 1, context);
	CHECK_CONDITION(pbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);
	memcpy(pbOut, pbPoint + 1, (int)(cbSize / 2));
	p = cn_cbor_data_create2(
		pbOut, (int)(cbSize / 2), 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(p != nullptr, cbor_error);
	pbOut = nullptr;
	CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_X, p,
							 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
		cbor_error);
	p = nullptr;

	if (FUseCompressed) {
		p = cn_cbor_bool_create(
			pbPoint[0] & 1, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(p != nullptr, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Y, p,
								 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
			cbor_error);
		p = nullptr;
	}
	else {
		pbOut = (byte *) COSE_CALLOC((int)(cbSize / 2), 1, context);
		CHECK_CONDITION(pbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);
		memcpy(pbOut, pbPoint + cbSize / 2 + 1, (int)(cbSize / 2));
		p = cn_cbor_data_create2(pbOut, (int)(cbSize / 2), 0,
			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(p != nullptr, cbor_error);
		pbOut = nullptr; 
		CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Y, p,
								 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
			cbor_error);
		p = nullptr;
	}

	p = cn_cbor_int_create(
		COSE_Key_Type_EC2, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(p != nullptr, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_Type, p,
							 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
		cbor_error);
	p = nullptr;

	coseKey = (COSE_KEY*) COSE_KEY_FromCbor(pkey, CBOR_CONTEXT_PARAM_COMMA perr);
	CHECK_CONDITION(coseKey != nullptr, COSE_ERR_OUT_OF_MEMORY);
	pkey = nullptr;

returnHere:
	if (pbPoint != nullptr) {
		COSE_FREE(pbPoint, context);
	}
	if (pbOut != nullptr) {
		COSE_FREE(pbOut, context);
	}
	if (p != nullptr) {
		CN_CBOR_FREE(p, context);
	}
	return coseKey;

errorReturn:
	CN_CBOR_FREE(pkey, context);
	pkey = nullptr;
	goto returnHere;
}

/*
bool ECDSA_Sign(const cn_cbor * pKey)
{
	byte * digest = nullptr;
	int digestLen = 0;
	ECDSA_SIG * sig;

	EC_KEY * eckey = ECKey_From(pKey);

	sig = ECDSA_do_sign(digest, digestLen, eckey);

	return true;
}
*/

bool ECDSA_Sign(COSE *pSigner,
	int index,
	COSE_KEY *pKey,
	int cbitDigest,
	const byte *rgbToSign,
	size_t cbToSign,
	cose_errback *perr)
{
	EC_KEY *eckey = nullptr;
	byte rgbDigest[EVP_MAX_MD_SIZE];
	unsigned int cbDigest = sizeof(rgbDigest);
	byte *pbSig = nullptr;
	const EVP_MD *digest;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pSigner->m_allocContext;
#endif
	cn_cbor *p = nullptr;
	ECDSA_SIG *psig = nullptr;
	cn_cbor_errback cbor_error;
	int cbR;
	byte rgbSig[66];
	int cb;

	eckey = ECKey_From(pKey, &cbR, perr);
	if (eckey == nullptr) {
	errorReturn:
		if (pbSig != nullptr) {
			COSE_FREE(pbSig, context);
		}
		if (p != nullptr) {
			CN_CBOR_FREE(p, context);
		}
		if (eckey != nullptr) {
			EC_KEY_free(eckey);
		}
		return false;
	}

	switch (cbitDigest) {
		case 256:
			digest = EVP_sha256();
			break;
		case 512:
			digest = EVP_sha512();
			break;
		case 384:
			digest = EVP_sha384();
			break;
		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, nullptr);

	psig = ECDSA_do_sign(rgbDigest, cbDigest, eckey);
	CHECK_CONDITION(psig != nullptr, COSE_ERR_CRYPTO_FAIL);

	pbSig = (byte *) COSE_CALLOC(cbR, 2, context);
	CHECK_CONDITION(pbSig != nullptr, COSE_ERR_OUT_OF_MEMORY);

	const BIGNUM *r;
	const BIGNUM *s;
	ECDSA_SIG_get0(psig, &r, &s);
	cb = BN_bn2bin(r, rgbSig);
	CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER);
	memcpy(pbSig + cbR - cb, rgbSig, cb);

	cb = BN_bn2bin(s, rgbSig);
	CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER);
	memcpy(pbSig + 2 * cbR - cb, rgbSig, cb);

	p = cn_cbor_data_create2(
		pbSig, cbR * 2, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(p != nullptr, cbor_error);

	CHECK_CONDITION(
		_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_CBOR);

	pbSig = nullptr;

	if (eckey != nullptr) {
		EC_KEY_free(eckey);
	}

	return true;
}

bool ECDSA_Verify(COSE *pSigner,
	int index,
	COSE_KEY *pKey,
	int cbitDigest,
	const byte *rgbToSign,
	size_t cbToSign,
	cose_errback *perr)
{
	EC_KEY *eckey = nullptr;
	byte rgbDigest[EVP_MAX_MD_SIZE];
	unsigned int cbDigest = sizeof(rgbDigest);
	const EVP_MD *digest;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pSigner->m_allocContext;
#endif
	cn_cbor *p = nullptr;
	ECDSA_SIG *sig = nullptr;
	int cbR;
	cn_cbor *pSig;
	size_t cbSignature;

	BIGNUM *r, *s;

	eckey = ECKey_From(pKey, &cbR, perr);
	if (eckey == nullptr) {
	errorReturn:
		if (p != nullptr) {
			CN_CBOR_FREE(p, context);
		}
		if (eckey != nullptr) {
			EC_KEY_free(eckey);
		}
		if (sig != nullptr) {
			ECDSA_SIG_free(sig);
		}
		return false;
	}

	switch (cbitDigest) {
		case 256:
			digest = EVP_sha256();
			break;
		case 512:
			digest = EVP_sha512();
			break;
		case 384:
			digest = EVP_sha384();
			break;
		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, nullptr);

	pSig = _COSE_arrayget_int(pSigner, index);
	CHECK_CONDITION(pSig != nullptr, COSE_ERR_INVALID_PARAMETER);
	cbSignature = pSig->length;

	CHECK_CONDITION(cbSignature / 2 == (size_t)cbR, COSE_ERR_INVALID_PARAMETER);
	r = BN_bin2bn(pSig->v.bytes, (int)cbSignature / 2, nullptr);
	CHECK_CONDITION(nullptr != r, COSE_ERR_OUT_OF_MEMORY);
	s = BN_bin2bn(pSig->v.bytes + cbSignature / 2, (int)cbSignature / 2, nullptr);
	CHECK_CONDITION(nullptr != s, COSE_ERR_OUT_OF_MEMORY);

	sig = ECDSA_SIG_new();
	CHECK_CONDITION(sig != nullptr, COSE_ERR_OUT_OF_MEMORY);

	ECDSA_SIG_set0(sig, r, s);

	CHECK_CONDITION(ECDSA_do_verify(rgbDigest, cbDigest, sig, eckey) == 1,
		COSE_ERR_CRYPTO_FAIL);

	if (eckey != nullptr) {
		EC_KEY_free(eckey);
	}
	if (sig != nullptr) {
		ECDSA_SIG_free(sig);
	}

	return true;
}

#ifdef USE_EDDSA
bool EdDSA_Sign(COSE *pSigner,
	int index,
	COSE_KEY *pKeyIn,
	const byte *rgbToSign,
	size_t cbToSign,
	cose_errback *perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pSigner->m_allocContext;
#endif
	cn_cbor *p;
	cn_cbor_errback cbor_error;
	EVP_PKEY_CTX *keyCtx = nullptr;
	EVP_MD_CTX *mdCtx = nullptr;
	EVP_PKEY *pkey = nullptr;
	byte *pbSig = nullptr;
	int cbSig;

	p = cn_cbor_mapget_int(pKeyIn->m_cborKey, COSE_Key_OPK_Curve);
	if (p == nullptr) {
	errorReturn:
		if (mdCtx != nullptr) {
			EVP_MD_CTX_free(mdCtx);
		}
		if (keyCtx != nullptr) {
			EVP_PKEY_CTX_free(keyCtx);
		}
		if (pkey != nullptr) {
			EVP_PKEY_free(pkey);
		}
		if (pbSig != nullptr) {
			COSE_FREE(pbSig, context);
		}
		return false;
	}

	int type;

	switch (p->v.uint) {
		case COSE_Curve_Ed25519:
			type = EVP_PKEY_ED25519;
			cbSig = 32 * 2;
			break;

		case COSE_Curve_Ed448:
			type = EVP_PKEY_ED448;
			cbSig = 64 * 2;
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	p = cn_cbor_mapget_int(pKeyIn->m_cborKey, COSE_Key_EC_d);
	CHECK_CONDITION(p != nullptr, COSE_ERR_INVALID_PARAMETER);

	pkey = EVP_PKEY_new_raw_private_key(type, nullptr, p->v.bytes, p->length);
	CHECK_CONDITION(pkey != nullptr, COSE_ERR_CRYPTO_FAIL);

	keyCtx = EVP_PKEY_CTX_new_id(type, nullptr);
	CHECK_CONDITION(keyCtx != nullptr, COSE_ERR_OUT_OF_MEMORY);

	mdCtx = EVP_MD_CTX_new();
	CHECK_CONDITION(mdCtx != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(EVP_DigestSignInit(mdCtx, &keyCtx, nullptr, nullptr, pkey) == 1,
		COSE_ERR_CRYPTO_FAIL);
	keyCtx = nullptr;

	pbSig = (byte *) COSE_CALLOC(cbSig, 1, context);
	CHECK_CONDITION(pbSig != nullptr, COSE_ERR_OUT_OF_MEMORY);

	size_t cb2 = cbSig;
	CHECK_CONDITION(
		EVP_DigestSign(mdCtx, pbSig, &cb2, rgbToSign, cbToSign) == 1,
		COSE_ERR_CRYPTO_FAIL);

	p = cn_cbor_data_create2(
		pbSig, (int)cb2, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION(p != nullptr, COSE_ERR_OUT_OF_MEMORY);
	pbSig = nullptr;

	CHECK_CONDITION(
		_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_CBOR);

	if (mdCtx != nullptr) {
		EVP_MD_CTX_free(mdCtx);
	}
	if (keyCtx != nullptr) {
		EVP_PKEY_CTX_free(keyCtx);
	}
	if (pkey != nullptr) {
		EVP_PKEY_free(pkey);
	}
	if (pbSig != nullptr) {
		COSE_FREE(pbSig, context);
	}

	return true;
}

bool EdDSA_Verify(COSE *pSigner,
	int index,
	COSE_KEY *pKey,
	const byte *rgbToSign,
	size_t cbToSign,
	cose_errback *perr)
{
	cn_cbor *pSig;
	EVP_PKEY *pkey = nullptr;

	cn_cbor *p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_OPK_Curve);
	if (p == nullptr) {
	errorReturn:
		if (pkey != nullptr) {
			EVP_PKEY_free(pkey);
		}
		return false;
	}

	int type;

	switch (p->v.uint) {
		case COSE_Curve_Ed25519:
			type = EVP_PKEY_ED25519;
			break;

		case COSE_Curve_Ed448:
			type = EVP_PKEY_ED448;
			break;

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_OPK_X);
	CHECK_CONDITION(p != nullptr, COSE_ERR_INVALID_PARAMETER);

	pkey = EVP_PKEY_new_raw_public_key(type, nullptr, p->v.bytes, p->length);
	CHECK_CONDITION(pkey != nullptr, COSE_ERR_CBOR);

	pSig = _COSE_arrayget_int(pSigner, index);
	CHECK_CONDITION(pSig != nullptr, COSE_ERR_INVALID_PARAMETER);

	EVP_MD_CTX *pmdCtx = EVP_MD_CTX_new();
	EVP_PKEY_CTX *keyCtx = EVP_PKEY_CTX_new_id(type, nullptr);

	CHECK_CONDITION(
		EVP_DigestVerifyInit(pmdCtx, &keyCtx, nullptr, nullptr, pkey) == 1,
		COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(EVP_DigestVerify(pmdCtx, pSig->v.bytes, pSig->length,
						rgbToSign, cbToSign) == 1,
		COSE_ERR_CRYPTO_FAIL);

	if (pmdCtx != nullptr) {
		EVP_MD_CTX_free(pmdCtx);
	}
	if (pkey != nullptr) {
		EVP_PKEY_free(pkey);
	}

	return true;
}
#endif

bool AES_KW_Decrypt(COSE_Enveloped *pcose,
	const byte *pbKeyIn,
	size_t cbitKey,
	const byte *pbCipherText,
	size_t cbCipherText,
	byte *pbKeyOut,
	int *pcbKeyOut,
	cose_errback *perr)
{
	byte rgbOut[512 / 8];
	AES_KEY key;

	UNUSED(pcose);

	CHECK_CONDITION(AES_set_decrypt_key(pbKeyIn, (int)cbitKey, &key) == 0,
		COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(
		AES_unwrap_key(&key, nullptr, rgbOut, pbCipherText, (int)cbCipherText),
		COSE_ERR_CRYPTO_FAIL);

	memcpy(pbKeyOut, rgbOut, cbCipherText - 8);
	*pcbKeyOut = (int)(cbCipherText - 8);

	return true;
errorReturn:
	return false;
}

bool AES_KW_Encrypt(COSE_RecipientInfo *pcose,
	const byte *pbKeyIn,
	int cbitKey,
	const byte *pbContent,
	int cbContent,
	cose_errback *perr)
{
	byte *pbOut = nullptr;
	AES_KEY key;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_encrypt.m_message.m_allocContext;
#endif
	cn_cbor *cnTmp = nullptr;

	pbOut = (byte *) COSE_CALLOC(cbContent + 8, 1, context);
	CHECK_CONDITION(pbOut != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(
		AES_set_encrypt_key(pbKeyIn, cbitKey, &key) == 0, COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(AES_wrap_key(&key, nullptr, pbOut, pbContent, cbContent),
		COSE_ERR_CRYPTO_FAIL);

	cnTmp = cn_cbor_data_create2(
		pbOut, (int)cbContent + 8, 0, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_CONDITION(cnTmp != nullptr, COSE_ERR_CBOR);
	pbOut = nullptr;
	CHECK_CONDITION(_COSE_array_replace(&pcose->m_encrypt.m_message, cnTmp,
						INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_CBOR);
	cnTmp = nullptr;

	return true;

errorReturn:
	COSE_FREE(cnTmp, context);
	if (pbOut != nullptr) {
		COSE_FREE(pbOut, context);
	}
	return false;
}

void rand_bytes(byte *pb, size_t cb)
{
	RAND_bytes(pb, (int)cb);
}

/*!
 *
 * @param[in] pRecipent	Pointer to the message object
 * @param[in] ppKeyPrivate	Address of key with private portion
 * @param[in] pKeyPublic	Address of the key w/o a private portion
 * @param[in/out] ppbSecret	pointer to buffer to hold the computed secret
 * @param[in/out] pcbSecret	size of the computed secret
 * @param[in] context		cbor allocation context structure
 * @param[out] perr			location to return error information
 * @returns		success of the function
 */

bool ECDH_ComputeSecret(COSE *pRecipient,
	COSE_KEY **ppKeyPrivate,
	COSE_KEY *pKeyPublic,
	byte **ppbSecret,
	size_t *pcbSecret,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	EC_KEY *peckeyPrivate = nullptr;
	EC_KEY *peckeyPublic = nullptr;
	int cbGroup;
	int cbsecret;
	byte *pbsecret = nullptr;
	bool fRet = false;

	peckeyPublic = ECKey_From(pKeyPublic, &cbGroup, perr);
	if (peckeyPublic == nullptr) {
		goto errorReturn;
	}

	if (*ppKeyPrivate == nullptr) {
		{
			cn_cbor *pCompress = _COSE_map_get_int(
				pRecipient, COSE_Header_UseCompressedECDH, COSE_BOTH, perr);
			if (pCompress == nullptr) {
				FUseCompressed = false;
			}
			else {
				FUseCompressed = (pCompress->type == CN_CBOR_TRUE);
			}
		}
		peckeyPrivate = EC_KEY_new();
		EC_KEY_set_group(peckeyPrivate, EC_KEY_get0_group(peckeyPublic));
		CHECK_CONDITION(
			EC_KEY_generate_key(peckeyPrivate) == 1, COSE_ERR_CRYPTO_FAIL);
		*ppKeyPrivate =
			EC_FromKey(peckeyPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
		if (*ppKeyPrivate == nullptr) {
			goto errorReturn;
		}
	}
	else {
		peckeyPrivate = ECKey_From(*ppKeyPrivate, &cbGroup, perr);
		if (peckeyPrivate == nullptr) {
			goto errorReturn;
		}
	}

	pbsecret = (byte *) COSE_CALLOC(cbGroup, 1, context);
	CHECK_CONDITION(pbsecret != nullptr, COSE_ERR_OUT_OF_MEMORY);

	cbsecret = ECDH_compute_key(pbsecret, cbGroup,
		EC_KEY_get0_public_key(peckeyPublic), peckeyPrivate, nullptr);
	CHECK_CONDITION(cbsecret > 0, COSE_ERR_CRYPTO_FAIL);

	*ppbSecret = pbsecret;
	*pcbSecret = cbsecret;
	pbsecret = nullptr;

	fRet = true;

errorReturn:
	if (pbsecret != nullptr) {
		COSE_FREE(pbsecret, context);
	}
	if (peckeyPublic != nullptr) {
		EC_KEY_free(peckeyPublic);
	}
	if (peckeyPrivate != nullptr) {
		EC_KEY_free(peckeyPrivate);
	}

	return fRet;
}

#endif	// COSE_C_USE_OPENSSL
