/** \file MacMessage.c
 * Contains implementation of the functions related to HCOSE_MAC handle objects.
 */

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

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

#if INCLUDE_MAC

COSE *MacRoot = NULL;

/*! \private
 * @brief Test if a HCOSE_MAC handle is valid
 *
 *  Internal function to test if a MAC 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 IsValidMacHandle(HCOSE_MAC h)
{
	COSE_MacMessage *p = (COSE_MacMessage *)h;
	return _COSE_IsInList(MacRoot, (COSE *)p);
}

HCOSE_MAC COSE_Mac_Init(COSE_INIT_FLAGS flags,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	COSE_MacMessage *pobj = NULL;

	CHECK_CONDITION(flags == COSE_INIT_FLAGS_NONE, COSE_ERR_INVALID_PARAMETER);

	pobj = (COSE_MacMessage *)COSE_CALLOC(1, sizeof(COSE_MacMessage), context);
	CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);

	if (!_COSE_Init(flags, &pobj->m_message, COSE_mac_object,
			CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}

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

	return (HCOSE_MAC)pobj;

errorReturn:
	if (pobj != NULL) {
		_COSE_Mac_Release(pobj);
		COSE_FREE(pobj, context);
	}
	return NULL;
}

HCOSE_MAC _COSE_Mac_Init_From_Object(cn_cbor *cbor,
	COSE_MacMessage *pIn,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	COSE_MacMessage *pobj = pIn;
	cn_cbor *pRecipients = NULL;
	// cn_cbor * tmp;
	cose_errback error = {COSE_ERR_NONE};
	if (perr == NULL) {
		perr = &error;
	}

	if (pobj == NULL) {
		pobj =
			(COSE_MacMessage *)COSE_CALLOC(1, sizeof(COSE_MacMessage), context);
	}
	if (pobj == NULL) {
		perr->err = COSE_ERR_OUT_OF_MEMORY;
	errorReturn:
		if (pobj != NULL) {
			_COSE_Mac_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_MAC_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);
			if (pInfo == NULL) {
				goto errorReturn;
			}

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

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

	return (HCOSE_MAC)pobj;
}

bool COSE_Mac_Free(HCOSE_MAC h)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context;
#endif
	COSE_MacMessage *p = (COSE_MacMessage *)h;

	if (!IsValidMacHandle(h)) {
		return false;
	}

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

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

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

	_COSE_Mac_Release((COSE_MacMessage *)h);

	COSE_FREE((COSE_MacMessage *)h, context);

	return true;
}

bool _COSE_Mac_Release(COSE_MacMessage *p)
{
	COSE_RecipientInfo *pRecipient;
	COSE_RecipientInfo *pRecipient2;

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

	_COSE_Release(&p->m_message);

	return true;
}

bool COSE_Mac_SetContent(HCOSE_MAC cose,
	const byte *rgbContent,
	size_t cbContent,
	cose_errback *perr)
{
	COSE_MacMessage *p = (COSE_MacMessage *)cose;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &p->m_message.m_allocContext;
#endif
	cn_cbor *ptmp = NULL;
	cn_cbor_errback cbor_error;

	CHECK_CONDITION(IsValidMacHandle(cose), COSE_ERR_INVALID_PARAMETER);

	ptmp = cn_cbor_data_create(
		rgbContent, (int)cbContent, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);

	CHECK_CONDITION_CBOR(_COSE_array_replace(&p->m_message, ptmp, INDEX_BODY,
							 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
		cbor_error);
	ptmp = NULL;

	return true;

errorReturn:
	if (ptmp != NULL) {
		CN_CBOR_FREE(ptmp, context);
	}
	return false;
}

/*!
 * @brief Set the application external data for authentication
 *
 * MAC 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 MAC 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_Mac_SetExternal(HCOSE_MAC hcose,
	const byte *pbExternalData,
	size_t cbExternalData,
	cose_errback *perr)
{
	if (!IsValidMacHandle(hcose)) {
		if (perr != NULL) {
			perr->err = COSE_ERR_INVALID_PARAMETER;
		}
		return false;
	}

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

cn_cbor *COSE_Mac_map_get_int(HCOSE_MAC h,
	int key,
	int flags,
	cose_errback *perror)
{
	if (!IsValidMacHandle(h)) {
		if (perror != NULL) {
			perror->err = COSE_ERR_INVALID_PARAMETER;
		}
		return NULL;
	}

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

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

	return _COSE_map_put(
		&((COSE_MacMessage *)h)->m_message, key, value, flags, perror);
}
#endif

#if INCLUDE_MAC || INCLUDE_MAC0
bool _COSE_Mac_Build_AAD(COSE *pCose,
	const char *szContext,
	byte **ppbAuthData,
	size_t *pcbAuthData,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	cn_cbor *pAuthData = NULL;
	bool fRet = false;
	cn_cbor_errback cbor_error;
	cn_cbor *ptmp = NULL;
	cn_cbor *pcn;
	size_t cbAuthData;
	byte *pbAuthData = NULL;

	//  Build authenticated data
	//  Protected headers
	//  external data
	//  body

	pAuthData = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(pAuthData != NULL, COSE_ERR_OUT_OF_MEMORY);

	//  Add the context string

	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;

	// Add the protected attributes

	pcn = _COSE_arrayget_int(pCose, INDEX_PROTECTED);
	CHECK_CONDITION((pcn != NULL) && (pcn->type == CN_CBOR_BYTES),
		COSE_ERR_INVALID_PARAMETER);

	if ((pcn->length == 1) && (pcn->v.bytes[0] == 0xa0)) {
		ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA NULL);
	}
	else {
		ptmp = cn_cbor_data_create(
			pcn->v.bytes, (int)pcn->length, CBOR_CONTEXT_PARAM_COMMA NULL);
	}
	CHECK_CONDITION(ptmp != NULL, COSE_ERR_CBOR);

	CHECK_CONDITION(cn_cbor_array_append(pAuthData, ptmp, NULL), COSE_ERR_CBOR);
	ptmp = NULL;

	//  Add the external bytes

	ptmp = cn_cbor_data_create(pCose->m_pbExternal, (int)pCose->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;

	//  Add the content
	pcn = _COSE_arrayget_int(pCose, INDEX_BODY);
	ptmp = cn_cbor_data_create(
		pcn->v.bytes, (int)pcn->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;

	//  Turn it into bytes
	cbAuthData = cn_cbor_encode_size(pAuthData);
	CHECK_CONDITION(cbAuthData > 0, COSE_ERR_CBOR);
	pbAuthData = (byte *)COSE_CALLOC(cbAuthData, 1, context);
	CHECK_CONDITION(pbAuthData != NULL, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(cn_cbor_encoder_write(pbAuthData, 0, cbAuthData,
						pAuthData) == (ssize_t)cbAuthData,
		COSE_ERR_CBOR);

	*ppbAuthData = pbAuthData;
	*pcbAuthData = cbAuthData;
	pbAuthData = NULL;
	fRet = true;

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

#if INCLUDE_MAC
bool COSE_Mac_encrypt(HCOSE_MAC h, cose_errback *perr)
{
	COSE_MacMessage *pcose = (COSE_MacMessage *)h;

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

	return _COSE_Mac_compute(pcose, NULL, 0, "MAC", perr);

errorReturn:
	return false;
}
#endif

#if INCLUDE_MAC || INCLUDE_MAC0
bool _COSE_Mac_compute(COSE_MacMessage *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;
	size_t cbAuthData = 0;
	const byte *pbKey = NULL;
	byte *pbKeyNew = 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_CBC_MAC_128_64
		case COSE_Algorithm_CBC_MAC_128_64:
			cbitKey = 128;
			break;
#endif

#ifdef USE_AES_CBC_MAC_128_128
		case COSE_Algorithm_CBC_MAC_128_128:
			cbitKey = 128;
			break;
#endif

#ifdef USE_AES_CBC_MAC_256_64
		case COSE_Algorithm_CBC_MAC_256_64:
			cbitKey = 256;
			break;
#endif

#ifdef USE_AES_CBC_MAC_256_128
		case COSE_Algorithm_CBC_MAC_256_128:
			cbitKey = 256;
			break;
#endif

#ifdef USE_HMAC_256_64
		case COSE_Algorithm_HMAC_256_64:
			cbitKey = 256;
			break;
#endif

#ifdef USE_HMAC_256_256
		case COSE_Algorithm_HMAC_256_256:
			cbitKey = 256;
			break;
#endif

#ifdef USE_HMAC_384_384
		case COSE_Algorithm_HMAC_384_384:
			cbitKey = 384;
			break;
#endif

#ifdef USE_HMAC_512_512
		case COSE_Algorithm_HMAC_512_512:
			cbitKey = 512;
			break;
#endif

		default:
			FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
	}

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

	if (pbKeyIn != NULL) {
		CHECK_CONDITION(cbKeyIn == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);
		pbKey = pbKeyIn;
		cbKey = cbKeyIn;
	}
	else {
		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;
				CHECK_CONDITION(pbKeyNew != NULL, COSE_ERR_OUT_OF_MEMORY);
				pbKey = pbKeyNew;
			}
			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);
			pbKey = pbKeyNew;
			cbKey = cbitKey / 8;
			rand_bytes(pbKeyNew, cbKey);
		}
	}

	//  Build protected headers

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

	//  Build authenticated data

	if (!_COSE_Mac_Build_AAD(&pcose->m_message, szContext, &pbAuthData,
			&cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}

	switch (alg) {
#ifdef USE_AES_CBC_MAC_128_64
		case COSE_Algorithm_CBC_MAC_128_64:
			if (!AES_CBC_MAC_Create(
					pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_AES_CBC_MAC_256_64
		case COSE_Algorithm_CBC_MAC_256_64:
			if (!AES_CBC_MAC_Create(
					pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_AES_CBC_MAC_128_128
		case COSE_Algorithm_CBC_MAC_128_128:
			if (!AES_CBC_MAC_Create(
					pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_AES_CBC_MAC_256_128
		case COSE_Algorithm_CBC_MAC_256_128:
			if (!AES_CBC_MAC_Create(
					pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_HMAC_256_64
		case COSE_Algorithm_HMAC_256_64:
			if (!HMAC_Create(pcose, 256, 64, pbKey, cbKey, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_HMAC_256_256
		case COSE_Algorithm_HMAC_256_256:
			if (!HMAC_Create(pcose, 256, 256, pbKey, cbKey, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_HMAC_384_384
		case COSE_Algorithm_HMAC_384_384:
			if (!HMAC_Create(pcose, 384, 384, pbKey, cbKey, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_HMAC_512_512
		case COSE_Algorithm_HMAC_512_512:
			if (!HMAC_Create(pcose, 512, 512, pbKey, cbKey, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

		default:
			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

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

#if INCLUDE_COUNTERSIGNATURE
	if (pcose->m_message.m_counterSigners != NULL) {
		if (!_COSE_CounterSign_Sign(
				&pcose->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
			goto errorReturn;
		}
	}
#endif

	//  Figure out the clean up

	fRet = true;

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

#if INCLUDE_MAC
bool COSE_Mac_validate(HCOSE_MAC h, HCOSE_RECIPIENT hRecip, cose_errback *perr)
{
	cose_errback error;

	if (perr == NULL) {
		perr = &error;
	}
	
	COSE_MacMessage *pcose = (COSE_MacMessage *)h;
	COSE_RecipientInfo *pRecip = (COSE_RecipientInfo *)hRecip;

	CHECK_CONDITION(IsValidMacHandle(h) && IsValidRecipientHandle(hRecip),
		COSE_ERR_INVALID_PARAMETER);

	return _COSE_Mac_validate(pcose, pRecip, NULL, 0, "MAC", perr);

errorReturn:
	return false;
}
#endif

#if INCLUDE_MAC || INCLUDE_MAC0
bool _COSE_Mac_validate(COSE_MacMessage *pcose,
	COSE_RecipientInfo *pRecip,
	const byte *pbKeyIn,
	size_t cbKeyIn,
	const char *szContext,
	cose_errback *perr)
{
	byte *pbAuthData = NULL;
	size_t cbitKey = 0;
	bool fRet = false;

	int alg;
	const cn_cbor *cn = NULL;
	byte *pbKeyNew = NULL;
	const byte *pbKey = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = &pcose->m_message.m_allocContext;
#endif
	size_t cbAuthData;

	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) {
		goto errorReturn;
	}

	if (cn->type == CN_CBOR_TEXT) {
		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
	}
	else {
		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_CBC_MAC_128_64
			case COSE_Algorithm_CBC_MAC_128_64:
				cbitKey = 128;
				break;
#endif

#ifdef USE_AES_CBC_MAC_128_128
			case COSE_Algorithm_CBC_MAC_128_128:
				cbitKey = 128;
				break;
#endif

#ifdef USE_AES_CBC_MAC_256_64
			case COSE_Algorithm_CBC_MAC_256_64:
				cbitKey = 256;
				break;
#endif

#ifdef USE_AES_CBC_MAC_256_128
			case COSE_Algorithm_CBC_MAC_256_128:
				cbitKey = 256;
				break;
#endif

#ifdef USE_HMAC_256_64
			case COSE_Algorithm_HMAC_256_64:
				cbitKey = 256;
				break;
#endif

#ifdef USE_HMAC_256_256
			case COSE_Algorithm_HMAC_256_256:
				cbitKey = 256;
				break;
#endif

#ifdef USE_HMAC_384_384
			case COSE_Algorithm_HMAC_384_384:
				cbitKey = 384;
				break;
#endif

#ifdef USE_HMAC_512_512
			case COSE_Algorithm_HMAC_512_512:
				cbitKey = 512;
				break;
#endif
			default:
				FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
				break;
		}
	}

	//  Allocate the key if we have not already done so

	if (pbKeyIn != NULL) {
		CHECK_CONDITION(cbitKey / 8 == cbKeyIn, COSE_ERR_INVALID_PARAMETER);
		pbKey = pbKeyIn;
	}
	else {
		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 (pRecip == pRecipX) {
					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);
		}
	}

	//  Build authenticated data

	if (!_COSE_Mac_Build_AAD(&pcose->m_message, szContext, &pbAuthData,
			&cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}

	switch (alg) {
#ifdef USE_HMAC_256_256
		case COSE_Algorithm_HMAC_256_256:
			if (!HMAC_Validate(pcose, 256, 256, pbKey, cbitKey / 8, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_HMAC_256_64
		case COSE_Algorithm_HMAC_256_64:
			if (!HMAC_Validate(pcose, 256, 64, pbKey, cbitKey / 8, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_HMAC_384_384
		case COSE_Algorithm_HMAC_384_384:
			if (!HMAC_Validate(pcose, 384, 384, pbKey, cbitKey / 8, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_HMAC_512_512
		case COSE_Algorithm_HMAC_512_512:
			if (!HMAC_Validate(pcose, 512, 512, pbKey, cbitKey / 8, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_AES_CBC_MAC_128_64
		case COSE_Algorithm_CBC_MAC_128_64:
			if (!AES_CBC_MAC_Validate(pcose, 64, pbKey, cbitKey / 8, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_AES_CBC_MAC_256_64
		case COSE_Algorithm_CBC_MAC_256_64:
			if (!AES_CBC_MAC_Validate(pcose, 64, pbKey, cbitKey / 8, pbAuthData,
					cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_AES_CBC_MAC_128_128
		case COSE_Algorithm_CBC_MAC_128_128:
			if (!AES_CBC_MAC_Validate(pcose, 128, pbKey, cbitKey / 8,
					pbAuthData, cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

#ifdef USE_AES_CBC_MAC_256_128
		case COSE_Algorithm_CBC_MAC_256_128:
			if (!AES_CBC_MAC_Validate(pcose, 128, pbKey, cbitKey / 8,
					pbAuthData, cbAuthData, perr)) {
				goto errorReturn;
			}
			break;
#endif

		default:
			FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
			break;
	}

	fRet = true;

errorReturn:
	if (pbKeyNew != NULL) {
		memset(pbKeyNew, 0xff, cbitKey / 8);
		COSE_FREE(pbKeyNew, context);
	}

	return fRet;
}
#endif

#if INCLUDE_MAC
bool COSE_Mac_AddRecipient(HCOSE_MAC hMac,
	HCOSE_RECIPIENT hRecip,
	cose_errback *perr)
{
	COSE_RecipientInfo *pRecip;
	COSE_MacMessage *pMac;
	cn_cbor *pRecipients = NULL;
	cn_cbor *pRecipientsT = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = NULL;
#endif
	cn_cbor_errback cbor_error;

	CHECK_CONDITION(IsValidMacHandle(hMac), COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(IsValidRecipientHandle(hRecip), COSE_ERR_INVALID_PARAMETER);

	pMac = (COSE_MacMessage *)hMac;
	pRecip = (COSE_RecipientInfo *)hRecip;

	pRecip->m_recipientNext = pMac->m_recipientFirst;
	pMac->m_recipientFirst = pRecip;

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

	pRecipients = _COSE_arrayget_int(&pMac->m_message, INDEX_MAC_RECIPIENTS);
	if (pRecipients == NULL) {
		pRecipientsT =
			cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(pRecipientsT != NULL, cbor_error);

		CHECK_CONDITION_CBOR(
			_COSE_array_replace(&pMac->m_message, pRecipientsT,
				INDEX_MAC_RECIPIENTS, CBOR_CONTEXT_PARAM_COMMA & cbor_error),
			cbor_error);
		pRecipients = pRecipientsT;
		pRecipientsT = NULL;
	}

	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:
	if (pRecipientsT == NULL) {
		CN_CBOR_FREE(pRecipientsT, context);
	}
	return false;
}

HCOSE_RECIPIENT COSE_Mac_GetRecipient(HCOSE_MAC cose,
	int iRecipient,
	cose_errback *perr)
{
	int i;
	COSE_RecipientInfo *p;

	CHECK_CONDITION(IsValidMacHandle(cose), COSE_ERR_INVALID_PARAMETER);

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

errorReturn:
	return NULL;
}

#endif
