/** \file Encrypt.c
* Contains implementation of the functions related to HCOSE_ENVELOPED handle objects.
*/

#include <stdlib.h>
#ifndef __MBED__
#include <memory.h>
#else
#include <stddef.h>
#endif
#include <stdio.h>
#include <assert.h>

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

#if INCLUDE_ENCRYPT || INCLUDE_MAC
void _COSE_Enveloped_Release(COSE_Enveloped * p);

static COSE * EnvelopedRoot = NULL;
#endif

#if INCLUDE_ENCRYPT
/*! \private
* @brief Test if a HCOSE_ENVELOPED handle is valid
*
*  Internal function to test if a enveloped message 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 IsValidEnvelopedHandle(HCOSE_ENVELOPED h)
{
	COSE_Enveloped * p = (COSE_Enveloped *)h;
	return _COSE_IsInList(EnvelopedRoot, (COSE *) p);
}


/*!
* @brief Allocate and initialize an object for creation of an Enveloped message object
*
* Allocate and initialize the object used to create a COSE Enveloped message object.
* Supported flags are:
*  COSE_INIT_FLAG_DETACHED_CONTENT - content is not part of the message
*  COSE_INIT_NO_CBOR_FLAG - Do not emit the leading CBOR tag on the message.
* 
*  See the notes on the memory model for the use of the context variable.
*  Applications need to free the returned handle before deallocating the 
*  memory block that it was wrapped in for correct handle checking.
*
* @param flags Set of initialization flags from the COSE_INIT_FLAGS enum
* @param context CN_CBOR context allocator struture
* @param perr Location to return error specific information
* @returns handle to the newly allocated object
*/
HCOSE_ENVELOPED COSE_Enveloped_Init(COSE_INIT_FLAGS flags, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	COSE_Enveloped * pobj = (COSE_Enveloped *)COSE_CALLOC(1, sizeof(COSE_Enveloped), context);
	CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);

	if (!_COSE_Init(flags,&pobj->m_message, COSE_enveloped_object, CBOR_CONTEXT_PARAM_COMMA perr)) {
		_COSE_Enveloped_Release(pobj);
		COSE_FREE(pobj, context);
		return NULL;
	}

	_COSE_InsertInList(&EnvelopedRoot, &pobj->m_message);

	return (HCOSE_ENVELOPED) pobj;

errorReturn:
	return NULL;
}
#endif

#if INCLUDE_ENCRYPT || INCLUDE_MAC
HCOSE_ENVELOPED _COSE_Enveloped_Init_From_Object(cn_cbor * cbor, COSE_Enveloped * pIn, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	COSE_Enveloped * pobj = pIn;
	cn_cbor * pRecipients = NULL;
	cose_errback error = { 0 };
	if (perr == NULL) perr = &error;

	if (pobj == NULL) pobj = (COSE_Enveloped *)COSE_CALLOC(1, sizeof(COSE_Enveloped), context);
	if (pobj == NULL) {
		perr->err = COSE_ERR_OUT_OF_MEMORY;
	errorReturn:
		if (pobj != NULL) {
			_COSE_Enveloped_Release(pobj);
			if (pIn == NULL) COSE_FREE(pobj, context);
		}
		return NULL;
	}

	if (!_COSE_Init_From_Object(&pobj->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}

	pRecipients = _COSE_arrayget_int(&pobj->m_message, INDEX_RECIPIENTS);
	if (pRecipients != NULL) {
		CHECK_CONDITION(pRecipients->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);

		pRecipients = pRecipients->first_child;
		while (pRecipients != NULL) {
			COSE_RecipientInfo * pInfo = _COSE_Recipient_Init_From_Object(pRecipients, CBOR_CONTEXT_PARAM_COMMA perr);
			CHECK_CONDITION(pInfo != NULL, COSE_ERR_OUT_OF_MEMORY);

			pInfo->m_recipientNext = pobj->m_recipientFirst;
			pobj->m_recipientFirst = pInfo;
			pRecipients = pRecipients->next;
		}
	}

	if (pIn == NULL) _COSE_InsertInList(&EnvelopedRoot, &pobj->m_message);

	return(HCOSE_ENVELOPED) pobj;
}
#endif

#if INCLUDE_ENCRYPT
bool COSE_Enveloped_Free(HCOSE_ENVELOPED h)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context;
#endif
	COSE_Enveloped * p = (COSE_Enveloped *)h;

	if (!IsValidEnvelopedHandle(h)) return false;

	if (p->m_message.m_refCount > 1) {
		p->m_message.m_refCount--;
		return true;
	}

#ifdef USE_CBOR_CONTEXT
	context = &((COSE_Enveloped *)h)->m_message.m_allocContext;
#endif

	_COSE_RemoveFromList(&EnvelopedRoot, &p->m_message);

	_COSE_Enveloped_Release((COSE_Enveloped *)h);

	COSE_FREE((COSE_Enveloped *)h, context);

	return true;
}
#endif

#if INCLUDE_ENCRYPT || INCLUDE_MAC
void _COSE_Enveloped_Release(COSE_Enveloped * p)
{
	COSE_RecipientInfo * pRecipient1;
	COSE_RecipientInfo * pRecipient2;

	if (p->pbContent != NULL) COSE_FREE((void *) p->pbContent, &p->m_message.m_allocContext);
	//	if (p->pbIV != NULL) COSE_FREE(p->pbIV, &p->m_message.m_allocContext);

	for (pRecipient1 = p->m_recipientFirst; pRecipient1 != NULL; pRecipient1 = pRecipient2) {
		pRecipient2 = pRecipient1->m_recipientNext;
		COSE_Recipient_Free((HCOSE_RECIPIENT)pRecipient1);
	}

	_COSE_Release(&p->m_message);
}
#endif

#if INCLUDE_ENCRYPT
bool COSE_Enveloped_decrypt(HCOSE_ENVELOPED h, HCOSE_RECIPIENT hRecip, cose_errback * perr)
{
	COSE_Enveloped * pcose = (COSE_Enveloped *)h;
	COSE_RecipientInfo * pRecip = (COSE_RecipientInfo *)hRecip;
	bool f = false;

	CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(IsValidRecipientHandle(hRecip), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(pcose->m_recipientFirst != NULL, COSE_ERR_INVALID_PARAMETER);

	f = _COSE_Enveloped_decrypt(pcose, pRecip, NULL, 0, "Encrypt", perr);

	errorReturn:
	return f;
}
#endif

#if INCLUDE_ENCRYPT || INCLUDE_ENCRYPT0
bool _COSE_Enveloped_decrypt(COSE_Enveloped * pcose, COSE_RecipientInfo * pRecip, const byte *pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr)
{
	int alg;
	const cn_cbor * cn = NULL;
	byte * pbKeyNew = NULL;
	const byte * pbKey = NULL;
	size_t cbitKey = 0;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context;
#endif
	byte * pbAuthData = NULL;
	size_t cbAuthData;

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

	CHECK_CONDITION(!((pRecip != NULL) && (pbKeyIn != NULL)), COSE_ERR_INTERNAL);

	cn = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
	if (cn == NULL) {
	error:
	errorReturn:
		if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
		if (pbKeyNew != NULL) {
			memset(pbKeyNew, 0xff, cbitKey / 8);
			COSE_FREE(pbKeyNew, context);
		}
		return false;
	}
	CHECK_CONDITION((cn->type == CN_CBOR_UINT) || (cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
	alg = (int) cn->v.uint;

	switch (alg) {
#ifdef USE_AES_CCM_16_64_128
	case COSE_Algorithm_AES_CCM_16_64_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_16_128_128
	case COSE_Algorithm_AES_CCM_16_128_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_64_64_128
	case COSE_Algorithm_AES_CCM_64_64_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_64_128_128
	case COSE_Algorithm_AES_CCM_64_128_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_64_64_256
	case COSE_Algorithm_AES_CCM_64_64_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_CCM_16_128_256
	case COSE_Algorithm_AES_CCM_16_128_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_CCM_64_128_256
	case COSE_Algorithm_AES_CCM_64_128_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_CCM_16_64_256
	case COSE_Algorithm_AES_CCM_16_64_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_GCM_128
	case COSE_Algorithm_AES_GCM_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_GCM_192
	case COSE_Algorithm_AES_GCM_192:
		cbitKey = 192;
		break;
#endif

#ifdef USE_AES_GCM_256
	case COSE_Algorithm_AES_GCM_256:
		cbitKey = 256;
		break;
#endif

	default:
		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
		break;
	}

	//
	//  We are doing the enveloped item - so look for the passed in recipient
	//

	if (pbKeyIn != NULL) {
		CHECK_CONDITION(cbKeyIn == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);
		pbKey = pbKeyIn;
	}
#ifdef INCLUDE_ENCRYPT
	else {
		//  Allocate the key if we have not already done so

		if (pbKeyNew == NULL) {
			pbKeyNew = COSE_CALLOC(cbitKey / 8, 1, context);
			CHECK_CONDITION(pbKeyNew != NULL, COSE_ERR_OUT_OF_MEMORY);
			pbKey = pbKeyNew;
		}

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

		if (pRecip != NULL) {
			COSE_RecipientInfo * pRecipX;

			for (pRecipX = pcose->m_recipientFirst; pRecipX != NULL; pRecipX = pRecipX->m_recipientNext) {
				if (pRecipX == pRecip) {
					if (!_COSE_Recipient_decrypt(pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr)) goto errorReturn;
					break;
				}
				else if (pRecipX->m_encrypt.m_recipientFirst != NULL) {
					if (_COSE_Recipient_decrypt(pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr)) break;
				}
			}
			CHECK_CONDITION(pRecipX != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
		}
		else {
			for (pRecip = pcose->m_recipientFirst; pRecip != NULL; pRecip = pRecip->m_recipientNext) {
				if (_COSE_Recipient_decrypt(pRecip, NULL, alg, cbitKey, pbKeyNew, perr)) break;
			}
			CHECK_CONDITION(pRecip != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
		}
	}
#endif // INCLUDE_ENCRYPT

	//  Build authenticated data

	if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr)) goto errorReturn;

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

	switch (alg) {
#ifdef USE_AES_CCM_16_64_128
	case COSE_Algorithm_AES_CCM_16_64_128:
		if (!AES_CCM_Decrypt(pcose, 64, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_CCM_16_64_256
	case COSE_Algorithm_AES_CCM_16_64_256:
		if (!AES_CCM_Decrypt(pcose, 64, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_CCM_16_128_128
	case COSE_Algorithm_AES_CCM_16_128_128:
		if (!AES_CCM_Decrypt(pcose, 128, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_CCM_16_128_256
	case COSE_Algorithm_AES_CCM_16_128_256:
		if (!AES_CCM_Decrypt(pcose, 128, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_CCM_64_64_128
	case COSE_Algorithm_AES_CCM_64_64_128:
		if (!AES_CCM_Decrypt(pcose, 64, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_CCM_64_64_256
	case COSE_Algorithm_AES_CCM_64_64_256:
		if (!AES_CCM_Decrypt(pcose, 64, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_CCM_64_128_128
	case COSE_Algorithm_AES_CCM_64_128_128:
		if (!AES_CCM_Decrypt(pcose, 128, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_CCM_64_128_256
	case COSE_Algorithm_AES_CCM_64_128_256:
		if (!AES_CCM_Decrypt(pcose, 128, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_GCM_128
	case COSE_Algorithm_AES_GCM_128:
		if (!AES_GCM_Decrypt(pcose, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_GCM_192
	case COSE_Algorithm_AES_GCM_192:
		if (!AES_GCM_Decrypt(pcose, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

#ifdef USE_AES_GCM_256
	case COSE_Algorithm_AES_GCM_256:
		if (!AES_GCM_Decrypt(pcose, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
		break;
#endif

	default:
		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
		break;
	}

	if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
	if (pbKeyNew != NULL) COSE_FREE(pbKeyNew, context);
	if (perr != NULL) perr->err = COSE_ERR_NONE;

	return true;
}
#endif

#if INCLUDE_ENCRYPT
bool COSE_Enveloped_encrypt(HCOSE_ENVELOPED h, cose_errback * perr)
{
	COSE_Enveloped * pcose = (COSE_Enveloped *)h;

	CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(pcose->m_recipientFirst != NULL, COSE_ERR_INVALID_HANDLE);

	return _COSE_Enveloped_encrypt(pcose, NULL, 0, "Encrypt", perr);

errorReturn:
	return false;
}
#endif

#if INCLUDE_ENCRYPT || INCLUDE_ENCRYPT0
bool _COSE_Enveloped_encrypt(COSE_Enveloped * pcose, const byte * pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr)
{
	int alg;
	int t;
	COSE_RecipientInfo * pri;
	const cn_cbor * cn_Alg = NULL;
	byte * pbAuthData = NULL;
	size_t cbitKey;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
	bool fRet = false;
	byte * pbKeyNew = NULL;
	const byte * pbKey = NULL;
	size_t cbKey = 0;

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

	CHECK_CONDITION((cn_Alg->type != CN_CBOR_TEXT), COSE_ERR_UNKNOWN_ALGORITHM);
	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) {
#ifdef USE_AES_CCM_64_64_128
	case COSE_Algorithm_AES_CCM_64_64_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_16_128_128
	case COSE_Algorithm_AES_CCM_16_128_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_64_128_128
	case COSE_Algorithm_AES_CCM_64_128_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_16_64_128
	case COSE_Algorithm_AES_CCM_16_64_128:
		cbitKey = 128;
		break;
#endif

#ifdef USE_AES_CCM_64_64_256
	case COSE_Algorithm_AES_CCM_64_64_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_CCM_16_128_256
	case COSE_Algorithm_AES_CCM_16_128_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_CCM_64_128_256
	case COSE_Algorithm_AES_CCM_64_128_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_CCM_16_64_256
	case COSE_Algorithm_AES_CCM_16_64_256:
		cbitKey = 256;
		break;
#endif

#ifdef USE_AES_GCM_128
	case COSE_Algorithm_AES_GCM_128: 
		cbitKey = 128; 
		break;
#endif

#ifdef USE_AES_GCM_192
	case COSE_Algorithm_AES_GCM_192: 
		cbitKey = 192; 
		break;
#endif

#ifdef USE_AES_GCM_256
	case COSE_Algorithm_AES_GCM_256: 
		cbitKey = 256; 
		break;
#endif

	default:
		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
	}

	//  Enveloped or Encrypted?

	if (pbKeyIn != NULL) {
		CHECK_CONDITION(cbKeyIn == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);
		pbKey = pbKeyIn;
		cbKey = cbKeyIn;
	}
#ifdef INCLUDE_ENCRYPT
	else {
		//  If we are doing direct encryption - then recipient generates the key

		t = 0;
		for (pri = pcose->m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
			if (pri->m_encrypt.m_message.m_flags & 1) {
				CHECK_CONDITION(pbKey == NULL, COSE_ERR_INVALID_PARAMETER);

				t |= 1;
				pbKeyNew = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
				cbKey = cbitKey / 8;
				if (pbKeyNew == NULL) goto errorReturn;
			}
			else {
				t |= 2;
			}
		}
		CHECK_CONDITION(t != 3, COSE_ERR_INVALID_PARAMETER);

		if (t == 2) {
			pbKeyNew = (byte *)COSE_CALLOC(cbitKey / 8, 1, context);
			CHECK_CONDITION(pbKeyNew != NULL, COSE_ERR_OUT_OF_MEMORY);
			cbKey = cbitKey / 8;
			rand_bytes(pbKeyNew, cbKey);
		}
		pbKey = pbKeyNew;
	}
#endif // INCLUDE_ENCRYPT

	//  Build protected headers

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


#ifdef USE_COUNTER_SIGNATURES
	//  Setup Counter Signatures
	if (!_COSE_CountSign_create(&pcose->m_message, NULL, CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}
#endif

	//  Build authenticated data

	size_t cbAuthData = 0;
	if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr)) goto errorReturn;

	switch (alg) {
#ifdef USE_AES_CCM_16_64_128
	case COSE_Algorithm_AES_CCM_16_64_128:
		if (!AES_CCM_Encrypt(pcose, 64, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_CCM_16_64_256
	case COSE_Algorithm_AES_CCM_16_64_256:
		if (!AES_CCM_Encrypt(pcose, 64, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_CCM_16_128_128
	case COSE_Algorithm_AES_CCM_16_128_128:
		if (!AES_CCM_Encrypt(pcose, 128, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_CCM_16_128_256
	case COSE_Algorithm_AES_CCM_16_128_256:
		if (!AES_CCM_Encrypt(pcose, 128, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_CCM_64_64_128
	case COSE_Algorithm_AES_CCM_64_64_128:
		if (!AES_CCM_Encrypt(pcose, 64, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_CCM_64_64_256
	case COSE_Algorithm_AES_CCM_64_64_256:
		if (!AES_CCM_Encrypt(pcose, 64, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_CCM_64_128_128
	case COSE_Algorithm_AES_CCM_64_128_128:
		if (!AES_CCM_Encrypt(pcose, 128, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_CCM_64_128_256
	case COSE_Algorithm_AES_CCM_64_128_256:
		if (!AES_CCM_Encrypt(pcose, 128, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_GCM_128
	case COSE_Algorithm_AES_GCM_128:
		if (!AES_GCM_Encrypt(pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_GCM_192
	case COSE_Algorithm_AES_GCM_192:
		if (!AES_GCM_Encrypt(pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

#ifdef USE_AES_GCM_256
	case COSE_Algorithm_AES_GCM_256:
		if (!AES_GCM_Encrypt(pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
		break;
#endif

	default:
		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
	}

#ifdef INCLUDE_ENCRYPT        
	for (pri = pcose->m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr)) goto errorReturn;
	}
#endif // INCLUDE_ENCRYPT

	//  Figure out the clean up

	fRet = true;

errorReturn:
	if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
	if (pbKeyNew != NULL) {
		memset(pbKeyNew, 0, cbKey);
		COSE_FREE(pbKeyNew, context);
	}
	return fRet;
}
#endif

#if INCLUDE_ENCRYPT
bool COSE_Enveloped_SetContent(HCOSE_ENVELOPED h, const byte * rgb, size_t cb, cose_errback * perr)
{
	CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(rgb != NULL, COSE_ERR_INVALID_PARAMETER);

	return _COSE_Enveloped_SetContent((COSE_Enveloped *)h, rgb, cb, perr);

errorReturn:
	return false;
}

/*!
* @brief Set the application external data for authentication
*
* Enveloped 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 Enveloped 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_Enveloped_SetExternal(HCOSE_ENVELOPED hcose, const byte * pbExternalData, size_t cbExternalData, cose_errback * perr)
{
	CHECK_CONDITION(IsValidEnvelopedHandle(hcose), COSE_ERR_INVALID_HANDLE)
	CHECK_CONDITION((pbExternalData != NULL) || (cbExternalData == 0), COSE_ERR_INVALID_PARAMETER);

	return _COSE_SetExternal(&((COSE_Enveloped *)hcose)->m_message, pbExternalData, cbExternalData, perr);

errorReturn:
	return false;
}


bool _COSE_Enveloped_SetContent(COSE_Enveloped * cose, const byte * rgb, size_t cb, cose_errback * perror)
{
	byte * pb;
	cose->pbContent = pb = (byte *)COSE_CALLOC(cb, 1, &cose->m_message.m_allocContext);
	if (cose->pbContent == NULL) {
		if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
		return false;
	}
	memcpy(pb, rgb, cb);
	cose->cbContent = cb;

	return true;
}

/*! brief Retrieve header parameter from an enveloped message structure
*
* Retrieve a header parameter from the message.
* Retrieved object is the same as the one in the message - do not delete it
*
* @param[in]	h	Handle of recipient object
* @param[in]    key	Key to look for
* @param[in]	flags	What buckets should we look for the message
* @param[out]	perror	Location to return error codes
* @return	Object which is found or NULL
*/

cn_cbor * COSE_Enveloped_map_get_int(HCOSE_ENVELOPED h, int key, int flags, cose_errback * perror)
{
	if (!IsValidEnvelopedHandle(h)) {
		if (perror != NULL) perror->err = COSE_ERR_INVALID_HANDLE;
		return NULL;
	}

	return _COSE_map_get_int(&((COSE_Enveloped *)h)->m_message, key, flags, perror);
}


bool COSE_Enveloped_map_put_int(HCOSE_ENVELOPED h, int key, cn_cbor * value, int flags, cose_errback * perr)
{
	CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(value != NULL, COSE_ERR_INVALID_PARAMETER);

	return _COSE_map_put(&((COSE_Enveloped *)h)->m_message, key, value, flags, perr);

errorReturn:
	return false;
}

bool COSE_Enveloped_AddRecipient(HCOSE_ENVELOPED hEnc, HCOSE_RECIPIENT hRecip, cose_errback * perr)
{
	COSE_RecipientInfo * pRecip;
	COSE_Enveloped * pEncrypt;
	cn_cbor * pRecipients  = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context;
#endif
	cn_cbor_errback cbor_error;

	CHECK_CONDITION(IsValidEnvelopedHandle(hEnc), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(IsValidRecipientHandle(hRecip), COSE_ERR_INVALID_HANDLE);

	pEncrypt = (COSE_Enveloped *)hEnc;
	pRecip = (COSE_RecipientInfo *)hRecip;

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

	pRecip->m_recipientNext = pEncrypt->m_recipientFirst;
	pEncrypt->m_recipientFirst = pRecip;

	pRecipients = _COSE_arrayget_int(&pEncrypt->m_message, INDEX_RECIPIENTS);
	if (pRecipients == NULL) {
		pRecipients = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(pRecipients != NULL, cbor_error);

		if (!_COSE_array_replace(&pEncrypt->m_message, pRecipients, INDEX_RECIPIENTS, CBOR_CONTEXT_PARAM_COMMA &cbor_error)) {
			CN_CBOR_FREE(pRecipients, context);
			if (perr != NULL) perr->err = _MapFromCBOR(cbor_error);
			goto errorReturn;
		}
	}

	CHECK_CONDITION_CBOR(cn_cbor_array_append(pRecipients, pRecip->m_encrypt.m_message.m_cbor, &cbor_error), cbor_error);

	pRecip->m_encrypt.m_message.m_refCount++;

	return true;

errorReturn:
	return false;
}
#endif

#if INCLUDE_ENCRYPT || INCLUDE_ENCRYPT0 || INCLUDE_MAC || INCLUDE_MAC0
bool _COSE_Encrypt_Build_AAD(COSE * pMessage, byte ** ppbAAD, size_t * pcbAAD, const char * szContext, cose_errback * perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pMessage->m_allocContext;
#endif
	cn_cbor_errback cbor_error;
    byte  * pbAuthData = NULL;
	size_t cbAuthData;
    cn_cbor * pAuthData = NULL;
    cn_cbor * pItem = NULL;
	cn_cbor * ptmp = NULL;

	//  Build authenticated data
	pAuthData = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(pAuthData != NULL, cbor_error);

	ptmp = cn_cbor_string_create(szContext, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
	ptmp = NULL;

	pItem = _COSE_arrayget_int(pMessage, INDEX_PROTECTED);
	CHECK_CONDITION(pItem != NULL, COSE_ERR_INVALID_PARAMETER);
	if ((pItem->length == 1) && (pItem->v.bytes[0] == 0xa0)) {
		ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	}
	else {
		ptmp = cn_cbor_data_create(pItem->v.bytes, (int)pItem->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	}
	CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
	ptmp = NULL;

	ptmp = cn_cbor_data_create(pMessage->m_pbExternal, (int) pMessage->m_cbExternal, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
	CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
	ptmp = NULL;

	cbAuthData = cn_cbor_encode_size(pAuthData);
	pbAuthData = (byte *)COSE_CALLOC(cbAuthData, 1, context);
	CHECK_CONDITION(pbAuthData != NULL, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION((size_t)cn_cbor_encoder_write(pbAuthData, 0, cbAuthData, pAuthData) == cbAuthData, COSE_ERR_CBOR);

	*ppbAAD = pbAuthData;
	*pcbAAD = cbAuthData;

#if 0
        {
            printf("Encrypt* AAD = ");
            int iX;
            for (iX=0; iX < cbAuthData; iX++) {
                printf("%02x ", pbAuthData[iX]);
            }
            printf("\n");
        }
#endif
        

	return true;

errorReturn:
	if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
	if (ptmp != NULL) CN_CBOR_FREE(ptmp, NULL);
	if (pAuthData != NULL) CN_CBOR_FREE(pAuthData, context);
	return false;
}
#endif

#if INCLUDE_ENCRYPT
HCOSE_RECIPIENT COSE_Enveloped_GetRecipient(HCOSE_ENVELOPED cose, int iRecipient, cose_errback * perr)
{
	int i;
	COSE_RecipientInfo * p = NULL;

	CHECK_CONDITION(IsValidEnvelopedHandle(cose), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(iRecipient >= 0, COSE_ERR_INVALID_PARAMETER);

	p = ((COSE_Enveloped *)cose)->m_recipientFirst;
	for (i = 0; i < iRecipient; i++) {
		CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
		p = p->m_recipientNext;
	}
	if (p != NULL) p->m_encrypt.m_message.m_refCount++;

errorReturn:
	return (HCOSE_RECIPIENT)p;
}

#ifdef USE_COUNTER_SIGNATURES
bool COSE_Enveloped_AddCounterSigner(HCOSE_ENCRYPT hEnv, HCOSE_COUNTERSIGN hSign, cose_errback * perr)
{
	CHECK_CONDITION(IsValidEncryptHandle(hEnv), COSE_ERR_INVALID_HANDLE);
	return _COSE_CounterSign_add(&((COSE_Enveloped *)hEnv)->m_message, hSign, perr);

errorReturn:
	return false;
}

HCOSE_COUNTERSIGN COSE_Enveloped_GetCounterSigner(HCOSE_ENCRYPT h, int iSigner, cose_errback * perr)
{
	CHECK_CONDITION(IsValidEncryptHandle(h), COSE_ERR_INVALID_HANDLE);
	return _COSE_CounterSign_get(&((COSE_Enveloped *)h)->m_message, iSigner, perr);

errorReturn:
	return NULL;
}
#endif

#endif
