#include <stdlib.h>
#include <memory.h>

#include "cose.h"
#include "cose_int.h"
#include "configure.h"
#include "crypto.h"

extern bool BuildContextBytes(COSE * pcose, int algID, size_t cbitKey, byte ** ppbContext, size_t * pcbContext, CBOR_CONTEXT_COMMA cose_errback * perr);


COSE* RecipientRoot = NULL;

/*! \private
* @brief Test if a HCOSE_RECIPIENT handle is valid
*
*  Internal function to test if a recipient handle is valid.
*  This will start returning invalid results and cause the code to
*  crash if handles are not released before the memory that underlies them
*  is deallocated.  This is an issue of a block allocator is used since
*  in that case it is common to allocate memory but never to de-allocate it
*  and just do that in a single big block.
*
*  @param h handle to be validated
*  @returns result of check
*/
bool IsValidRecipientHandle(HCOSE_RECIPIENT h)
{
	COSE_RecipientInfo * p = (COSE_RecipientInfo *)h;

	if (p == NULL) return false;
	return _COSE_IsInList(RecipientRoot, &p->m_encrypt.m_message);
}

HCOSE_RECIPIENT COSE_Recipient_Init(COSE_INIT_FLAGS flags, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	CHECK_CONDITION(flags == COSE_INIT_FLAGS_NONE, COSE_ERR_INVALID_PARAMETER);
	COSE_RecipientInfo * pobj = (COSE_RecipientInfo *)COSE_CALLOC(1, sizeof(COSE_RecipientInfo), context);
	CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);

	if (!_COSE_Init(flags, &pobj->m_encrypt.m_message, COSE_recipient_object, CBOR_CONTEXT_PARAM_COMMA perr)) {
		_COSE_Recipient_Free(pobj);
		return NULL;
	}

	_COSE_InsertInList(&RecipientRoot, &pobj->m_encrypt.m_message);
	return (HCOSE_RECIPIENT)pobj;

errorReturn:
	return NULL;
}

bool COSE_Recipient_Free(HCOSE_RECIPIENT hRecipient)
{
	if (IsValidRecipientHandle(hRecipient)) {
		COSE_RecipientInfo * p = (COSE_RecipientInfo *)hRecipient;
		_COSE_RemoveFromList(&RecipientRoot, &p->m_encrypt.m_message);

		_COSE_Recipient_Free(p);
		return true;
	}

	return false;
}

HCOSE_RECIPIENT COSE_Recipient_from_shared_secret(byte * rgbKey, int cbKey, byte * rgbKid, int cbKid, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	HCOSE_RECIPIENT hRecipient = NULL;

	hRecipient = COSE_Recipient_Init(0, CBOR_CONTEXT_PARAM_COMMA perr);
	if (hRecipient == NULL) goto errorReturn;

	if (!COSE_Recipient_SetKey_secret(hRecipient, rgbKey, cbKey, rgbKid, cbKid, perr)) goto errorReturn;

	return hRecipient;

errorReturn:
	if (hRecipient != NULL) COSE_Recipient_Free(hRecipient);
	return NULL;
}



COSE_RecipientInfo * _COSE_Recipient_Init_From_Object(cn_cbor * cbor, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	COSE_RecipientInfo * pRecipient = NULL;

	pRecipient = (COSE_RecipientInfo *)COSE_CALLOC(1, sizeof(COSE_RecipientInfo), context);
	CHECK_CONDITION(pRecipient != NULL, COSE_ERR_OUT_OF_MEMORY);

#ifdef USE_ARRAY
	CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
#else
	if (cbor->type != CN_CBOR_MAP) {
		if (errp != NULL) errp->err = COSE_ERR_INVALID_PARAMETER;
		COSE_FREE(pRecipient, context);
		return NULL;
	}
#endif

	if (_COSE_Enveloped_Init_From_Object(cbor, &pRecipient->m_encrypt, CBOR_CONTEXT_PARAM_COMMA perr) == NULL) {
		goto errorReturn;
	}

	_COSE_InsertInList(&RecipientRoot, &pRecipient->m_encrypt.m_message);

	return pRecipient;

errorReturn:
	if (pRecipient != NULL) _COSE_Recipient_Free(pRecipient);
	return NULL;
}

void _COSE_Recipient_Free(COSE_RecipientInfo * pRecipient)
{
	if (pRecipient->m_encrypt.m_message.m_refCount > 1) {
		pRecipient->m_encrypt.m_message.m_refCount--;
		return;
	}

	COSE_FREE(pRecipient, &pRecipient->m_encrypt.m_message.m_allocContext);

	return;
}

/**
* Perform an AES-CCM Decryption operation
*
* @param[in]	COSE *		Pointer to COSE Encryption context object
* @param[in]	int			Alorithm key is being generated for
* @param[in]	cn_cbor *	Key used for operation
* @param[out]	byte *		Buffer to return new key in	
* @param[in]	size_t       Size of key to create in bits
* @param[in]    size_t		Size of digest function
* @param[in]	cbor_context * Allocation context
* @param[out]	cose_errback * Returned error information
* @return                   Did the function succeed?
*/

static bool HKDF_X(COSE * pCose, bool fHMAC, bool fECDH, bool fStatic, bool fSend, int algResult, const cn_cbor * pKey, byte * pbKey, size_t cbitKey, size_t cbitHash, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	byte * pbContext = NULL;
	size_t cbContext;
	bool fRet = false;
	const cn_cbor * cn;
	byte rgbDigest[512 / 8];
	size_t cbDigest;
	byte * pbSecret = NULL;
	size_t cbSecret = 0;

	if (!BuildContextBytes(pCose, algResult, cbitKey, &pbContext, &cbContext, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

	cn = cn_cbor_mapget_int(pKey, COSE_Key_Type);
	CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);

	if (fECDH) {
		cn_cbor * pkeyMessage;

		pkeyMessage = _COSE_map_get_int(pCose, fStatic ? COSE_Header_ECDH_STATIC : COSE_Header_ECDH_EPHEMERAL, COSE_BOTH, perr);

		CHECK_CONDITION(pKey != NULL, COSE_ERR_INVALID_PARAMETER);
		if (fSend) {
			if (!ECDH_ComputeSecret(pCose, &pkeyMessage, pKey, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
			if (pkeyMessage->parent == NULL) {
				if (!_COSE_map_put(pCose, COSE_Header_ECDH_EPHEMERAL, pkeyMessage, COSE_UNPROTECT_ONLY, perr)) goto errorReturn;
			}
		}
		else {
			CHECK_CONDITION(pkeyMessage != NULL, COSE_ERR_INVALID_PARAMETER);
			if (!ECDH_ComputeSecret(pCose, (cn_cbor **)&pKey, pkeyMessage, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		}
	}
	else {
		CHECK_CONDITION(cn->v.sint == 4, COSE_ERR_INVALID_PARAMETER);

		cn = cn_cbor_mapget_int(pKey, -1);
		CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
		pbSecret = (byte *) cn->v.bytes;
		cbSecret = cn->length;
	}

	if (fHMAC) {
		if (!HKDF_Extract(pCose, pbSecret, cbSecret, cbitHash, rgbDigest, &cbDigest, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

		if (!HKDF_Expand(pCose, cbitHash, rgbDigest, cbDigest, pbContext, cbContext, pbKey, cbitKey / 8, perr)) goto errorReturn;
	}
	else {
		if (!HKDF_AES_Expand(pCose, cbitHash, pbSecret, cbSecret, pbContext, cbContext, pbKey, cbitKey / 8, perr)) goto errorReturn;
	}
	fRet = true;

errorReturn:
	if (fECDH && pbSecret != NULL) {
		memset(pbSecret, 0, cbSecret);
		COSE_FREE(pbSecret, context);
	}
	memset(rgbDigest, 0, sizeof(rgbDigest));
	if (pbContext != NULL) COSE_FREE(pbContext, context);
	return fRet;
}

bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, int algIn, int cbitKey, byte * pbKeyIn, cose_errback * perr)
{
	int alg;
	const cn_cbor * cn = NULL;
	COSE_RecipientInfo * pRecip2;
	byte * pbKey = pbKeyIn;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context;
#endif
	byte * pbAuthData = NULL;
	byte * pbProtected = NULL;
	COSE_Enveloped * pcose = &pRecip->m_encrypt;
	cn_cbor * cnBody = NULL;
	byte * pbContext = NULL;
	byte rgbKey[256 / 8];
	byte * pbSecret = NULL;
	int cbKey2;

#ifdef USE_CBOR_CONTEXT
	context = &pcose->m_message.m_allocContext;
#endif

	cn = _COSE_map_get_int(&pRecip->m_encrypt.m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
	if (cn == NULL) {
	errorReturn:
		if (pbContext != NULL) COSE_FREE(pbContext, context);
		if (pbProtected != NULL) COSE_FREE(pbProtected, context);
		if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
		if (pbSecret != NULL) COSE_FREE(pbSecret, context);
		return false;
	}
	CHECK_CONDITION((cn->type == CN_CBOR_UINT) || (cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
	alg = (int)cn->v.uint;

	CHECK_CONDITION(pbKey != NULL, COSE_ERR_INVALID_PARAMETER);

	switch (alg) {
	case COSE_Algorithm_Direct:
		CHECK_CONDITION(pRecip->m_pkey != NULL, COSE_ERR_INVALID_PARAMETER);
		cn = cn_cbor_mapget_int(pRecip->m_pkey, -1);
		CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION((cn->length == (unsigned int)cbitKey / 8), COSE_ERR_INVALID_PARAMETER);
		memcpy(pbKey, cn->v.bytes, cn->length);

		return true;

	case COSE_Algorithm_AES_KW_128:
	case COSE_Algorithm_AES_KW_192:
	case COSE_Algorithm_AES_KW_256:
		break;

	case COSE_Algorithm_Direct_HKDF_AES_128:
	case COSE_Algorithm_Direct_HKDF_AES_256:
	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
		break;

	case COSE_Algorithm_ECDH_ES_HKDF_256:
	case COSE_Algorithm_ECDH_ES_HKDF_512:
	case COSE_Algorithm_ECDH_SS_HKDF_256:
	case COSE_Algorithm_ECDH_SS_HKDF_512:
		break;

	case COSE_Algorithm_ECDH_ES_A128KW:
	case COSE_Algorithm_ECDH_ES_A192KW:
	case COSE_Algorithm_ECDH_ES_A256KW:
		break;

	case COSE_Algorithm_ECDH_SS_A128KW:
	case COSE_Algorithm_ECDH_SS_A192KW:
	case COSE_Algorithm_ECDH_SS_A256KW:
		break;

	default:
		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
		break;
	}

	//  If there is a recipient - ask it for the key

	for (pRecip2 = pcose->m_recipientFirst; pRecip2 != NULL; pRecip2 = pRecip->m_recipientNext) {
		if (_COSE_Recipient_decrypt(pRecip2, alg, cbitKey, pbKey, perr)) break;
	}

	cnBody = _COSE_arrayget_int(&pcose->m_message, INDEX_BODY);
	CHECK_CONDITION(cnBody != NULL, COSE_ERR_INVALID_PARAMETER);

	switch (alg) {
	case COSE_Algorithm_AES_KW_128:
	case COSE_Algorithm_AES_KW_192:
	case COSE_Algorithm_AES_KW_256:
		CHECK_CONDITION(pRecip->m_pkey != NULL, COSE_ERR_INVALID_PARAMETER);
		int x = cbitKey / 8;
		cn = cn_cbor_mapget_int(pRecip->m_pkey, -1);
		CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);

		if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, cn->v.bytes, cn->length * 8, cnBody->v.bytes, cnBody->length, pbKey, &x, perr)) goto errorReturn;
		break;

	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
		if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
		if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_Direct_HKDF_AES_128:
		if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 128, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_Direct_HKDF_AES_256:
		if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_ES_HKDF_256:
		if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_ES_HKDF_512:
		if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_SS_HKDF_256:
		if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_SS_HKDF_512:
		if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_ES_A128KW:
		if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_128, pRecip->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

		if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 128, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;

		break;

	case COSE_Algorithm_ECDH_ES_A192KW:
		if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_192, pRecip->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

		if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 192, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;

		break;

	case COSE_Algorithm_ECDH_ES_A256KW:
		if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_256, pRecip->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

		if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 256, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;

		break;

	case COSE_Algorithm_ECDH_SS_A128KW:
		if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_128, pRecip->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

		if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 128, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;

		break;

	case COSE_Algorithm_ECDH_SS_A192KW:
		if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_192, pRecip->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

		if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 192, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;

		break;

	case COSE_Algorithm_ECDH_SS_A256KW:
		if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_256, pRecip->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

		if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 256, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;

		break;

	default:
		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
		break;
	}

	return true;
}

bool _COSE_Recipient_encrypt(COSE_RecipientInfo * pRecipient, const byte * pbContent, size_t cbContent, cose_errback * perr)
{
	int alg;
	int t;
	COSE_RecipientInfo * pri;
	const cn_cbor * cn_Alg = NULL;
	byte * pbAuthData = NULL;
	cn_cbor * ptmp = NULL;
	size_t cbitKey;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = NULL;
#endif
	cn_cbor_errback cbor_error;
	bool fRet = false;
	byte * pbContext = NULL;
	byte rgbKey[256 / 8];
	byte * pbSecret = NULL;
	byte * pbKey = NULL;
	size_t cbKey = 0;

#ifdef USE_CBOR_CONTEXT
	context = &pRecipient->m_encrypt.m_message.m_allocContext;
#endif // USE_CBOR_CONTEXT

	cn_Alg = _COSE_map_get_int(&pRecipient->m_encrypt.m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
	if (cn_Alg == NULL) goto errorReturn;

	CHECK_CONDITION((cn_Alg->type == CN_CBOR_UINT) || (cn_Alg->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
	alg = (int)cn_Alg->v.uint;

	//  Get the key size

	switch (alg) {
	case COSE_Algorithm_Direct:
	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
	case COSE_Algorithm_Direct_HKDF_AES_128:
	case COSE_Algorithm_Direct_HKDF_AES_256:
	case COSE_Algorithm_ECDH_ES_HKDF_256:
	case COSE_Algorithm_ECDH_ES_HKDF_512:
	case COSE_Algorithm_ECDH_SS_HKDF_256:
	case COSE_Algorithm_ECDH_SS_HKDF_512:
		//  This is a NOOP
		cbitKey = 0;
		CHECK_CONDITION(pRecipient->m_encrypt.m_recipientFirst == NULL, COSE_ERR_INVALID_PARAMETER);
		break;

	case COSE_Algorithm_AES_KW_128:
	case COSE_Algorithm_ECDH_ES_A128KW:
	case COSE_Algorithm_ECDH_SS_A128KW:
		cbitKey = 128;
		break;

	case COSE_Algorithm_AES_KW_192:
	case COSE_Algorithm_ECDH_ES_A192KW:
	case COSE_Algorithm_ECDH_SS_A192KW:
		cbitKey = 192;
		break;

	case COSE_Algorithm_AES_KW_256:
	case COSE_Algorithm_ECDH_ES_A256KW:
	case COSE_Algorithm_ECDH_SS_A256KW:
		cbitKey = 256;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	//  If we are doing direct encryption - then recipient generates the key

	if (pRecipient->m_encrypt.m_recipientFirst != NULL) {
		t = 0;
		for (pri = pRecipient->m_encrypt.m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
			if (pri->m_encrypt.m_message.m_flags & 1) {
				t |= 1;
				pbKey = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
				if (pbKey == NULL) goto errorReturn;
				cbKey = cbitKey / 8;
			}
			else {
				t |= 2;
			}
		}
		CHECK_CONDITION(t != 3, COSE_ERR_INVALID_PARAMETER);
	}

	//   Do we need to generate a random key at this point - 
	//   This is only true if we both haven't done it and and we have a recipient to encrypt it.

	if ((pRecipient->m_pkey!= NULL)) {
		pbKey = (byte *)COSE_CALLOC(cbitKey / 8, 1, context);
		CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
		cbKey = cbitKey / 8;
		rand_bytes(pbKey, cbKey);
	}

	//  Build protected headers

	const cn_cbor * cbProtected = _COSE_encode_protected(&pRecipient->m_encrypt.m_message, perr);
	if (cbProtected == NULL) goto errorReturn;

	//  Build authenticated data
	size_t cbAuthData = 0;
	if (!_COSE_Encrypt_Build_AAD(&pRecipient->m_encrypt.m_message, &pbAuthData, &cbAuthData, "Recipient", perr)) goto errorReturn;

	switch (alg) {

	case COSE_Algorithm_Direct:
	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
	case COSE_Algorithm_Direct_HKDF_AES_128:
	case COSE_Algorithm_Direct_HKDF_AES_256:
	case COSE_Algorithm_ECDH_ES_HKDF_256:
	case COSE_Algorithm_ECDH_ES_HKDF_512:
	case COSE_Algorithm_ECDH_SS_HKDF_256:
	case COSE_Algorithm_ECDH_SS_HKDF_512:
		ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
		CHECK_CONDITION_CBOR(_COSE_array_replace(&pRecipient->m_encrypt.m_message, ptmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
		ptmp = NULL;
		break;


	case COSE_Algorithm_AES_KW_128:
	case COSE_Algorithm_AES_KW_192:
	case COSE_Algorithm_AES_KW_256:
		if (pRecipient->m_pkey != NULL) {
			cn_cbor * pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
			CHECK_CONDITION(pK != NULL, COSE_ERR_INVALID_PARAMETER);
			if (!AES_KW_Encrypt(pRecipient, pK->v.bytes, (int) pK->length*8, pbContent, (int) cbContent, perr)) goto errorReturn;
		}
		else {
			if (!AES_KW_Encrypt(pRecipient, NULL, 0, pbContent, (int) cbContent, perr)) goto errorReturn;
		}
		break;

	case COSE_Algorithm_ECDH_ES_A128KW:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_128, pRecipient->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		if (!AES_KW_Encrypt(pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_ES_A192KW:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_192, pRecipient->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		if (!AES_KW_Encrypt(pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_ES_A256KW:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_256, pRecipient->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		if (!AES_KW_Encrypt(pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_SS_A128KW:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_128, pRecipient->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		if (!AES_KW_Encrypt(pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_SS_A192KW:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_192, pRecipient->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		if (!AES_KW_Encrypt(pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_SS_A256KW:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_256, pRecipient->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		if (!AES_KW_Encrypt(pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr)) goto errorReturn;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	for (pri = pRecipient->m_encrypt.m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr)) goto errorReturn;
	}

	//  Figure out the clean up

	fRet = true;

errorReturn:
	memset(rgbKey, 0, sizeof(rgbKey));
	if (pbKey != NULL) {
		memset(pbKey, 0, cbKey);
		COSE_FREE(pbKey, context);
	}
	if (pbSecret != NULL) COSE_FREE(pbSecret, context);
	if (pbContext != NULL) COSE_FREE(pbContext, context);
	if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
	if (ptmp != NULL) cn_cbor_free(ptmp CBOR_CONTEXT_PARAM);
	return fRet;
}

byte * _COSE_RecipientInfo_generateKey(COSE_RecipientInfo * pRecipient, int algIn, size_t cbitKeySize, cose_errback * perr)
{
	int alg;
	const cn_cbor * cn_Alg = _COSE_map_get_int(&pRecipient->m_encrypt.m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
	byte * pbContext = NULL;
	byte * pb = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pRecipient->m_encrypt.m_message.m_allocContext;
#endif
	const cn_cbor * pK;
	byte *pbSecret = NULL;

	CHECK_CONDITION(cn_Alg != NULL, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION((cn_Alg->type == CN_CBOR_UINT) || (cn_Alg->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
	alg = (int)cn_Alg->v.uint;

	_COSE_encode_protected(&pRecipient->m_encrypt.m_message, perr);

	pb = COSE_CALLOC(cbitKeySize / 8, 1, context);
	CHECK_CONDITION(pb != NULL, COSE_ERR_OUT_OF_MEMORY);

	switch (alg) {
	case COSE_Algorithm_Direct:
		CHECK_CONDITION(pRecipient->m_pkey != NULL, COSE_ERR_INVALID_PARAMETER);
			pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
			CHECK_CONDITION((pK != NULL) && (pK->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
			CHECK_CONDITION(pK->length == cbitKeySize / 8, COSE_ERR_INVALID_PARAMETER);
			memcpy(pb, pK->v.bytes, cbitKeySize / 8);
	break;

	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_Direct_HKDF_AES_128:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 128, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_Direct_HKDF_AES_256:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_ES_HKDF_256:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_ES_HKDF_512:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_SS_HKDF_256:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	case COSE_Algorithm_ECDH_SS_HKDF_512:
		if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	if (pbSecret != NULL) COSE_FREE(pbSecret, context);
	if (pbContext != NULL) COSE_FREE(pbContext, context);
	return pb;

errorReturn:

	if (pbSecret != NULL) COSE_FREE(pbSecret, context);
	if (pbContext != NULL) COSE_FREE(pbContext, context);
	if (pb != NULL) COSE_FREE(pb, context);
	return NULL;
}

bool COSE_Recipient_SetKey_secret(HCOSE_RECIPIENT hRecipient, const byte * rgbKey, int cbKey, const byte * rgbKid, int cbKid, cose_errback * perr)
{
	COSE_RecipientInfo * p;
	cn_cbor * cn_Temp = NULL;
	cn_cbor * cnTemp = NULL;
	cn_cbor_errback cbor_error;
	byte * pbTemp = NULL;
	byte * pbKey = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context;
#endif

	if (!IsValidRecipientHandle(hRecipient) || (rgbKey == NULL)) {
		if (perr != NULL) perr->err = COSE_ERR_CBOR;
		return false;
	}

	p = (COSE_RecipientInfo *)hRecipient;

#ifdef USE_CBOR_CONTEXT
	context = &p->m_encrypt.m_message.m_allocContext;
#endif

	cn_Temp = cn_cbor_int_create(COSE_Algorithm_Direct, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cn_Temp != NULL, cbor_error);
	if (!COSE_Recipient_map_put(hRecipient, COSE_Header_Algorithm, cn_Temp, COSE_UNPROTECT_ONLY, perr)) goto errorReturn;
	cn_Temp = NULL;

	if (cbKid > 0) {
		pbTemp = (byte *)COSE_CALLOC(cbKid, 1, context);
		CHECK_CONDITION(pbTemp != NULL, COSE_ERR_OUT_OF_MEMORY);

		memcpy(pbTemp, rgbKid, cbKid);
		cnTemp = cn_cbor_data_create(pbTemp, cbKid, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnTemp != NULL, cbor_error);
		pbTemp = NULL;

		if (!COSE_Recipient_map_put(hRecipient, COSE_Header_KID, cnTemp, COSE_UNPROTECT_ONLY, perr)) goto errorReturn;
	}

	pbKey = (byte *)COSE_CALLOC(cbKey, 1, context);
	CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);

	memcpy(pbKey, rgbKey, cbKey);

	cn_Temp = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cn_Temp != NULL, cbor_error);

	cnTemp = cn_cbor_int_create(4, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cnTemp != NULL, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_mapput_int(cn_Temp, COSE_Key_Type, cnTemp, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
	cnTemp = NULL;

	cnTemp = cn_cbor_data_create(pbKey, cbKey, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cnTemp != NULL, cbor_error);
	pbKey = NULL;
	CHECK_CONDITION_CBOR(cn_cbor_mapput_int(cn_Temp, -1, cnTemp, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
	cnTemp = NULL;

	if (!COSE_Recipient_SetKey(hRecipient, cn_Temp, perr)) goto errorReturn;
	cn_Temp = NULL;

	return true;

errorReturn:
	if (cn_Temp != NULL) CN_CBOR_FREE(cn_Temp, context);
	if (cnTemp != NULL) CN_CBOR_FREE(cnTemp, context);
	if (pbTemp != NULL) COSE_FREE(pbTemp, context);
	if (pbKey != NULL) COSE_FREE(pbKey, context);
	return false;
}

bool COSE_Recipient_SetKey(HCOSE_RECIPIENT h, const cn_cbor * pKey, cose_errback * perror)
{
	COSE_RecipientInfo * p;

	if (!IsValidRecipientHandle(h) || (pKey == NULL)) {
		if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
		return false;
	}



	p = (COSE_RecipientInfo *)h;
	p->m_pkey = pKey;

	return true;
}

/*!
* @brief Set the application external data for authentication
*
* Recipient data objects support the authentication of external application
* supplied data.  This function is provided to supply that data to the library.
*
* The external data is not copied, nor will be it freed when the handle is released.
*
* @param hcose  Handle for the COSE recipient data object
* @param pbEternalData  point to the external data
* @param cbExternalData size of the external data
* @param perr  location to return errors
* @return result of the operation.
*/

bool COSE_Recipient_SetExternal(HCOSE_RECIPIENT hcose, const byte * pbExternalData, size_t cbExternalData, cose_errback * perr)
{
	if (!IsValidRecipientHandle(hcose)) {
		if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
		return false;
	}

	return _COSE_SetExternal(&((COSE_RecipientInfo *)hcose)->m_encrypt.m_message, pbExternalData, cbExternalData, perr);
}


bool COSE_Recipient_map_put(HCOSE_RECIPIENT h, int key, cn_cbor * value, int flags, cose_errback * perror)
{
	if (!IsValidRecipientHandle(h) || (value == NULL)) {
		if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
		return false;
	}

	if (!_COSE_map_put(&((COSE_RecipientInfo *)h)->m_encrypt.m_message, key, value, flags, perror)) return false;

	if (key == COSE_Header_Algorithm) {
		if (value->type == CN_CBOR_INT) {
			switch (value->v.uint) {
			case COSE_Algorithm_Direct:
			case COSE_Algorithm_Direct_HKDF_AES_128:
			case COSE_Algorithm_Direct_HKDF_AES_256:
			case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
			case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
			case COSE_Algorithm_ECDH_ES_HKDF_256:
			case COSE_Algorithm_ECDH_ES_HKDF_512:
			case COSE_Algorithm_ECDH_SS_HKDF_256:
			case COSE_Algorithm_ECDH_SS_HKDF_512:
				((COSE_RecipientInfo *)h)->m_encrypt.m_message.m_flags |= 1;
				break;

			default:
				((COSE_RecipientInfo *)h)->m_encrypt.m_message.m_flags &= ~1;
				break;
			}
		}
		else {
			((COSE_RecipientInfo *)h)->m_encrypt.m_message.m_flags &= ~1;
		}
	}

	return true;
}


byte RgbDontUse4[8 * 1024];

bool BuildContextBytes(COSE * pcose, int algID, size_t cbitKey, byte ** ppbContext, size_t * pcbContext, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	cn_cbor * pArray;
	cn_cbor_errback cbor_error;
	bool fReturn = false;
	cn_cbor * cnT = NULL;
	cn_cbor * cnArrayT = NULL;
	cn_cbor * cnParam;
	byte * pbContext = NULL;
	size_t cbContext;

	pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(pArray != NULL, cbor_error);

	cnT = cn_cbor_int_create(algID, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnT, &cbor_error), cbor_error);
	cnT = NULL;

	cnArrayT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cnArrayT != NULL, cbor_error);

	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_U_nonce, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_U_name, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_U_other, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnArrayT, &cbor_error), cbor_error);
	cnArrayT = NULL;

	cnArrayT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cnArrayT != NULL, cbor_error);

	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_V_nonce, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_V_name, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_V_other, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnArrayT, &cbor_error), cbor_error);
	cnArrayT = NULL;

	cnArrayT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cnArrayT != NULL, cbor_error);

	cnT = cn_cbor_int_create(cbitKey, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
	cnT = NULL;

	cnParam = _COSE_arrayget_int(pcose, INDEX_PROTECTED);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_PUB_other, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnArrayT, &cbor_error), cbor_error);
	cnArrayT = NULL;


	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_PRIV, COSE_BOTH, perr);
	if (cnParam != NULL) {
		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
		CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnT, &cbor_error), cbor_error);
		cnT = NULL;
		cnParam = NULL;
	}

	cbContext = cn_cbor_encoder_write(RgbDontUse4, 0, sizeof(RgbDontUse4), pArray);
	CHECK_CONDITION(cbContext > 0, COSE_ERR_CBOR);
	pbContext = (byte *)COSE_CALLOC(cbContext, 1, context);
	CHECK_CONDITION(pbContext != NULL, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(cn_cbor_encoder_write(pbContext, 0, cbContext, pArray), COSE_ERR_CBOR);

	*ppbContext = pbContext;
	*pcbContext = cbContext;
	pbContext = NULL;
	fReturn = true;

returnHere:
	if (pbContext != NULL) COSE_FREE(pbContext, context);
	if (pArray != NULL) CN_CBOR_FREE(pArray, context);
	if (cnArrayT != NULL) CN_CBOR_FREE(cnArrayT, context);
	if (cnT != NULL) CN_CBOR_FREE(cnT, context);
	return fReturn;

errorReturn:
	fReturn = false;
	goto returnHere;
}

