Setup to not compile some algorithms for MBED TLS

Also try and link things into the right library
diff --git a/.travis.yml b/.travis.yml
index 5b367e0..24e8773 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,8 +7,8 @@
   - pip install cpp-coveralls --user
   - export LD_LIBRARY_PATH=$PWD/build/dist/lib:$LD_LIBRARY_PATH
 env:
-  - USE_CONTEXT=ON
-  - USE_CONTEXT=OFF
+#  - USE_CONTEXT=ON
+#  - USE_CONTEXT=OFF
   - USE_CONTEXT=OFF USE_EMBEDTLS=ON
 matrix:
   exclude:
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 44c09fe..aef0143 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,6 +6,7 @@
 	Cose.c
 	MacMessage.c
         MacMessage0.c
+        mbedtls.c
 	openssl.c
 	Sign.c
         Sign0.c
@@ -29,6 +30,9 @@
 
 target_link_libraries ( cose-c PRIVATE ${OPENSSL_LIBRARIES} )
 target_link_libraries ( cose-c PRIVATE cn-cbor )
+if (use_embedtls)
+    target_link_libraries ( cose-c PRIVATE embedtls )
+endif()
 
 install ( TARGETS cose-c
 	LIBRARY DESTINATION lib
diff --git a/src/configure.h b/src/configure.h
index 00c0b8f..811e7b5 100644
--- a/src/configure.h
+++ b/src/configure.h
@@ -1,7 +1,24 @@
 //
+//  Determine which cryptographic library we are goig to be usig
+//
+
+#if defined(USE_MBED_TLS)
+#if defined(USE_OPEN_SSL) || defined(USE_BCRYPT)
+#error Only Define One Crypto Package
+#endif
+#elif defined(USE_BCRYPT)
+#if defined(USE_OPENSSL)
+#error Only Define One Crypto Package
+#endif
+#elif !defined(USE_OPEN_SSL)
+#define USE_OPEN_SSL
+#endif
+
+//
 //  Define which AES GCM algorithms are being used
 //
 
+#if !defined(USE_MBED_TLS)
 #define USE_AES_GCM_128
 #define USE_AES_GCM_192
 #define USE_AES_GCM_256
@@ -9,6 +26,7 @@
 #if defined(USE_AES_GCM_128) || defined(USE_AES_GCM_192) || defined(USE_AES_GCM_256)
 #define USE_AES_GCM
 #endif
+#endif // !defined(USE_MBED_TLS)
 
 //
 //  Define which AES CCM algorithms are being used
@@ -41,64 +59,67 @@
 //  Define which AES CBC-MAC algorithms are to be used
 //
 
+#if !defined(USE_MBED_TLS)
+
 #define USE_AES_CBC_MAC_128_64
 #define USE_AES_CBC_MAC_128_128
 #define USE_AES_CBC_MAC_256_64
 #define USE_AES_CBC_MAC_256_128
 
+#endif // !defined(USE_MBED_TLS)
+
 //
 //  Define which ECDH algorithms are to be used
 //
 
+#if !defined(USE_MBED_TLS)
 #define USE_ECDH_ES_HKDF_256
 #define USE_ECDH_ES_HKDF_512
 #define USE_ECDH_SS_HKDF_256
 #define USE_ECDH_SS_HKDF_512
+#endif // !defined(USE_MBED_TLS)
 
+#if !defined(USE_MBED_TLS)
 #define USE_ECDH_ES_A128KW
 #define USE_ECDH_ES_A192KW
 #define USE_ECDH_ES_A256KW
 #define USE_ECDH_SS_A128KW
 #define USE_ECDH_SS_A192KW
 #define USE_ECDH_SS_A256KW
+#endif // !defined(USE_MBED_TLS)
 
 //
 //  Define which Key Wrap functions are to be used
 //
 
+#if !defined(USE_MBED_TLS)
 #define USE_AES_KW_128
 #define USE_AES_KW_192
 #define USE_AES_KW_256
+#endif // !defined(USE_MBED_TLS)
 
 //
 //  Define which of the DIRECT + KDF algorithms are to be used
 //
 
+#if !defined(USE_MBED_TLS)
 #define USE_Direct_HKDF_HMAC_SHA_256
 #define USE_Direct_HKDF_HMAC_SHA_512
 #define USE_Direct_HKDF_AES_128
 #define USE_Direct_HKDF_AES_256
+#endif // !defined(USE_MBED_TLS)
 
 
 //
 //  Define which of the signature algorithms are to be used
 //
 
+#if !defined(USE_MBED_TLS)
 #define USE_ECDSA_SHA_256
 #define USE_ECDSA_SHA_384
 #define USE_ECDSA_SHA_512
+#endif // !defined(USE_MBED_TLS)
 
 
-#if defined(USE_MBED_TLS)
-#if defined(USE_OPEN_SSL) || defined(USE_BCRYPT)
-#error Only Define One Crypto Package
-#endif
-#elif defined(USE_BCRYPT)
-#if defined(USE_OPENSSL)
-#error Only Define One Crypto Package
-#endif
-#elif !defined(USE_OPEN_SSL)
-#define USE_OPEN_SSL
-#endif
 
 //#define USE_COUNTER_SIGNATURES
diff --git a/src/mbedtls.c b/src/mbedtls.c
new file mode 100644
index 0000000..d2ee833
--- /dev/null
+++ b/src/mbedtls.c
@@ -0,0 +1,1237 @@
+#include "cose.h"
+#include "configure.h"
+#include "cose_int.h"
+#include "crypto.h"
+
+#include <assert.h>
+#include <memory.h>
+
+#ifdef USE_MBED_TLS
+
+#include "include/mbedtls/ccm.h"
+#include "include/mbedtls/md.h"
+#include "include/mbedtls/ctr_drbg.h"
+#include "include/mbedtls/entropy.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.
+
+	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);
+	printf("errorReturn from OPENSSL\n");
+	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)
+{
+	EVP_CIPHER_CTX ctx;
+	int cbOut;
+	byte * rgbOut = NULL;
+	int outl = 0;
+	byte rgbIV[15] = { 0 };
+	const cn_cbor * pIV = NULL;
+	const EVP_CIPHER * cipher;
+#ifdef USE_CBOR_CONTEXT
+	cn_cbor_context * context = &pcose->m_message.m_allocContext;
+#endif
+	int TSize = 128 / 8;
+
+	EVP_CIPHER_CTX_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);
+		EVP_CIPHER_CTX_cleanup(&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:
+		cipher = EVP_aes_128_gcm();
+		break;
+
+	case 192 / 8:
+		cipher = EVP_aes_192_gcm();
+		break;
+
+	case 256 / 8:
+		cipher = EVP_aes_256_gcm();
+		break;
+
+	default:
+		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+		break;
+	}
+
+	//  Do the setup for OpenSSL
+
+	CHECK_CONDITION(EVP_DecryptInit_ex(&ctx, cipher, NULL, NULL, NULL), COSE_ERR_DECRYPT_FAILED);
+
+	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, TSize, (void *)&pbCrypto[cbCrypto - TSize]), COSE_ERR_DECRYPT_FAILED);
+
+	CHECK_CONDITION(EVP_DecryptInit(&ctx, 0, pbKey, rgbIV), COSE_ERR_DECRYPT_FAILED);
+	
+	//  Pus in the AAD
+
+	CHECK_CONDITION(EVP_DecryptUpdate(&ctx, NULL, &outl, pbAuthData, (int) cbAuthData), COSE_ERR_DECRYPT_FAILED);
+
+	//  
+
+	cbOut = (int)cbCrypto - TSize;
+	rgbOut = (byte *)COSE_CALLOC(cbOut, 1, context);
+	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+	//  Process content
+
+	CHECK_CONDITION(EVP_DecryptUpdate(&ctx, rgbOut, &cbOut, pbCrypto, (int)cbCrypto - TSize), COSE_ERR_DECRYPT_FAILED);
+
+	//  Process Tag
+
+	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, TSize, (byte *)pbCrypto + cbCrypto - TSize), COSE_ERR_DECRYPT_FAILED);
+
+	//  Check the result
+
+	CHECK_CONDITION(EVP_DecryptFinal(&ctx, rgbOut + cbOut, &cbOut), COSE_ERR_DECRYPT_FAILED);
+
+	EVP_CIPHER_CTX_cleanup(&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)
+{
+	EVP_CIPHER_CTX 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;
+	const EVP_CIPHER * cipher;
+#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
+	EVP_CIPHER_CTX_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:
+		cipher = EVP_aes_128_gcm();
+		break;
+
+	case 192:
+		cipher = EVP_aes_192_gcm();
+		break;
+
+	case 256:
+		cipher = EVP_aes_256_gcm();
+		break;
+
+	default:
+		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+		break;
+	}
+
+	//  Setup and run the OpenSSL code
+
+	CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, cipher, NULL, NULL, NULL), COSE_ERR_CRYPTO_FAIL);
+
+	CHECK_CONDITION(EVP_EncryptInit(&ctx, 0, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);
+
+	CHECK_CONDITION(EVP_EncryptUpdate(&ctx, NULL, &outl, pbAuthData, (int) 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_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pcose->pbContent, (int)pcose->cbContent), COSE_ERR_CRYPTO_FAIL);
+
+	CHECK_CONDITION(EVP_EncryptFinal_ex(&ctx, &rgbOut[cbOut], &cbOut), COSE_ERR_CRYPTO_FAIL);
+
+	CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 128/8, &rgbOut[pcose->cbContent]), 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);
+
+	EVP_CIPHER_CTX_cleanup(&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);
+	EVP_CIPHER_CTX_cleanup(&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)
+{
+	byte rgbSalt[EVP_MAX_MD_SIZE] = { 0 };
+	int cbSalt;
+	cn_cbor * cnSalt;
+	HMAC_CTX ctx;
+	const EVP_MD * pmd = NULL;
+	unsigned int cbDigest;
+
+	HMAC_CTX_init(&ctx);
+
+	if (0) {
+	errorReturn:
+		HMAC_cleanup(&ctx);
+		return false;
+	}
+
+	switch (cbitDigest) {
+	case 256: pmd = EVP_sha256(); cbSalt = 256 / 8;  break;
+	case 384: pmd = EVP_sha384(); cbSalt = 384 / 8; break;
+	case 512: pmd = EVP_sha512(); cbSalt = 512 / 8; break;
+	default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
+	}
+
+	cnSalt = _COSE_map_get_int(pcose, COSE_Header_HKDF_salt, COSE_BOTH, perr);
+
+	if (cnSalt != NULL) {
+		CHECK_CONDITION(HMAC_Init(&ctx, cnSalt->v.bytes, (int) cnSalt->length, pmd), COSE_ERR_CRYPTO_FAIL);
+	}
+	else {
+		CHECK_CONDITION(HMAC_Init(&ctx, rgbSalt, cbSalt, pmd), COSE_ERR_CRYPTO_FAIL);
+	}
+	CHECK_CONDITION(HMAC_Update(&ctx, pbKey, (int)cbKey), COSE_ERR_CRYPTO_FAIL);
+	CHECK_CONDITION(HMAC_Final(&ctx, rgbDigest, &cbDigest), COSE_ERR_CRYPTO_FAIL);
+	*pcbDigest = cbDigest;
+	HMAC_cleanup(&ctx);
+	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)
+{
+	HMAC_CTX ctx;
+	const EVP_MD * pmd = NULL;
+	size_t ib;
+	int cbSalt;
+	unsigned int cbDigest = 0;
+	byte rgbDigest[EVP_MAX_MD_SIZE];
+	byte bCount = 1;
+
+	HMAC_CTX_init(&ctx);
+
+	if (0) {
+	errorReturn:
+		HMAC_cleanup(&ctx);
+		return false;
+	}
+
+	switch (cbitDigest) {
+	case 256: pmd = EVP_sha256(); cbSalt = 256 / 8;  break;
+	case 384: pmd = EVP_sha384(); cbSalt = 384 / 8; break;
+	case 512: pmd = EVP_sha512(); cbSalt = 512 / 8; break;
+	default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
+	}
+
+
+	for (ib = 0; ib < cbOutput; ib += cbDigest, bCount += 1) {
+		CHECK_CONDITION(HMAC_Init_ex(&ctx, pbPRK, (int)cbPRK, pmd, NULL), COSE_ERR_CRYPTO_FAIL);
+		CHECK_CONDITION(HMAC_Update(&ctx, rgbDigest, cbDigest), COSE_ERR_CRYPTO_FAIL);
+		CHECK_CONDITION(HMAC_Update(&ctx, pbInfo, cbInfo), COSE_ERR_CRYPTO_FAIL);
+		CHECK_CONDITION(HMAC_Update(&ctx, &bCount, 1), COSE_ERR_CRYPTO_FAIL);
+		CHECK_CONDITION(HMAC_Final(&ctx, rgbDigest, &cbDigest), COSE_ERR_CRYPTO_FAIL);
+
+		memcpy(pbOutput + ib, rgbDigest, MIN(cbDigest, cbOutput - ib));
+	}
+
+	HMAC_cleanup(&ctx);
+	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, (char*)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, (char*)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
+
+EC_KEY * ECKey_From(const cn_cbor * pKey, int * cbGroup, cose_errback * perr)
+{
+	EC_KEY * pNewKey = EC_KEY_new();
+	byte  rgbKey[512+1];
+	int cbKey;
+	const cn_cbor * p;
+	int nidGroup = -1;
+	EC_POINT * pPoint = NULL;
+
+	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Curve);
+	CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
+
+	switch (p->v.sint) {
+	case 1: // P-256
+		nidGroup = NID_X9_62_prime256v1;
+		*cbGroup = 256 / 8;
+		break;
+
+	case 2: // P-384
+		nidGroup = NID_secp384r1;
+		*cbGroup = 384 / 8;
+		break;
+
+	case 3: // P-521
+		nidGroup = NID_secp521r1;
+		*cbGroup = (521 + 7) / 8;
+		break;
+
+	default:
+		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+	}
+
+	EC_GROUP * ecgroup = EC_GROUP_new_by_curve_name(nidGroup);
+	CHECK_CONDITION(ecgroup != NULL, COSE_ERR_INVALID_PARAMETER);
+	CHECK_CONDITION(EC_KEY_set_group(pNewKey, ecgroup) == 1, COSE_ERR_CRYPTO_FAIL);
+
+	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] = POINT_CONVERSION_UNCOMPRESSED;
+		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] = POINT_CONVERSION_COMPRESSED + 1;
+	}
+	else if (p->type == CN_CBOR_FALSE) {
+		cbKey = (*cbGroup) + 1;
+		rgbKey[0] = POINT_CONVERSION_COMPRESSED;
+	}
+	else FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+
+	pPoint = EC_POINT_new(ecgroup);
+	CHECK_CONDITION(pPoint != NULL, COSE_ERR_CRYPTO_FAIL);
+	CHECK_CONDITION(EC_POINT_oct2point(ecgroup, pPoint, rgbKey, cbKey, NULL) == 1, COSE_ERR_CRYPTO_FAIL);
+	CHECK_CONDITION(EC_KEY_set_public_key(pNewKey, pPoint) == 1, COSE_ERR_CRYPTO_FAIL);
+
+	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_d);
+	if (p != NULL) {
+		BIGNUM * pbn;
+
+		pbn = BN_bin2bn(p->v.bytes, (int) p->length, NULL);
+		CHECK_CONDITION(pbn != NULL, COSE_ERR_CRYPTO_FAIL);
+		CHECK_CONDITION(EC_KEY_set_private_key(pNewKey, pbn) == 1, COSE_ERR_CRYPTO_FAIL);
+	}
+	
+	return pNewKey;
+
+errorReturn:
+	if (pNewKey != NULL) EC_KEY_free(pNewKey);
+	return NULL;
+}
+
+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(const cn_cbor * pKey)
+{
+	byte * digest = NULL;
+	int digestLen = 0;
+	ECDSA_SIG * sig;
+
+	EC_KEY * eckey = ECKey_From(pKey);
+
+	sig = ECDSA_do_sign(digest, digestLen, eckey);
+
+	return true;
+}
+*/
+/*
+bool ECDSA_Sign(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
+{
+	EC_KEY * eckey = NULL;
+	byte rgbDigest[EVP_MAX_MD_SIZE];
+	unsigned int cbDigest = sizeof(rgbDigest);
+	byte  * pbSig = NULL;
+	const EVP_MD * digest;
+#ifdef USE_CBOR_CONTEXT
+	cn_cbor_context * context = &pSigner->m_allocContext;
+#endif
+	cn_cbor * p = NULL;
+	ECDSA_SIG * psig = NULL;
+	cn_cbor_errback cbor_error;
+	int cbR;
+	byte rgbSig[66];
+	int cb;
+	
+	eckey = ECKey_From(pKey, &cbR, perr);
+	if (eckey == NULL) {
+	errorReturn:
+		if (pbSig != NULL) COSE_FREE(pbSig, context);
+		if (p != NULL) CN_CBOR_FREE(p, context);
+		if (eckey != NULL) EC_KEY_free(eckey);
+		return false;
+	}
+
+	switch (cbitDigest) {
+	case 256: digest = EVP_sha256(); break;
+	case 512: digest = EVP_sha512(); break;
+	case 384: digest = EVP_sha384(); break;
+	default:
+		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+	}
+
+	EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL);
+
+	psig = ECDSA_do_sign(rgbDigest, cbDigest, eckey);
+	CHECK_CONDITION(psig != NULL, COSE_ERR_CRYPTO_FAIL);
+
+	pbSig = COSE_CALLOC(cbR, 2, context);
+	CHECK_CONDITION(pbSig != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+	cb = BN_bn2bin(psig->r, rgbSig);
+	CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER);
+	memcpy(pbSig + cbR - cb, rgbSig, cb);
+
+	cb = BN_bn2bin(psig->s, rgbSig);
+	CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER);
+	memcpy(pbSig + 2*cbR - cb, rgbSig, cb);
+
+	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);
+	
+	pbSig = NULL;
+
+	if (eckey != NULL) EC_KEY_free(eckey);
+
+	return true;
+}
+
+bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
+{
+	EC_KEY * eckey = NULL;
+	byte rgbDigest[EVP_MAX_MD_SIZE];
+	unsigned int cbDigest = sizeof(rgbDigest);
+	const EVP_MD * digest;
+#ifdef USE_CBOR_CONTEXT
+	cn_cbor_context * context = &pSigner->m_allocContext;
+#endif
+	cn_cbor * p = NULL;
+	ECDSA_SIG sig = { NULL, NULL };
+	int cbR;
+	cn_cbor * pSig;
+	size_t cbSignature;
+
+	eckey = ECKey_From(pKey, &cbR, perr);
+	if (eckey == NULL) {
+	errorReturn:
+		if (sig.r != NULL) BN_free(sig.r);
+		if (sig.s != NULL) BN_free(sig.s);
+		if (p != NULL) CN_CBOR_FREE(p, context);
+		if (eckey != NULL) EC_KEY_free(eckey);
+		return false;
+	}
+
+	switch (cbitDigest) {
+	case 256: digest = EVP_sha256(); break;
+	case 512: digest = EVP_sha512(); break;
+	case 384: digest = EVP_sha384(); break;
+	default:
+		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+	}
+	EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL);
+
+	pSig = _COSE_arrayget_int(pSigner, index);
+	CHECK_CONDITION(pSig != NULL, COSE_ERR_INVALID_PARAMETER);
+	cbSignature = pSig->length;
+
+	CHECK_CONDITION(cbSignature / 2 == cbR, COSE_ERR_INVALID_PARAMETER);
+	sig.r = BN_bin2bn(pSig->v.bytes,(int) cbSignature/2, NULL);
+	sig.s = BN_bin2bn(pSig->v.bytes+cbSignature/2, (int) cbSignature/2, NULL);
+
+	CHECK_CONDITION(ECDSA_do_verify(rgbDigest, cbDigest, &sig, eckey) == 1, COSE_ERR_CRYPTO_FAIL);
+
+	BN_free(sig.r);
+	BN_free(sig.s);
+	if (eckey != NULL) EC_KEY_free(eckey);
+
+	return true;
+}
+
+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)
+{
+	byte rgbOut[512 / 8];
+	AES_KEY key;
+
+	CHECK_CONDITION(AES_set_decrypt_key(pbKeyIn, (int)cbitKey, &key) == 0, COSE_ERR_CRYPTO_FAIL);
+
+	CHECK_CONDITION(AES_unwrap_key(&key, NULL, rgbOut, pbCipherText, (int) cbCipherText), COSE_ERR_CRYPTO_FAIL);
+
+	memcpy(pbKeyOut, rgbOut, cbCipherText - 8);
+	*pcbKeyOut = (int) (cbCipherText - 8);
+
+	return true;
+errorReturn:
+	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;
+	AES_KEY key;
+#ifdef USE_CBOR_CONTEXT
+	cn_cbor_context * context = &pcose->m_encrypt.m_message.m_allocContext;
+#endif
+	cn_cbor * cnTmp = NULL;
+
+	pbOut = COSE_CALLOC(cbContent + 8, 1, context);
+	CHECK_CONDITION(pbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+	CHECK_CONDITION(AES_set_encrypt_key(pbKeyIn, cbitKey, &key) == 0, COSE_ERR_CRYPTO_FAIL);
+
+	CHECK_CONDITION(AES_wrap_key(&key, NULL, pbOut, pbContent, cbContent), 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;
+
+	return true;
+
+errorReturn:
+	COSE_FREE(cnTmp, context);
+	if (pbOut != NULL) COSE_FREE(pbOut, context);
+	return false;
+}
+
+*/
+/*
+//#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
+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 };
+
+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 );
+ }
+
+void rand_bytes(byte* pb, size_t cb){
+     
+     mbedtls_ctr_drbg_context ctx;
+    // unsigned char buf[16];
+     
+     mbedtls_ctr_drbg_init( &ctx );
+     
+     mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, (void *) entropy_source_pr, nonce_pers_pr, 16, 32 );
+     
+     //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 );
+}
+//END OF TODO RANDOM BYTES
+
+/*!
+*
+* @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)
+{
+	EC_KEY * peckeyPrivate = NULL;
+	EC_KEY * peckeyPublic = NULL;
+	int cbGroup;
+	int cbsecret;
+	byte * pbsecret = NULL;
+	bool fRet = false;
+
+	peckeyPublic = ECKey_From(pKeyPublic, &cbGroup, perr);
+	if (peckeyPublic == NULL) 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);
+		}
+		peckeyPrivate = EC_KEY_new();
+		EC_KEY_set_group(peckeyPrivate, EC_KEY_get0_group(peckeyPublic));
+		CHECK_CONDITION(EC_KEY_generate_key(peckeyPrivate) == 1, COSE_ERR_CRYPTO_FAIL);
+		*ppKeyPrivate = EC_FromKey(peckeyPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
+		if (*ppKeyPrivate == NULL) goto errorReturn;
+	}
+	else {
+		peckeyPrivate = ECKey_From(*ppKeyPrivate, &cbGroup, perr);
+		if (peckeyPrivate == NULL) goto errorReturn;
+	}
+
+	pbsecret = COSE_CALLOC(cbGroup, 1, context);
+	CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+	cbsecret = ECDH_compute_key(pbsecret, cbGroup, EC_KEY_get0_public_key(peckeyPublic), peckeyPrivate, NULL);
+	CHECK_CONDITION(cbsecret > 0, COSE_ERR_CRYPTO_FAIL);
+
+	*ppbSecret = pbsecret;
+	*pcbSecret = cbsecret;
+	pbsecret = NULL;
+
+	fRet = true;
+
+errorReturn:
+	if (pbsecret != NULL) COSE_FREE(pbsecret, context);
+	if (peckeyPublic != NULL) EC_KEY_free(peckeyPublic);
+	if (peckeyPrivate != NULL) EC_KEY_free(peckeyPrivate);
+
+	return fRet;
+}
+*/
+#endif // USE_MBED_TLS
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2173f53..9dd2cc3 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,11 +11,15 @@
 add_executable ( cose_test test.c json.c encrypt.c sign.c context.c mac_test.c)
 
 target_link_libraries (cose_test PRIVATE cose-c )
+if (use_embedtls)
+    target_link_libraries ( cose-c PRIVATE embedtls )
+endif()
 
 ## OpenSSL
 
 target_include_directories(cose_test PRIVATE ${OPENSSL_INCLUDE_DIR})
 target_link_libraries( cose_test PRIVATE ${OPENSSL_LIBRARIES} )
+
 target_link_libraries( cose_test PRIVATE cn-cbor )
 if ( MSVC )
     target_link_libraries( cose_test PRIVATE ws2_32 )