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

#include <assert.h>
#include <memory.h>
#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>

static bool FUseCompressed = true;

#define MIN(A, B) ((A) < (B) ? (A) : (B))

#if (OPENSSL_VERSION_NUMBER < 0x10100000)

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

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

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

int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
	if (r == NULL || s == NULL)
		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 = NULL;
	int NSize = 15 - (LSize / 8);
	int outl = 0;
	byte rgbIV[15] = {0};
	const cn_cbor *pIV = NULL;
	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 != NULL, 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, NULL);
	if ((pIV == NULL) || (pIV->type != CN_CBOR_BYTES)) {
		if (perr != NULL) {
			perr->err = COSE_ERR_INVALID_PARAMETER;
		}

	errorReturn:
		if (rgbOut != NULL) {
			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, NULL, NULL, NULL),
		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, NULL, pbKey, rgbIV),
		COSE_ERR_DECRYPT_FAILED);

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

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

	CHECK_CONDITION(
		EVP_DecryptUpdate(ctx, NULL, &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 = NULL;
	int NSize = 15 - (LSize / 8);
	int outl = 0;
	const cn_cbor *cbor_iv = NULL;
	cn_cbor *cbor_iv_t = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif
	cn_cbor *cnTmp = NULL;
	const EVP_CIPHER *cipher;
	byte rgbIV[16];
	byte *pbIV = NULL;
	cn_cbor_errback cbor_error;

	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(NULL != 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 == NULL) {
		pbIV = COSE_CALLOC(NSize, 1, context);
		CHECK_CONDITION(pbIV != NULL, COSE_ERR_OUT_OF_MEMORY);
		rand_bytes(pbIV, NSize);
		memcpy(rgbIV, pbIV, NSize);
		cbor_iv_t = cn_cbor_data_create(
			pbIV, NSize, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(cbor_iv_t != NULL, cbor_error);
		pbIV = NULL;

		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t,
				COSE_UNPROTECT_ONLY, perr)) {
			goto errorReturn;
		}
		cbor_iv_t = NULL;
	}
	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, NULL, NULL, NULL),
		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, NULL),
		COSE_ERR_CRYPTO_FAIL);	// Say we are doing an 8 byte tag

	CHECK_CONDITION(
		EVP_EncryptInit_ex(ctx, 0, NULL, 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, NULL, &outl, pbAuthData, (int)cbAuthData),
		COSE_ERR_CRYPTO_FAIL);

	rgbOut = (byte *)COSE_CALLOC(cbOut + TSize, 1, context);
	CHECK_CONDITION(rgbOut != NULL, 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_create(
		rgbOut, (int)pcose->cbContent + TSize, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR);
	rgbOut = NULL;

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

errorReturn:
	if (pbIV != NULL) {
		COSE_FREE(pbIV, context);
	}
	if (cbor_iv_t != NULL) {
		COSE_FREE(cbor_iv_t, context);
	}
	if (rgbOut != NULL) {
		COSE_FREE(rgbOut, context);
	}
	if (cnTmp != NULL) {
		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 = NULL;
	int outl = 0;
	byte rgbIV[15] = {0};
	const cn_cbor *pIV = NULL;
	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(NULL != 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, NULL);
	if ((pIV == NULL) || (pIV->type != CN_CBOR_BYTES)) {
		if (perr != NULL) {
			perr->err = COSE_ERR_INVALID_PARAMETER;
		}

	errorReturn:
		if (rgbOut != NULL) {
			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, NULL, NULL, NULL),
		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, NULL, pbKey, rgbIV),
		COSE_ERR_DECRYPT_FAILED);

	//  Pus in the AAD

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

	//

	cbOut = (int)cbCrypto - TSize;
	rgbOut = (byte *)COSE_CALLOC(cbOut, 1, context);
	CHECK_CONDITION(rgbOut != NULL, 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 = NULL;
	int outl = 0;
	byte rgbIV[16] = {0};
	byte *pbIV = NULL;
	const cn_cbor *cbor_iv = NULL;
	cn_cbor *cbor_iv_t = NULL;
	const EVP_CIPHER *cipher;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif
	cn_cbor_errback cbor_error;

	// Make it first so we can clean it up
	ctx = EVP_CIPHER_CTX_new();
	CHECK_CONDITION(NULL != 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 == NULL) {
		pbIV = COSE_CALLOC(96, 1, context);
		CHECK_CONDITION(pbIV != NULL, COSE_ERR_OUT_OF_MEMORY);
		rand_bytes(pbIV, 96 / 8);
		memcpy(rgbIV, pbIV, 96 / 8);
		cbor_iv_t = cn_cbor_data_create(
			pbIV, 96 / 8, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(cbor_iv_t != NULL, cbor_error);
		pbIV = NULL;

		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t,
				COSE_UNPROTECT_ONLY, perr)) {
			goto errorReturn;
		}
		cbor_iv_t = NULL;
	}
	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, NULL, NULL, NULL),
		COSE_ERR_CRYPTO_FAIL);

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

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

	rgbOut = (byte *)COSE_CALLOC(pcose->cbContent + 128 / 8, 1, context);
	CHECK_CONDITION(rgbOut != NULL, 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_create(
		rgbOut, (int)pcose->cbContent + 128 / 8, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR);
	rgbOut = NULL;
	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cnTmp, INDEX_BODY,
						CBOR_CONTEXT_PARAM_COMMA NULL),
		COSE_ERR_CBOR);

	EVP_CIPHER_CTX_free(ctx);
	return true;

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

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 = NULL;
	EVP_CIPHER_CTX *ctx;
	int cbOut;
	byte rgbIV[16] = {0};
	byte *rgbOut = NULL;
	bool f = false;
	unsigned int i;
	cn_cbor *cn = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif

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

	rgbOut = COSE_CALLOC(16, 1, context);
	CHECK_CONDITION(rgbOut != NULL, 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, NULL, 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_create(rgbOut, TSize / 8, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(cn != NULL, COSE_ERR_OUT_OF_MEMORY);
	rgbOut = NULL;

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

	EVP_CIPHER_CTX_free(ctx);
	return !f;

errorReturn:
	if (rgbOut != NULL) {
		COSE_FREE(rgbOut, context);
	}
	if (cn != NULL) {
		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 = NULL;
	EVP_CIPHER_CTX *ctx = NULL;
	int cbOut;
	byte rgbIV[16] = {0};
	byte rgbTag[16] = {0};
	bool f = false;
	unsigned int i;

	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(NULL != ctx, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(EVP_EncryptInit_ex(ctx, pcipher, NULL, 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 != NULL, 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;

errorReturn:
	EVP_CIPHER_CTX_free(ctx);
	return false;
}

#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 = NULL;
	const EVP_CIPHER * pcipher = NULL;
	byte * rgbOut = NULL;
	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 != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(CMAC_Init(pctx, pcose->pbKey, pcose->cbKey, pcipher, NULL /*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 != NULL, 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 = NULL;
	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(NULL != 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, NULL, 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)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, 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 = NULL;
	unsigned int cbDigest;

	ctx = HMAC_CTX_new();
	CHECK_CONDITION(NULL != 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 != NULL) {
		CHECK_CONDITION(
			HMAC_Init_ex(ctx, cnSalt->v.bytes, (int)cnSalt->length, pmd, NULL),
			COSE_ERR_CRYPTO_FAIL);
	}
	else {
		CHECK_CONDITION(HMAC_Init_ex(ctx, rgbSalt, cbSalt, pmd, NULL),
			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 = NULL;
	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 != NULL, 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, NULL),
			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, 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 = NULL;
	byte *rgbOut = NULL;
	unsigned int cbOut;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif

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

	if (0) {
	errorReturn:
		COSE_FREE(rgbOut, 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 = COSE_CALLOC(EVP_MAX_MD_SIZE, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(
		HMAC_Init_ex(ctx, pbKey, (int)cbKey, pmd, NULL), 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);

	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message,
						cn_cbor_data_create(
							rgbOut, TSize / 8, CBOR_CONTEXT_PARAM_COMMA NULL),
						INDEX_MAC_TAG, CBOR_CONTEXT_PARAM_COMMA NULL),
		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;
	const EVP_MD *pmd = NULL;
	byte *rgbOut = NULL;
	unsigned int cbOut;
	bool f = false;
	unsigned int i;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif

	ctx = HMAC_CTX_new();
	CHECK_CONDITION(ctx != NULL, 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 = COSE_CALLOC(EVP_MAX_MD_SIZE, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(
		HMAC_Init_ex(ctx, pbKey, (int)cbKey, pmd, NULL), 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 != NULL, COSE_ERR_CBOR);

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

	HMAC_CTX_free(ctx);
	return !f;

errorReturn:
	COSE_FREE(rgbOut, context);
	HMAC_CTX_free(ctx);
	return false;
}

#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(const cn_cbor *pKey, int *cbGroup, cose_errback *perr)
{
	EC_KEY *pNewKey = EC_KEY_new();
	byte rgbKey[512 + 1];
	int cbKey;
	const cn_cbor *p;
	int nidGroup = -1;
	EC_POINT *pPoint = NULL;

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Curve);
	CHECK_CONDITION(p != NULL, 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 != NULL, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(
		EC_KEY_set_group(pNewKey, ecgroup) == 1, COSE_ERR_CRYPTO_FAIL);

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

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Y);
	CHECK_CONDITION((p != NULL), COSE_ERR_INVALID_PARAMETER);
	if (p->type == CN_CBOR_BYTES) {
		rgbKey[0] = POINT_CONVERSION_UNCOMPRESSED;
		cbKey = (*cbGroup * 2) + 1;
		CHECK_CONDITION(p->length == *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 != NULL, COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(
		EC_POINT_oct2point(ecgroup, pPoint, rgbKey, cbKey, NULL) == 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, COSE_Key_EC_d);
	if (p != NULL) {
		BIGNUM *pbn;

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

	return pNewKey;

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

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

	pgroup = EC_KEY_get0_group(pKey);
	CHECK_CONDITION(pgroup != NULL, 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 != NULL, cbor_error);

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

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

	if (FUseCompressed) {
		cbSize = EC_POINT_point2oct(
			pgroup, pPoint, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL);
		CHECK_CONDITION(cbSize > 0, COSE_ERR_CRYPTO_FAIL);
		pbOut = COSE_CALLOC(cbSize, 1, context);
		CHECK_CONDITION(pbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
		CHECK_CONDITION(
			EC_POINT_point2oct(pgroup, pPoint, POINT_CONVERSION_COMPRESSED,
				pbOut, cbSize, NULL) == cbSize,
			COSE_ERR_CRYPTO_FAIL);
	}
	else {
		cbSize = EC_POINT_point2oct(
			pgroup, pPoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
		CHECK_CONDITION(cbSize > 0, COSE_ERR_CRYPTO_FAIL);
		pbOut = COSE_CALLOC(cbSize, 1, context);
		CHECK_CONDITION(pbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
		CHECK_CONDITION(
			EC_POINT_point2oct(pgroup, pPoint, POINT_CONVERSION_UNCOMPRESSED,
				pbOut, cbSize, NULL) == cbSize,
			COSE_ERR_CRYPTO_FAIL);
	}
	p = cn_cbor_data_create(
		pbOut + 1, (int)(cbSize / 2), CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(p != NULL, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_X, p,
							 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
		cbor_error);
	p = NULL;

	if (FUseCompressed) {
		p = cn_cbor_bool_create(
			pbOut[0] & 1, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(p != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Y, p,
								 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
			cbor_error);
		p = NULL;
	}
	else {
		p = cn_cbor_data_create(pbOut + cbSize / 2 + 1, (int)(cbSize / 2),
			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		pbOut = NULL;  // It is already part of the other one.
		CHECK_CONDITION_CBOR(p != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Y, p,
								 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
			cbor_error);
		p = NULL;
	}

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

returnHere:
	if (pbOut != NULL) {
		COSE_FREE(pbOut, context);
	}
	if (p != NULL) {
		CN_CBOR_FREE(p, context);
	}
	return pkey;

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

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

	eckey = ECKey_From(pKey, &cbR, perr);
	if (eckey == NULL) {
	errorReturn:
		if (pbSig != NULL) {
			COSE_FREE(pbSig, context);
		}
		if (p != NULL) {
			CN_CBOR_FREE(p, context);
		}
		if (eckey != NULL) {
			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, NULL);

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

	pbSig = COSE_CALLOC(cbR, 2, context);
	CHECK_CONDITION(pbSig != NULL, 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_create(
		pbSig, cbR * 2, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(p != NULL, cbor_error);

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

	pbSig = NULL;

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

	return true;
}

bool ECDSA_Verify(COSE *pSigner,
	int index,
	const cn_cbor *pKey,
	int cbitDigest,
	const byte *rgbToSign,
	size_t cbToSign,
	cose_errback *perr)
{
	EC_KEY *eckey = NULL;
	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 = NULL;
	ECDSA_SIG *sig = NULL;
	int cbR;
	cn_cbor *pSig;
	size_t cbSignature;

	BIGNUM *r, *s;

	eckey = ECKey_From(pKey, &cbR, perr);
	if (eckey == NULL) {
	errorReturn:
		if (p != NULL) {
			CN_CBOR_FREE(p, context);
		}
		if (eckey != NULL) {
			EC_KEY_free(eckey);
		}
		if (sig != NULL) {
			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, NULL);

	pSig = _COSE_arrayget_int(pSigner, index);
	CHECK_CONDITION(pSig != NULL, 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, NULL);
	CHECK_CONDITION(NULL != r, COSE_ERR_OUT_OF_MEMORY);
	s = BN_bin2bn(pSig->v.bytes + cbSignature / 2, (int)cbSignature / 2, NULL);
	CHECK_CONDITION(NULL != s, COSE_ERR_OUT_OF_MEMORY);

	sig = ECDSA_SIG_new();
	CHECK_CONDITION(sig != NULL, 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 != NULL) {
		EC_KEY_free(eckey);
	}
	if (sig != NULL) {
		ECDSA_SIG_free(sig);
	}

	return true;
}

#ifdef USE_EDDSA
bool EdDSA_Sign(COSE *pSigner,
	int index,
	const cn_cbor *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 = NULL;
	EVP_MD_CTX *mdCtx = NULL;
	EVP_PKEY *pkey = NULL;
	byte *pbSig = NULL;
	int cbSig;

	p = cn_cbor_mapget_int(pKeyIn, COSE_Key_OPK_Curve);
	if (p == NULL) {
	errorReturn:
		if (mdCtx != NULL) {
			EVP_MD_CTX_free(mdCtx);
		}
		if (keyCtx != NULL) {
			EVP_PKEY_CTX_free(keyCtx);
		}
		if (pkey != NULL) {
			EVP_PKEY_free(pkey);
		}
		if (pbSig != NULL) {
			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, COSE_Key_EC_d);
	CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);

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

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

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

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

	pbSig = COSE_CALLOC(cbSig, 1, context);
	CHECK_CONDITION(pbSig != NULL, 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_create(
		pbSig, (int)cb2, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION(p != NULL, COSE_ERR_OUT_OF_MEMORY);
	pbSig = NULL;

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

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

	return true;
}

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

	cn_cbor *p = cn_cbor_mapget_int(pKey, COSE_Key_OPK_Curve);
	if (p == NULL) {
	errorReturn:
		if (pkey != NULL) {
			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, COSE_Key_OPK_X);
	CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);

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

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

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

	CHECK_CONDITION(
		EVP_DigestVerifyInit(pmdCtx, &keyCtx, NULL, NULL, 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 != NULL) {
		EVP_MD_CTX_free(pmdCtx);
	}
	if (pkey != NULL) {
		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, NULL, 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 = NULL;
	AES_KEY key;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_encrypt.m_message.m_allocContext;
#endif
	cn_cbor *cnTmp = NULL;

	pbOut = COSE_CALLOC(cbContent + 8, 1, context);
	CHECK_CONDITION(pbOut != NULL, 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, NULL, pbOut, pbContent, cbContent),
		COSE_ERR_CRYPTO_FAIL);

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

	return true;

errorReturn:
	COSE_FREE(cnTmp, context);
	if (pbOut != NULL) {
		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,
	cn_cbor **ppKeyPrivate,
	const cn_cbor *pKeyPublic,
	byte **ppbSecret,
	size_t *pcbSecret,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	EC_KEY *peckeyPrivate = NULL;
	EC_KEY *peckeyPublic = NULL;
	int cbGroup;
	int cbsecret;
	byte *pbsecret = NULL;
	bool fRet = false;

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

	if (*ppKeyPrivate == NULL) {
		{
			cn_cbor *pCompress = _COSE_map_get_int(
				pRecipient, COSE_Header_UseCompressedECDH, COSE_BOTH, perr);
			if (pCompress == NULL) {
				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 == NULL) {
			goto errorReturn;
		}
	}
	else {
		peckeyPrivate = ECKey_From(*ppKeyPrivate, &cbGroup, perr);
		if (peckeyPrivate == NULL) {
			goto errorReturn;
		}
	}

	pbsecret = COSE_CALLOC(cbGroup, 1, context);
	CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);

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

	*ppbSecret = pbsecret;
	*pcbSecret = cbsecret;
	pbsecret = NULL;

	fRet = true;

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

	return fRet;
}

#endif	// COSE_C_USE_OPENSSL
