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

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

#ifdef USE_MBED_TLS

#include "mbedtls/ccm.h"
#include "mbedtls/md.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/gcm.h"
#include "mbedtls/ecp.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/nist_kw.h"

bool FUseCompressed = true;

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

bool AES_CCM_Decrypt(COSE_Enveloped * pcose, int TSize, int LSize, const byte * pbKey, size_t cbKey, const byte * pbCrypto, size_t cbCrypto, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{

	mbedtls_ccm_context ctx;
	int cbOut;
	byte * rgbOut = NULL;
	int NSize = 15 - (LSize/8);
	byte rgbIV[15] = { 0 };
	const cn_cbor * pIV = NULL;
	mbedtls_cipher_id_t cipher;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	mbedtls_ccm_init(&ctx);
	
        //  Setup the IV/Nonce and put it into the message
	pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL);
	if ((pIV == NULL) || (pIV->type!= CN_CBOR_BYTES)) {
		if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;

	errorReturn:
		if (rgbOut != NULL) COSE_FREE(rgbOut, context);
		mbedtls_ccm_free(&ctx);
		return false;
	}
	CHECK_CONDITION(pIV->length == NSize, COSE_ERR_INVALID_PARAMETER);
	memcpy(rgbIV, pIV->v.str, pIV->length);

	//  Setup and run the mbedTLS code
	cipher = MBEDTLS_CIPHER_ID_AES;
	
        CHECK_CONDITION(!mbedtls_ccm_setkey(&ctx, cipher, pbKey, cbKey*8), COSE_ERR_CRYPTO_FAIL);
	TSize /= 8; // Comes in in bits not bytes.

	cbOut = (int)  cbCrypto - TSize;
	rgbOut = (byte *)COSE_CALLOC(cbOut, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
        
		
	CHECK_CONDITION(!mbedtls_ccm_auth_decrypt(&ctx, cbOut, rgbIV, NSize, pbAuthData, cbAuthData, pbCrypto, rgbOut, &pbCrypto[cbOut], TSize), COSE_ERR_CRYPTO_FAIL);
        
	mbedtls_ccm_free(&ctx);
	pcose->pbContent = rgbOut;
	pcose->cbContent = cbOut;

	return true;
}


bool AES_CCM_Encrypt(COSE_Enveloped * pcose, int TSize, int LSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	mbedtls_ccm_context ctx;
	int cbOut;
	byte * rgbOut = NULL;
	int NSize = 15 - (LSize/8);
	const cn_cbor * cbor_iv = NULL;
	cn_cbor * cbor_iv_t = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
	cn_cbor * cnTmp = NULL;
	mbedtls_cipher_id_t cipher;
	byte rgbIV[16];
	byte * pbIV = NULL;
	cn_cbor_errback cbor_error;

        mbedtls_ccm_init(&ctx);

	cipher = MBEDTLS_CIPHER_ID_AES;			
	
	//  Setup the IV/Nonce and put it into the message
	cbor_iv = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, perr);
	if (cbor_iv == NULL) {
	
                pbIV = COSE_CALLOC(NSize, 1, context);
		CHECK_CONDITION(pbIV != NULL, COSE_ERR_OUT_OF_MEMORY);
		rand_bytes(pbIV, NSize);
		memcpy(rgbIV, pbIV, NSize);
		cbor_iv_t = cn_cbor_data_create(pbIV, NSize, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cbor_iv_t != NULL, cbor_error);
		pbIV = NULL;

		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t, COSE_UNPROTECT_ONLY, perr)) goto errorReturn;
		cbor_iv_t = NULL;
	}
	else {
		CHECK_CONDITION(cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION(cbor_iv->length == NSize, COSE_ERR_INVALID_PARAMETER);
		memcpy(rgbIV, cbor_iv->v.str, cbor_iv->length);
	}

	//  Setup and run the mbedTLS code
	
	//cbKey comes in bytes not bits
 	CHECK_CONDITION(!mbedtls_ccm_setkey(&ctx, cipher, pbKey, cbKey*8), COSE_ERR_CRYPTO_FAIL);
	
	TSize /= 8; // Comes in in bits not bytes.

        cbOut = pcose->cbContent; // M00BUG - This is a missing call?
	rgbOut = (byte *)COSE_CALLOC(cbOut+TSize, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(!mbedtls_ccm_encrypt_and_tag(&ctx, pcose->cbContent, rgbIV, NSize, pbAuthData, cbAuthData, pcose->pbContent, rgbOut, &rgbOut[pcose->cbContent], TSize), COSE_ERR_CRYPTO_FAIL);	

	cnTmp = cn_cbor_data_create(rgbOut, (int)pcose->cbContent + TSize, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR);
	rgbOut = NULL;

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

	mbedtls_ccm_free(&ctx);
	
	return true;

errorReturn:
	if (pbIV != NULL) COSE_FREE(pbIV, context);
	if (cbor_iv_t != NULL) COSE_FREE(cbor_iv_t, context);
	if (rgbOut != NULL) COSE_FREE(rgbOut, context);
	if (cnTmp != NULL) COSE_FREE(cnTmp, context);
	mbedtls_ccm_free(&ctx);
	return false;
}

bool AES_GCM_Decrypt(COSE_Enveloped * pcose, const byte * pbKey, size_t cbKey, const byte * pbCrypto, size_t cbCrypto, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	mbedtls_gcm_context ctx;
	int cbOut;
	byte * rgbOut = NULL;
	int outl = 0;
	byte rgbIV[15] = { 0 };
	const cn_cbor * pIV = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
	int TSize = 128 / 8;

	// Make it first so we can clean it up
	mbedtls_gcm_init(&ctx);


	//  Setup the IV/Nonce and put it into the message

	pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL);
	if ((pIV == NULL) || (pIV->type != CN_CBOR_BYTES)) {
		if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;

	errorReturn:
		if (rgbOut != NULL) COSE_FREE(rgbOut, context);
		mbedtls_gcm_free(&ctx);
		return false;
	}

	CHECK_CONDITION(pIV->length == 96 / 8, COSE_ERR_INVALID_PARAMETER);
	memcpy(rgbIV, pIV->v.str, pIV->length);

	//  Setup and run the OpenSSL code

	switch (cbKey) {
	case 128 / 8:
	case 192 / 8:
	case 256 / 8:
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
		break;
	}

	//  Do the setup for OpenSSL

	CHECK_CONDITION0(mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKey, cbKey * 8), COSE_ERR_CRYPTO_FAIL);

	//  

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

	//  Process content

	byte tag[128 / 8];
	CHECK_CONDITION0(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT, cbOut,
		rgbIV, 96 / 8,
		pbAuthData, cbAuthData,
		pbCrypto, rgbOut,
		TSize, tag), COSE_ERR_CRYPTO_FAIL);

	//  CHECK TAG HERE
	bool f = false;
	byte * pb = pbCrypto + cbOut;
	for (int i = 0; i < (unsigned int)TSize; i++) f |= (pb[i] != tag[i]);
	CHECK_CONDITION(!f, COSE_ERR_CRYPTO_FAIL);

	mbedtls_gcm_free(&ctx);

	pcose->pbContent = rgbOut;
	pcose->cbContent = cbOut;

	return true;
}

bool AES_GCM_Encrypt(COSE_Enveloped * pcose, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	mbedtls_gcm_context ctx;
	int cbOut;
	byte * rgbOut = NULL;
	int outl = 0;
	byte rgbIV[16] = { 0 };
	byte * pbIV = NULL;
	const cn_cbor * cbor_iv = NULL;
	cn_cbor * cbor_iv_t = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
	cn_cbor_errback cbor_error;

	// Make it first so we can clean it up
	mbedtls_gcm_init(&ctx);

	//  Setup the IV/Nonce and put it into the message

	cbor_iv = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, perr);
	if (cbor_iv == NULL) {
		pbIV = COSE_CALLOC(96, 1, context);
		CHECK_CONDITION(pbIV != NULL, COSE_ERR_OUT_OF_MEMORY);
		rand_bytes(pbIV, 96 / 8);
		memcpy(rgbIV, pbIV, 96 / 8);
		cbor_iv_t = cn_cbor_data_create(pbIV, 96 / 8, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
		CHECK_CONDITION_CBOR(cbor_iv_t != NULL, cbor_error);
		pbIV = NULL;

		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t, COSE_UNPROTECT_ONLY, perr)) goto errorReturn;
		cbor_iv_t = NULL;
	}
	else {
		CHECK_CONDITION(cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION(cbor_iv->length == 96 / 8, COSE_ERR_INVALID_PARAMETER);
		memcpy(rgbIV, cbor_iv->v.str, cbor_iv->length);
	}


	switch (cbKey * 8) {
	case 128:
	case 192:
	case 256:
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
		break;
	}

	//  Setup and run the OpenSSL code

	CHECK_CONDITION0(mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKey, cbKey * 8), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION0(mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT, rgbIV, 96 / 8, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);

	rgbOut = (byte *)COSE_CALLOC(pcose->cbContent + 128 / 8, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION0(mbedtls_gcm_update(&ctx, pcose->cbContent, pcose->pbContent, rgbOut), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION0(mbedtls_gcm_finish(&ctx, &rgbOut[pcose->cbContent], 128 / 8), COSE_ERR_CRYPTO_FAIL);

	cn_cbor * cnTmp = cn_cbor_data_create(rgbOut, (int)pcose->cbContent + 128 / 8, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR);
	rgbOut = NULL;
	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cnTmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);

	mbedtls_gcm_free(&ctx);
	return true;

errorReturn:
	if (pbIV != NULL) COSE_FREE(pbIV, context);
	if (cbor_iv_t != NULL) COSE_FREE(cbor_iv_t, context);
	if (rgbOut != NULL) COSE_FREE(rgbOut, context);
	mbedtls_gcm_free(&ctx);
	return false;
}
/*

bool AES_CBC_MAC_Create(COSE_MacMessage * pcose, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	const EVP_CIPHER * pcipher = NULL;
	EVP_CIPHER_CTX ctx;
	int cbOut;
	byte rgbIV[16] = { 0 };
	byte * rgbOut = NULL;
	bool f = false;
	unsigned int i;
	cn_cbor * cn = NULL;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	EVP_CIPHER_CTX_init(&ctx);

	rgbOut = COSE_CALLOC(16, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	switch (cbKey*8) {
	case 128:
		pcipher = EVP_aes_128_cbc();
		break;

	case 256:
		pcipher = EVP_aes_256_cbc();
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	//  Setup and run the OpenSSL code

	CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, pcipher, NULL, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);

	for (i = 0; i < (unsigned int)cbAuthData / 16; i++) {
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pbAuthData + (i * 16), 16), COSE_ERR_CRYPTO_FAIL);
	}
	if (cbAuthData % 16 != 0) {
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pbAuthData + (i * 16), cbAuthData % 16), COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, rgbIV, 16 - (cbAuthData % 16)), COSE_ERR_CRYPTO_FAIL);
	}

	cn = cn_cbor_data_create(rgbOut, TSize / 8, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(cn != NULL, COSE_ERR_OUT_OF_MEMORY);
	rgbOut = NULL;

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

	EVP_CIPHER_CTX_cleanup(&ctx);
	return !f;

errorReturn:
	if (rgbOut != NULL) COSE_FREE(rgbOut, context);
	if (cn != NULL) CN_CBOR_FREE(cn, context);
	EVP_CIPHER_CTX_cleanup(&ctx);
	return false;
}

bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	const EVP_CIPHER * pcipher = NULL;
	EVP_CIPHER_CTX ctx;
	int cbOut;
	byte rgbIV[16] = { 0 };
	byte rgbTag[16] = { 0 };
	bool f = false;
	unsigned int i;

	switch (cbKey*8) {
	case 128:
		pcipher = EVP_aes_128_cbc();
		break;

	case 256:
		pcipher = EVP_aes_256_cbc();
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	//  Setup and run the OpenSSL code

	EVP_CIPHER_CTX_init(&ctx);
	CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, pcipher, NULL, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);

	TSize /= 8;

	for (i = 0; i < (unsigned int) cbAuthData / 16; i++) {
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbTag, &cbOut, pbAuthData+(i*16), 16), COSE_ERR_CRYPTO_FAIL);
	}
	if (cbAuthData % 16 != 0) {
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbTag, &cbOut, pbAuthData + (i * 16), cbAuthData % 16), COSE_ERR_CRYPTO_FAIL);
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbTag, &cbOut, rgbIV, 16 - (cbAuthData % 16)), COSE_ERR_CRYPTO_FAIL);
	}

	cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR);

	for (i = 0; i < (unsigned int)TSize; i++) f |= (cn->v.bytes[i] != rgbTag[i]);

	EVP_CIPHER_CTX_cleanup(&ctx);
	return !f;

errorReturn:
	EVP_CIPHER_CTX_cleanup(&ctx);
	return false;
}

#if 0
//  We are doing CBC-MAC not CMAC at this time
bool AES_CMAC_Validate(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
{
	CMAC_CTX * pctx = NULL;
	const EVP_CIPHER * pcipher = NULL;
	byte * rgbOut = NULL;
	size_t cbOut;
	bool f = false;
	unsigned int i;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	pctx = CMAC_CTX_new();


	switch (KeySize) {
	case 128: pcipher = EVP_aes_128_cbc(); break;
	case 256: pcipher = EVP_aes_256_cbc(); break;
	default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
	}

	rgbOut = COSE_CALLOC(128/8, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(CMAC_Init(pctx, pcose->pbKey, pcose->cbKey, pcipher, NULL ) == 1, COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(CMAC_Update(pctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(CMAC_Final(pctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);

	cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR);

	for (i = 0; i < (unsigned int)TagSize / 8; i++) f |= (cn->v.bytes[i] != rgbOut[i]);

	COSE_FREE(rgbOut, context);
	CMAC_CTX_cleanup(pctx);
	CMAC_CTX_free(pctx);
	return !f;

errorReturn:
	COSE_FREE(rgbOut, context);
	CMAC_CTX_cleanup(pctx);
	CMAC_CTX_free(pctx);
	return false;

}
#endif

bool HKDF_AES_Expand(COSE * pcose, size_t cbitKey, const byte * pbPRK, size_t cbPRK, const byte * pbInfo, size_t cbInfo, byte * pbOutput, size_t cbOutput, cose_errback * perr)
{
	const EVP_CIPHER * pcipher = NULL;
	EVP_CIPHER_CTX ctx;
	int cbOut;
	byte rgbIV[16] = { 0 };
	byte bCount = 1;
	size_t ib;
	byte rgbDigest[128 / 8];
	int cbDigest = 0;
	byte rgbOut[16];

	EVP_CIPHER_CTX_init(&ctx);

	switch (cbitKey) {
	case 128:
		pcipher = EVP_aes_128_cbc();
		break;

	case 256:
		pcipher = EVP_aes_256_cbc();
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	CHECK_CONDITION(cbPRK == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);

	//  Setup and run the OpenSSL code


	for (ib = 0; ib < cbOutput; ib += 16, bCount += 1) {
		size_t ib2;

		CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, pcipher, NULL, pbPRK, rgbIV), COSE_ERR_CRYPTO_FAIL);

		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, rgbDigest, cbDigest), COSE_ERR_CRYPTO_FAIL);
		for (ib2 = 0; ib2 < cbInfo; ib2+=16) {
			CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pbInfo+ib2, (int) MIN(16, cbInfo-ib2)), COSE_ERR_CRYPTO_FAIL);
		}
		CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, &bCount, 1), COSE_ERR_CRYPTO_FAIL);
		if ((cbInfo + 1) % 16 != 0) {
			CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, rgbIV, (int) 16-(cbInfo+1)%16), COSE_ERR_CRYPTO_FAIL);
		}
		memcpy(rgbDigest, rgbOut, cbOut);
		cbDigest = cbOut;
		memcpy(pbOutput + ib, rgbDigest, MIN(16, cbOutput - ib));
	}

	EVP_CIPHER_CTX_cleanup(&ctx);
	return true;

errorReturn:
	EVP_CIPHER_CTX_cleanup(&ctx);
	return false;
}
*/

bool HKDF_Extract(COSE * pcose, const byte * pbKey, size_t cbKey, size_t cbitDigest, byte * rgbDigest, size_t * pcbDigest, CBOR_CONTEXT_COMMA cose_errback * perr)
{
    mbedtls_md_info_t * pmd;
    mbedtls_md_type_t mdType;

    int cbSalt;
    cn_cbor * cnSalt;
    unsigned int cbDigest;

    if (0) {
    errorReturn:
        return false;
    }

    switch (cbitDigest) {
    case 256: mdType = MBEDTLS_MD_SHA256; cbDigest = 256 / 8;  break;
    case 384: mdType = MBEDTLS_MD_SHA384; cbDigest = 384 / 8; break;
    case 512: mdType = MBEDTLS_MD_SHA512; cbDigest = 512 / 8; break;
    default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
    }

    pmd = mbedtls_md_info_from_type(mdType);
    if (pmd == NULL) goto errorReturn;

    cbSalt = 0;
    byte * pbSalt = NULL;

    cnSalt = _COSE_map_get_int(pcose, COSE_Header_HKDF_salt, COSE_BOTH, perr);

    if (cnSalt != NULL) {
        pbSalt = cnSalt->v.bytes;
		cbSalt = (int)cnSalt->length;
    }

    CHECK_CONDITION0(mbedtls_hkdf_extract(pmd, pbSalt, cbSalt, pbKey, cbKey, rgbDigest), 0);

    *pcbDigest = cbDigest;

    return true;
}

bool HKDF_Expand(COSE * pcose, size_t cbitDigest, const byte * pbPRK, size_t cbPRK, const byte * pbInfo, size_t cbInfo, byte * pbOutput, size_t cbOutput, cose_errback * perr)
{
	mbedtls_md_type_t mdType;
	mbedtls_md_info_t * pmd;

	size_t ib;
    int cbSalt;
    unsigned int cbDigest = 0;
    byte bCount = 1;

    if (0) {
    errorReturn:
        return false;
    }

    switch (cbitDigest) {
    case 256: mdType = MBEDTLS_MD_SHA256; cbDigest = 256 / 8;  break;
    case 384: mdType = MBEDTLS_MD_SHA384; cbDigest = 384 / 8; break;
    case 512: mdType = MBEDTLS_MD_SHA512; cbDigest = 512 / 8; break;
    default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
    }

    pmd = mbedtls_md_info_from_type(mdType);
    if (pmd == NULL) goto errorReturn;


    if (mbedtls_hkdf_expand(pmd, pbPRK, cbPRK, pbInfo, cbInfo, pbOutput, cbOutput) != 0) {
        goto errorReturn;
    }

    return true;

}
/*
void dump_output(byte* b, size_t s){
	for(int i = 0; i < s; i++){
		printf("%02x", *b);
		b++;
	}
	printf("\n");
}

void diff(unsigned char* a, size_t a_l, unsigned char* b, size_t b_l){
	size_t s;
	s = (a_l < b_l) ? a_l : b_l;
	unsigned char* tmp = a;
	printf("size = %d\n",s );
//	printf("%02x\n", *tmp);
	int i;
	for(i = 0; i < s; ++i){
		printf("%02x", *tmp);
		tmp++;
	}
	printf("\n");

	tmp = b;
	for(i = 0; i < s; ++i){
		printf("%02x", *tmp);
		tmp++;
	}
	printf("\n");

	for(i = 0; i < s; ++i){

		if(*a != *b){
			printf("^^");

		} else {
			printf("__");

		}

		a++;
		b++;
	}
	printf("\n");
}
*/

bool HMAC_Create(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	byte * rgbOut = NULL;
//	unsigned int cbOut;
	mbedtls_md_context_t contx;
	const char* md_name;
	const struct mbedtls_md_info_t * info;

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

	switch (HSize) {
		case 256: md_name = "SHA256"; break;
		case 384: md_name = "SHA384"; break;
		case 512: md_name = "SHA512"; break;
		default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
	}

	if (0) {
	errorReturn:
		COSE_FREE(rgbOut, context);
		mbedtls_md_free(&contx); 
		return false;
	}

	mbedtls_md_init(&contx);
	info = mbedtls_md_info_from_string (md_name);
	mbedtls_md_setup( &contx, info, 1 );

	rgbOut = COSE_CALLOC(mbedtls_md_get_size(info), 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(!(mbedtls_md_hmac_starts (&contx, pbKey, cbKey)), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(!(mbedtls_md_hmac_update (&contx, pbAuthData, cbAuthData)), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(!(mbedtls_md_hmac_finish (&contx, rgbOut)), COSE_ERR_CRYPTO_FAIL);

	CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cn_cbor_data_create(rgbOut, TSize / 8, CBOR_CONTEXT_PARAM_COMMA NULL), INDEX_MAC_TAG, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);

	mbedtls_md_free(&contx); 
	return true;
}

bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
	mbedtls_md_context_t contx;
	const char* md_name;
	const struct mbedtls_md_info_t * info;
	byte * rgbOut = NULL;
	unsigned int cbOut;
	bool f = false;
	unsigned int i;

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

	switch (HSize) {
		case 256: md_name = "SHA256"; break;
		case 384: md_name = "SHA384"; break;
		case 512: md_name = "SHA512"; break;
		default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
	}

	mbedtls_md_init(&contx);
	info = mbedtls_md_info_from_string (md_name);
	mbedtls_md_setup( &contx, info, 1 );
	
	cbOut = mbedtls_md_get_size(info);
	rgbOut = COSE_CALLOC(cbOut, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(!(mbedtls_md_hmac_starts (&contx, pbKey, cbKey)), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(!(mbedtls_md_hmac_update (&contx, pbAuthData, cbAuthData)), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(!(mbedtls_md_hmac_finish (&contx, rgbOut)), COSE_ERR_CRYPTO_FAIL);

	cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR);

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

	mbedtls_md_free(&contx); 
	return !f;

errorReturn:
	COSE_FREE(rgbOut, context);
	mbedtls_md_free(&contx); 
	return false;
}

#define COSE_Key_EC_Curve -1
#define COSE_Key_EC_X -2
#define COSE_Key_EC_Y -3
#define COSE_Key_EC_d -4

bool ECKey_From(const cn_cbor * pKey, mbedtls_ecp_keypair *keypair, cose_errback * perr)
{
	byte  rgbKey[MBEDTLS_ECP_MAX_PT_LEN];
	int cbKey;
	int cbGroup;
	const cn_cbor * p;
	mbedtls_ecp_group_id groupId;

	p = cn_cbor_mapget_int(pKey, COSE_Key_Type);
	CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
	if(p->type == CN_CBOR_UINT) {
		CHECK_CONDITION(p->v.uint == COSE_Key_Type_EC2, COSE_ERR_INVALID_PARAMETER);
	}
	else {
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

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

	switch (p->v.uint) {
	case 1: // P-256
		groupId = MBEDTLS_ECP_DP_SECP256R1;
		break;

	case 2: // P-384
		groupId = MBEDTLS_ECP_DP_SECP384R1;
		break;

	case 3: // P-521
		groupId = MBEDTLS_ECP_DP_SECP521R1;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	CHECK_CONDITION(mbedtls_ecp_group_load(&keypair->grp, groupId) == 0, COSE_ERR_INVALID_PARAMETER);
	cbGroup = (keypair->grp.nbits + 7) / 8;

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

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Y);
	CHECK_CONDITION((p != NULL), COSE_ERR_INVALID_PARAMETER);
	if (p->type == CN_CBOR_BYTES) {
		rgbKey[0] = 0x04;
		cbKey = cbGroup * 2 + 1;
		CHECK_CONDITION(p->length == cbGroup, COSE_ERR_INVALID_PARAMETER);
		memcpy(rgbKey + p->length + 1, p->v.str, p->length);
	}
	else if (p->type == CN_CBOR_TRUE) {
		cbKey = cbGroup + 1;
		rgbKey[0] = 0x03;
	}
	else if (p->type == CN_CBOR_FALSE) {
		cbKey = cbGroup + 1;
		rgbKey[0] = 0x02;
	}
	else FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);

	CHECK_CONDITION(mbedtls_ecp_point_read_binary(&keypair->grp, &keypair->Q, rgbKey, cbKey) == 0, COSE_ERR_INVALID_PARAMETER);

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_d);
	if (p != NULL) {
		CHECK_CONDITION(p->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION(mbedtls_mpi_read_binary( &keypair->d, p->v.bytes, p->length) == 0, COSE_ERR_CRYPTO_FAIL);
	}
	return true;

errorReturn:
	return false;
}

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

	pgroup = EC_KEY_get0_group(pKey);
	CHECK_CONDITION(pgroup != NULL, COSE_ERR_INVALID_PARAMETER);

	switch (EC_GROUP_get_curve_name(pgroup)) {
	case NID_X9_62_prime256v1:		cose_group = 1;		break;
	case NID_secp384r1: cose_group = 2; break;
	case NID_secp521r1: cose_group = 3; break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

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

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

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

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

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

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

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

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

bool ECDSA_Sign(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
	byte rgbDigest[MBEDTLS_MD_MAX_SIZE];
	uint8_t * pbSig = NULL;
	cn_cbor_errback cbor_error;
	int cbR;
	mbedtls_md_type_t mdType;
	const mbedtls_md_info_t *pmdInfo;
	mbedtls_ecp_keypair keypair;
	mbedtls_mpi r;
	mbedtls_mpi s;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pSigner->m_allocContext;
#endif
	cn_cbor * p = NULL;
	bool result = false;

	mbedtls_ecp_keypair_init(&keypair);
	mbedtls_mpi_init(&r);
	mbedtls_mpi_init(&s);

	if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn;

	CHECK_CONDITION(keypair.d.n != 0, COSE_ERR_INVALID_PARAMETER);

	switch(cbitDigest)
	{
	case 256:
		mdType = MBEDTLS_MD_SHA256;
		break;

	case 384:
		mdType = MBEDTLS_MD_SHA384;
		break;

	case 512:
		mdType = MBEDTLS_MD_SHA512;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	pmdInfo = mbedtls_md_info_from_type(mdType);
	CHECK_CONDITION(pmdInfo != NULL, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(mbedtls_md(pmdInfo, rgbToSign, cbToSign, rgbDigest) == 0, COSE_ERR_INVALID_PARAMETER);

	CHECK_CONDITION(mbedtls_ecdsa_sign_det(&keypair.grp, &r, &s, &keypair.d, rgbDigest, mbedtls_md_get_size(pmdInfo), mdType) == 0, COSE_ERR_CRYPTO_FAIL);

	cbR = (keypair.grp.nbits + 7) / 8;

	pbSig = COSE_CALLOC(cbR, 2, context);
	CHECK_CONDITION(pbSig != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(mbedtls_mpi_write_binary(&r, pbSig, cbR) == 0, COSE_ERR_INTERNAL);
	CHECK_CONDITION(mbedtls_mpi_write_binary(&s, pbSig + cbR, cbR) == 0, COSE_ERR_INTERNAL);

	p = cn_cbor_data_create(pbSig, cbR*2, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
	CHECK_CONDITION_CBOR(p != NULL, cbor_error);

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

	p = NULL;
	pbSig = NULL;
	result = true;

errorReturn:
	cn_cbor_free(p CBOR_CONTEXT_PARAM);
	COSE_FREE(pbSig, context);
	mbedtls_mpi_free(&r);
	mbedtls_mpi_free(&s);
	mbedtls_ecp_keypair_free(&keypair);
	return result;
#else
	return false;
#endif
}

bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
	mbedtls_ecp_keypair keypair;
	mbedtls_mpi r;
	mbedtls_mpi s;
	mbedtls_md_type_t mdType;
	const mbedtls_md_info_t *pmdInfo;
	byte rgbDigest[MBEDTLS_MD_MAX_SIZE];
	cn_cbor * pSig;
	bool result = false;

	mbedtls_ecp_keypair_init(&keypair);
	mbedtls_mpi_init(&r);
	mbedtls_mpi_init(&s);

	if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn;

	switch(cbitDigest)
	{
	case 256:
		mdType = MBEDTLS_MD_SHA256;
		break;

	case 384:
		mdType = MBEDTLS_MD_SHA384;
		break;

	case 512:
		mdType = MBEDTLS_MD_SHA512;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	pmdInfo = mbedtls_md_info_from_type(mdType);
	CHECK_CONDITION(pmdInfo != NULL, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(mbedtls_md(pmdInfo, rgbToSign, cbToSign, rgbDigest) == 0, COSE_ERR_INVALID_PARAMETER);

	pSig = _COSE_arrayget_int(pSigner, index);
	CHECK_CONDITION((pSig != NULL) && (pSig->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);

	CHECK_CONDITION(mbedtls_mpi_read_binary( &r, pSig->v.bytes, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(mbedtls_mpi_read_binary( &s, pSig->v.bytes + pSig->length / 2, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(mbedtls_ecdsa_verify(&keypair.grp, rgbDigest, mbedtls_md_get_size(pmdInfo), &keypair.Q, &r, &s) == 0, COSE_ERR_CRYPTO_FAIL);

	result = true;

errorReturn:
	mbedtls_mpi_free(&r);
	mbedtls_mpi_free(&s);
	mbedtls_ecp_keypair_free(&keypair);
	return result;
}

#ifdef MBEDTLS_NIST_KW_C
bool AES_KW_Decrypt(COSE_Enveloped * pcose, const byte * pbKeyIn, size_t cbitKey, const byte * pbCipherText, size_t cbCipherText, byte * pbKeyOut, int * pcbKeyOut, cose_errback * perr)
{
    mbedtls_nist_kw_context ctx;

    mbedtls_nist_kw_init(&ctx);

    CHECK_CONDITION0(mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKeyIn, cbitKey, FALSE), COSE_ERR_CRYPTO_FAIL);

    CHECK_CONDITION0(mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, pbCipherText, cbCipherText,
                                            pbKeyOut, pcbKeyOut, cbCipherText-8), COSE_ERR_CRYPTO_FAIL);

    mbedtls_nist_kw_free(&ctx);
    return true;

errorReturn:
    mbedtls_nist_kw_free(&ctx);
    return false;
}

bool AES_KW_Encrypt(COSE_RecipientInfo * pcose, const byte * pbKeyIn, int cbitKey, const byte *  pbContent, int  cbContent, cose_errback * perr)
{
    byte  *pbOut = NULL;
#ifdef USE_CBOR_CONTEXT
    cn_cbor_context * context = &pcose->m_encrypt.m_message.m_allocContext;
#endif
    cn_cbor * cnTmp = NULL;
    mbedtls_nist_kw_context ctx;
    size_t cbOut;

    mbedtls_nist_kw_init(&ctx);

    pbOut = COSE_CALLOC(cbContent + 8, 1, context);
    CHECK_CONDITION(pbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

    CHECK_CONDITION0(mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, pbKeyIn, cbitKey, FALSE), COSE_ERR_CRYPTO_FAIL);

    CHECK_CONDITION0(mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, pbContent, cbContent,
                                          pbOut, &cbOut, cbContent+8), COSE_ERR_CRYPTO_FAIL);

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

    mbedtls_nist_kw_free(&ctx);
    return true;

errorReturn:
    COSE_FREE(cnTmp, context);
    if (pbOut != NULL) COSE_FREE(pbOut, context);
    mbedtls_nist_kw_free(&ctx);
    return false;
}
#endif // MBEDTLS_NIST_KW_C

/*
//#include <stdio.h> //TODO
void rand_bytes(byte * pb, size_t cb){
//ctx->aes_ctx->rk e null... i callchainen längst in. prova istället:
//kolla https://tls.mbed.org/kb/how-to/add-a-random-generator
        //init random
       mbedtls_ctr_drbg_context ctr_drbg;
          char *personalization = "my_app_specific_string";

        ret = mbedtls_ctr_drbg_init( &ctr_drbg, mbedtls_entropy_func, &entropy,
                                         (const unsigned char *) personalization,
                                                             strlen( personalization ) ); 
        
        if(ret != 0) {
            //printf TODO
        }    
    
        mbedtls_ctr_drbg_random(&ctx,pb, cb); 	

	mbedtls_ctr_drbg_free(&ctx);	
        printf("rand byute done\n");
}*/
//TODO HOW TO GENERATE GOOD RANDOM BYTES
#if 0
static const unsigned char entropy_source_pr[96] =
   { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
     0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
     0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
     0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
     0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
     0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
     0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
     0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
     0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
     0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
     0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
     0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
#endif

static const unsigned char nonce_pers_pr[16] =
     { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
      0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };

/*
static size_t test_offset;
static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len ) {
    const unsigned char *p = data;
    memcpy( buf, p + test_offset, len );
    test_offset += len;
    return( 0 );
 }
*/

mbedtls_ctr_drbg_context ctx;
int ctx_setup = 0;
mbedtls_entropy_context entropy;

void rand_bytes(byte* pb, size_t cb){
     
    // unsigned char buf[16];

    if (!ctx_setup) {
        mbedtls_entropy_init(&entropy);
        
        mbedtls_ctr_drbg_init( &ctx );
     
        mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_entropy_func, (void *) &entropy, nonce_pers_pr, 16, 32 );

        ctx_setup = 1;
    }
     
     //mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
    
     mbedtls_ctr_drbg_random( &ctx, pb, cb );
     //mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE );
     //memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
     
     // mbedtls_ctr_drbg_free( &ctx );
}

int rand_bytes2(void * pv, unsigned char * pb, size_t cb)
{
    rand_bytes(pb, cb);
    return 0;
}

//END OF TODO RANDOM BYTES

#if USE_ECDH
/*!
*
* @param[in] pRecipent	Pointer to the message object
* @param[in] ppKeyPrivate	Address of key with private portion
* @param[in] pKeyPublic	Address of the key w/o a private portion
* @param[in/out] ppbSecret	pointer to buffer to hold the computed secret
* @param[in/out] pcbSecret	size of the computed secret
* @param[in] context		cbor allocation context structure
* @param[out] perr			location to return error information
* @returns		success of the function
*/

bool ECDH_ComputeSecret(COSE * pRecipient, cn_cbor ** ppKeyPrivate, const cn_cbor * pKeyPublic, byte ** ppbSecret, size_t * pcbSecret, CBOR_CONTEXT_COMMA cose_errback *perr)
{
    int cbGroup;
    int cbsecret;
    byte * pbsecret = NULL;
    bool fRet = false;
    mbedtls_ecp_group_id groupId;
    mbedtls_ecp_keypair keypair;
    mbedtls_ecdh_context ctx;
    mbedtls_mpi d;
    cn_cbor * p = NULL;
    mbedtls_mpi z;
    cn_cbor * pkey = NULL;
    int cose_group;
    
    mbedtls_mpi_init(&z);
    mbedtls_ecdh_init(&ctx);
    mbedtls_mpi_init(&d);
    mbedtls_ecp_keypair_init(&keypair);
        

    p = cn_cbor_mapget_int(pKeyPublic, COSE_Key_EC_Curve);
    CHECK_CONDITION((p != NULL) && (p->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);

    switch (p->v.uint) {
    case 1: // P-256
        groupId = MBEDTLS_ECP_DP_SECP256R1;
        cbGroup = 256 / 8;
        cose_group = 1;
        break;

    case 2: // P-384
        groupId = MBEDTLS_ECP_DP_SECP384R1;
        cbGroup = 384 / 12;
        cose_group = 2;
        break;

    case 3: // P-521
        groupId = MBEDTLS_ECP_DP_SECP521R1;
        cbGroup = (521 + 7) / 8;
        cose_group = 3;
        break;

    default:
        FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
    }
	p = NULL;

    mbedtls_ecp_group group = { 0 };
    CHECK_CONDITION0(mbedtls_ecp_group_load(&group, groupId), COSE_ERR_INVALID_PARAMETER);

    if (!ECKey_From(pKeyPublic, &keypair, perr)) goto errorReturn;

    if (*ppKeyPrivate == NULL) {
        {
            cn_cbor * pCompress = _COSE_map_get_int(pRecipient, COSE_Header_UseCompressedECDH, COSE_BOTH, perr);
            if (pCompress == NULL) FUseCompressed = false;
            else FUseCompressed = (pCompress->type == CN_CBOR_TRUE);
        }
        mbedtls_ecp_keypair privateKeyPair;
        mbedtls_ecp_keypair_init(&privateKeyPair);

        CHECK_CONDITION0( mbedtls_ecp_gen_key(groupId, &privateKeyPair, rand_bytes2, NULL), COSE_ERR_CRYPTO_FAIL);
        CHECK_CONDITION0( mbedtls_mpi_copy(&d, &privateKeyPair.d), COSE_ERR_CRYPTO_FAIL);
        
        size_t olen = 0;
        byte buff[528 * 2 / 8 + 1];
        CHECK_CONDITION0(mbedtls_ecp_point_write_binary(&group, &privateKeyPair.Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
                                                        &olen, buff, sizeof(buff)), COSE_ERR_CRYPTO_FAIL);

        cn_cbor_errback cbor_error;
        int cbSize = (olen - 1)/2;
        
        pkey = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
        CHECK_CONDITION_CBOR(pkey != NULL, cbor_error);

        p = cn_cbor_int_create(cose_group, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
        CHECK_CONDITION_CBOR(p != NULL, cbor_error);
        CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Curve, p, CBOR_CONTEXT_PARAM_COMMA perr), cbor_error);
        p = NULL;
        
        pbsecret = COSE_CALLOC(cbSize, 1, context);
        CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
        memcpy(pbsecret, buff + 1, cbSize);

        p = cn_cbor_data_create(pbsecret, (int) cbSize, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
        CHECK_CONDITION_CBOR(p != NULL, cbor_error);
        pbsecret = NULL;
        CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_X, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
        p = NULL;
        
        pbsecret = COSE_CALLOC(cbSize, 1, context);
        CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
        memcpy(pbsecret, buff + 1 + cbSize, cbSize);

        p = cn_cbor_data_create(pbsecret, cbSize, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
        CHECK_CONDITION_CBOR(p != NULL, cbor_error);
        CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Y, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
        p = NULL;

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

        *ppKeyPrivate = pkey;
        pkey = NULL;
    }
    else {
		p = cn_cbor_mapget_int(*ppKeyPrivate, COSE_Key_EC_d);
        CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);

        CHECK_CONDITION(p->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
        CHECK_CONDITION0(mbedtls_mpi_read_binary( &d, p->v.bytes, p->length), COSE_ERR_CRYPTO_FAIL);
    }



    CHECK_CONDITION0( mbedtls_ecdh_compute_shared(&group, &z, &keypair.Q, &d, NULL, NULL), COSE_ERR_CRYPTO_FAIL);

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

    CHECK_CONDITION0(mbedtls_mpi_write_binary(&z, pbsecret, cbsecret), COSE_ERR_CRYPTO_FAIL);

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

    fRet = true;

errorReturn:
    if (pbsecret != NULL) COSE_FREE(pbsecret, context);
    if (pkey != NULL) CN_CBOR_FREE(pkey, context);
    if (p != NULL) CN_CBOR_FREE(pkey, context);

    mbedtls_mpi_free(&d);
    mbedtls_mpi_free(&z);
    mbedtls_ecp_group_free(&group);
    mbedtls_ecp_keypair_free(&keypair);
    mbedtls_ecdh_free(&ctx);
    return fRet;
}
#endif // USE_ECDH
#endif // USE_MBED_TLS
