/** \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 "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(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;
	}

	//  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_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
