Start getting HKDF - HMAC-SHA256 running
diff --git a/src/Encrypt.c b/src/Encrypt.c
index 2440e14..a7d47e0 100644
--- a/src/Encrypt.c
+++ b/src/Encrypt.c
@@ -286,7 +286,7 @@
// If there is a recipient - ask it for the key
for (pRecip = pcose->m_recipientFirst; pRecip != NULL; pRecip = pRecip->m_recipientNext) {
- if (_COSE_Recipient_decrypt(pRecip, cbitKey, pbKey, perr)) break;
+ if (_COSE_Recipient_decrypt(pRecip, alg, cbitKey, pbKey, perr)) break;
}
// Build protected headers
@@ -414,7 +414,7 @@
for (pri = pcose->m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
if (pri->m_encrypt.m_message.m_flags & 1) {
t |= 1;
- pcose->pbKey = _COSE_RecipientInfo_generateKey(pri, cbitKey, perr);
+ pcose->pbKey = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
if (pcose->pbKey == NULL) goto errorReturn;
pcose->cbKey = cbitKey / 8;
}
@@ -632,4 +632,4 @@
if (ptmp != NULL) CN_CBOR_FREE(ptmp, NULL);
if (pAuthData != NULL) CN_CBOR_FREE(pAuthData, context);
return false;
-}
\ No newline at end of file
+}
diff --git a/src/MacMessage.c b/src/MacMessage.c
index 2b5c401..a6318a2 100644
--- a/src/MacMessage.c
+++ b/src/MacMessage.c
@@ -310,7 +310,7 @@
for (pri = pcose->m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
if (pri->m_encrypt.m_message.m_flags & 1) {
t |= 1;
- pcose->pbKey = _COSE_RecipientInfo_generateKey(pri, cbitKey, perr);
+ pcose->pbKey = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
if (pcose->pbKey == NULL) goto errorReturn;
pcose->cbKey = cbitKey / 8;
@@ -499,7 +499,7 @@
// If there is a recipient - ask it for the key
for (pRecip = pcose->m_recipientFirst; pRecip != NULL; pRecip = pRecip->m_recipientNext) {
- if (_COSE_Recipient_decrypt(pRecip, cbitKey, pbKey, perr)) break;
+ if (_COSE_Recipient_decrypt(pRecip, alg, cbitKey, pbKey, perr)) break;
}
CHECK_CONDITION(pRecip != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
diff --git a/src/Recipient.c b/src/Recipient.c
index cb1dc80..11fc583 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -6,6 +6,9 @@
#include "configure.h"
#include "crypto.h"
+extern bool BuildContextBytes(COSE * pcose, int algID, size_t cbitKey, byte ** ppbContext, size_t * pcbContext, CBOR_CONTEXT_COMMA cose_errback * perr);
+
+
COSE* RecipientRoot = NULL;
bool IsValidRecipientHandle(HCOSE_RECIPIENT h)
@@ -111,7 +114,7 @@
return;
}
-bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, int cbitKey, byte * pbKeyIn, cose_errback * perr)
+bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, int algIn, int cbitKey, byte * pbKeyIn, cose_errback * perr)
{
int alg;
const cn_cbor * cn = NULL;
@@ -125,6 +128,10 @@
byte * pbProtected = NULL;
COSE_Enveloped * pcose = &pRecip->m_encrypt;
cn_cbor * cnBody = NULL;
+ byte * pbContext = NULL;
+ size_t cbContext;
+ byte rgbDigest[512 / 8];
+ size_t cbDigest;
#ifdef USE_CBOR_CONTEXT
context = &pcose->m_message.m_allocContext;
@@ -133,6 +140,7 @@
cn = _COSE_map_get_int(&pRecip->m_encrypt.m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
if (cn == NULL) {
errorReturn:
+ if (pbContext != NULL) COSE_FREE(pbContext, context);
if (pbProtected != NULL) COSE_FREE(pbProtected, context);
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
@@ -167,6 +175,12 @@
case COSE_Algorithm_AES_KW_256:
break;
+ case COSE_Algorithm_Direct_HKDF_AES_128:
+ case COSE_Algorithm_Direct_HKDF_AES_256:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
+ break;
+
default:
FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
break;
@@ -182,7 +196,7 @@
// If there is a recipient - ask it for the key
for (pRecip2 = pcose->m_recipientFirst; pRecip2 != NULL; pRecip2 = pRecip->m_recipientNext) {
- if (_COSE_Recipient_decrypt(pRecip2, cbitKey, pbKey, perr)) break;
+ if (_COSE_Recipient_decrypt(pRecip2, alg, cbitKey, pbKey, perr)) break;
}
cnBody = _COSE_arrayget_int(&pcose->m_message, INDEX_BODY);
@@ -204,6 +218,16 @@
memcpy(pbKey, pcose->pbKey, pcose->cbKey);
}
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
+ if (!BuildContextBytes(&pcose->m_message, algIn, cbitKey, &pbContext, &cbContext, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ cn = cn_cbor_mapget_int(pRecip->m_pkey, -1);
+ CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
+
+ if (!HKDF_Extract(&pcose->m_message, cn->v.bytes, cn->length, 256, rgbDigest, &cbDigest, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ if (!HKDF_Expand(&pcose->m_message, 256, rgbDigest, cbDigest, pbContext, cbContext, pbKey, cbitKey / 8, perr)) goto errorReturn;
+
break;
default:
@@ -243,6 +267,8 @@
switch (alg) {
case COSE_Algorithm_Direct:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
// This is a NOOP
cbitKey = 0;
CHECK_CONDITION(pRecipient->m_encrypt.m_recipientFirst == NULL, COSE_ERR_INVALID_PARAMETER);
@@ -271,7 +297,7 @@
for (pri = pRecipient->m_encrypt.m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
if (pri->m_encrypt.m_message.m_flags & 1) {
t |= 1;
- pRecipient->m_encrypt.pbKey = _COSE_RecipientInfo_generateKey(pri, cbitKey, perr);
+ pRecipient->m_encrypt.pbKey = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
if (pRecipient->m_encrypt.pbKey == NULL) goto errorReturn;
pRecipient->m_encrypt.cbKey = cbitKey / 8;
}
@@ -304,11 +330,14 @@
switch (alg) {
case COSE_Algorithm_Direct:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
CHECK_CONDITION_CBOR(_COSE_array_replace(&pRecipient->m_encrypt.m_message, ptmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
break;
+
case COSE_Algorithm_AES_KW_256:
if (pRecipient->m_pkey != NULL) {
cn_cbor * pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
@@ -342,24 +371,33 @@
return false;
}
-byte * _COSE_RecipientInfo_generateKey(COSE_RecipientInfo * pRecipient, size_t cbitKeySize, cose_errback * perr)
+byte * _COSE_RecipientInfo_generateKey(COSE_RecipientInfo * pRecipient, int algIn, size_t cbitKeySize, cose_errback * perr)
{
int alg;
const cn_cbor * cn_Alg = _COSE_map_get_int(&pRecipient->m_encrypt.m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
+ byte * pbContext = NULL;
+ size_t cbContext;
+ byte * pb = NULL;
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = &pRecipient->m_encrypt.m_message.m_allocContext;
+#endif
+ const cn_cbor * pK;
+ byte rgbDigest[512 / 8];
+ size_t cbDigest;
CHECK_CONDITION(cn_Alg != NULL, COSE_ERR_INVALID_PARAMETER);
CHECK_CONDITION((cn_Alg->type == CN_CBOR_UINT) || (cn_Alg->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
alg = (int)cn_Alg->v.uint;
+ _COSE_encode_protected(&pRecipient->m_encrypt.m_message, perr);
+
switch (alg) {
case COSE_Algorithm_Direct:
- {
- byte * pb;
if (pRecipient->m_pkey != NULL) {
- const cn_cbor * pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
+ pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
CHECK_CONDITION((pK != NULL) && (pK->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
CHECK_CONDITION(pK->length == cbitKeySize / 8, COSE_ERR_INVALID_PARAMETER);
- pb = COSE_CALLOC(cbitKeySize / 8, 1, &pRecipient->m_encrypt.m_message.m_allocContext);
+ pb = COSE_CALLOC(cbitKeySize / 8, 1, context);
CHECK_CONDITION(pb != NULL, COSE_ERR_OUT_OF_MEMORY);
memcpy(pb, pK->v.bytes, cbitKeySize / 8);
}
@@ -369,10 +407,23 @@
if (pb == NULL) return NULL;
memcpy(pb, pRecipient->m_encrypt.pbKey, cbitKeySize / 8);
}
- return pb;
- }
break;
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
+ if (!BuildContextBytes(&pRecipient->m_encrypt.m_message, algIn, cbitKeySize, &pbContext, &cbContext, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
+ CHECK_CONDITION((pK != NULL) && (pK->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
+
+ if (!HKDF_Extract(&pRecipient->m_encrypt.m_message, pK->v.bytes, pK->length, 256, rgbDigest, &cbDigest, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ pb = COSE_CALLOC(cbitKeySize / 8, 1, context);
+ CHECK_CONDITION(pb != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ if (!HKDF_Expand(&pRecipient->m_encrypt.m_message, 256, rgbDigest, cbDigest, pbContext, cbContext, pb, cbitKeySize / 8, perr)) goto errorReturn;
+
+ break;
+
case COSE_Algorithm_ECDH_SS_HKDF_256: {
// Need to have a key and it needs to be the correct type of key.
if ((pRecipient->m_pkey == NULL) || (cn_cbor_mapget_int(pRecipient->m_pkey, 1)->v.uint != 2)) return NULL;
@@ -383,7 +434,13 @@
return NULL;
}
+ if (pbContext != NULL) COSE_FREE(pbContext, context);
+ return pb;
+
errorReturn:
+
+ if (pbContext != NULL) COSE_FREE(pbContext, context);
+ if (pb != NULL) COSE_FREE(pb, context);
return NULL;
}
@@ -440,6 +497,10 @@
if (value->type == CN_CBOR_INT) {
switch (value->v.uint) {
case COSE_Algorithm_Direct:
+ case COSE_Algorithm_Direct_HKDF_AES_128:
+ case COSE_Algorithm_Direct_HKDF_AES_256:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
+ case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
case COSE_Algorithm_ECDH_ES_HKDF_256:
case COSE_Algorithm_ECDH_ES_HKDF_512:
((COSE_RecipientInfo *)h)->m_encrypt.m_message.m_flags |= 1;
@@ -458,3 +519,153 @@
return true;
}
+
+byte RgbDontUse4[8 * 1024];
+
+bool BuildContextBytes(COSE * pcose, int algID, size_t cbitKey, byte ** ppbContext, size_t * pcbContext, CBOR_CONTEXT_COMMA cose_errback * perr)
+{
+ cn_cbor * pArray;
+ cn_cbor_errback cbor_error;
+ bool fReturn = false;
+ cn_cbor * cnT = NULL;
+ cn_cbor * cnArrayT = NULL;
+ cn_cbor * cnParam;
+ byte * pbContext = NULL;
+ size_t cbContext;
+
+ pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(pArray != NULL, cbor_error);
+
+ cnT = cn_cbor_int_create(algID, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnT, &cbor_error), cbor_error);
+ cnT = NULL;
+
+ cnArrayT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnArrayT != NULL, cbor_error);
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_U_nonce, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_U_name, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_U_other, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnArrayT, &cbor_error), cbor_error);
+ cnArrayT = NULL;
+
+ cnArrayT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnArrayT != NULL, cbor_error);
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_V_nonce, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_V_name, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_V_other, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnArrayT, &cbor_error), cbor_error);
+ cnArrayT = NULL;
+
+ cnArrayT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnArrayT != NULL, cbor_error);
+
+ cnT = cn_cbor_int_create(cbitKey, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
+ cnT = NULL;
+
+ cnParam = _COSE_arrayget_int(pcose, INDEX_PROTECTED);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_PUB_other, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cnArrayT, &cbor_error), cbor_error);
+ cnArrayT = NULL;
+
+
+ cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_PRIV, COSE_BOTH, perr);
+ if (cnParam != NULL) {
+ cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(cnArrayT, cnParam, &cbor_error), cbor_error);
+ cnT = NULL;
+ cnParam = NULL;
+ }
+
+ cbContext = cn_cbor_encoder_write(RgbDontUse4, 0, sizeof(RgbDontUse4), pArray);
+ CHECK_CONDITION(cbContext > 0, COSE_ERR_CBOR);
+ pbContext = (byte *)COSE_CALLOC(cbContext, 1, context);
+ CHECK_CONDITION(pbContext != NULL, COSE_ERR_OUT_OF_MEMORY);
+ CHECK_CONDITION(cn_cbor_encoder_write(pbContext, 0, cbContext, pArray), COSE_ERR_CBOR);
+
+ *ppbContext = pbContext;
+ *pcbContext = cbContext;
+ pbContext = NULL;
+ fReturn = true;
+
+returnHere:
+ if (pbContext != NULL) COSE_FREE(pbContext, context);
+ if (pArray != NULL) CN_CBOR_FREE(pArray, context);
+ if (cnArrayT != NULL) CN_CBOR_FREE(cnArrayT, context);
+ if (cnT != NULL) CN_CBOR_FREE(cnT, context);
+ return fReturn;
+
+errorReturn:
+ fReturn = false;
+ goto returnHere;
+}
+
diff --git a/src/Sign.c b/src/Sign.c
index 89f1d2c..5ec32ba 100644
--- a/src/Sign.c
+++ b/src/Sign.c
@@ -3,11 +3,14 @@
#include "cose.h"
#include "cose_int.h"
+COSE * SignRoot = NULL;
+
bool IsValidSignHandle(HCOSE_SIGN h)
{
COSE_SignMessage * p = (COSE_SignMessage *)h;
+
if (p == NULL) return false;
- return true;
+ return _COSE_IsInList(SignRoot, &p->m_message);
}
@@ -24,6 +27,8 @@
return NULL;
}
+ _COSE_InsertInList(&SignRoot, &pobj->m_message);
+
return (HCOSE_SIGN)pobj;
}
@@ -57,6 +62,8 @@
pSigners = pSigners->next;
} while (pSigners != NULL);
+ if (pIn == NULL) _COSE_InsertInList(&SignRoot, &pobj->m_message);
+
return(HCOSE_SIGN)pobj;
errorReturn:
@@ -79,6 +86,8 @@
return true;
}
+ _COSE_RemoveFromList(&SignRoot, &pMessage->m_message);
+
#ifdef USE_CBOR_CONTEXT
context = pMessage->m_message.m_allocContext;
#endif
diff --git a/src/Sign0.c b/src/Sign0.c
index 5b7201a..e404a53 100644
--- a/src/Sign0.c
+++ b/src/Sign0.c
@@ -8,13 +8,14 @@
bool _COSE_Signer0_validate(COSE_Sign0Message * pSign, const cn_cbor * pKey, cose_errback * perr);
void _COSE_Sign0_Release(COSE_Sign0Message * p);
-
+COSE * Sign0Root = NULL;
bool IsValidSign0Handle(HCOSE_SIGN0 h)
{
COSE_Sign0Message * p = (COSE_Sign0Message *)h;
+
if (p == NULL) return false;
- return true;
+ return _COSE_IsInList(Sign0Root, &p->m_message);
}
@@ -31,15 +32,16 @@
return NULL;
}
+ _COSE_InsertInList(&Sign0Root, &pobj->m_message);
+
return (HCOSE_SIGN0)pobj;
}
HCOSE_SIGN0 _COSE_Sign0_Init_From_Object(cn_cbor * cbor, COSE_Sign0Message * pIn, CBOR_CONTEXT_COMMA cose_errback * perr)
{
COSE_Sign0Message * pobj = pIn;
- cn_cbor * pSigners = NULL;
- // cn_cbor * tmp;
cose_errback error = { 0 };
+
if (perr == NULL) perr = &error;
if (pobj == NULL) pobj = (COSE_Sign0Message *)COSE_CALLOC(1, sizeof(COSE_Sign0Message), context);
@@ -49,6 +51,8 @@
goto errorReturn;
}
+ if (pIn == NULL) _COSE_InsertInList(&Sign0Root, &pobj->m_message);
+
return(HCOSE_SIGN0)pobj;
errorReturn:
@@ -71,6 +75,8 @@
return true;
}
+ _COSE_RemoveFromList(&Sign0Root, &pMessage->m_message);
+
#ifdef USE_CBOR_CONTEXT
context = pMessage->m_message.m_allocContext;
#endif
diff --git a/src/cbor.c b/src/cbor.c
index dc4c6bf..90e8256 100644
--- a/src/cbor.c
+++ b/src/cbor.c
@@ -1,5 +1,6 @@
#include "cn-cbor/cn-cbor.h"
#include <stdlib.h>
+#include <memory.h>
#define INIT_CB(v) \
if (errp) {errp->err = CN_CBOR_NO_ERROR;} \
@@ -14,10 +15,14 @@
calloc(1, sizeof(cn_cbor));
#define CN_CALLOC_CONTEXT() CN_CALLOC(context)
+#define CN_CBOR_CALLOC(c, i, ctx) ((ctx) && (ctx)->calloc_func) ? \
+ (ctx)->calloc_func(c, i, (ctx)->context) : \
+ calloc(c, i)
#else
#define CBOR_CONTEXT_PARAM
#define CN_CALLOC(ctx) calloc(1, sizeof(cn_cbor));
#define CN_CALLOC_CONTEXT() CN_CALLOC(context)
+#deifne CN_CBOR_CALLOC(c, i, ctx) calloc(c, i);
#endif
@@ -106,3 +111,34 @@
return true;
}
+
+cn_cbor * cn_cbor_clone(const cn_cbor * pIn, CBOR_CONTEXT_COMMA cn_cbor_errback * pcn_cbor_error)
+{
+ cn_cbor * pOut = NULL;
+ char * sz;
+ unsigned char * pb;
+
+ switch (pIn->type) {
+ case CN_CBOR_TEXT:
+ sz = CN_CBOR_CALLOC(pIn->length + 1, 1, context);
+ memcpy(sz, pIn->v.str, pIn->length);
+ sz[pIn->length] = 0;
+ pOut = cn_cbor_string_create(sz CBOR_CONTEXT_PARAM, pcn_cbor_error);
+ break;
+
+ case CN_CBOR_UINT:
+ pOut = cn_cbor_int_create(pIn->v.sint CBOR_CONTEXT_PARAM, pcn_cbor_error);
+ break;
+
+ case CN_CBOR_BYTES:
+ pb = CN_CBOR_CALLOC((int) pIn->length, 1, context);
+ memcpy(pb, pIn->v.bytes, pIn->length);
+ pOut = cn_cbor_data_create(pb, (int) pIn->length CBOR_CONTEXT_PARAM, pcn_cbor_error);
+ break;
+
+ default:
+ break;
+ }
+
+ return pOut;
+}
diff --git a/src/cose.h b/src/cose.h
index 7f7c0a0..d3aa969 100644
--- a/src/cose.h
+++ b/src/cose.h
@@ -136,6 +136,17 @@
COSE_Header_Content_Type = 3,
COSE_Header_KID = 4,
COSE_Header_IV = 5,
+
+ COSE_Header_HKDF_salt = -20,
+ COSE_Header_KDF_U_nonce = -21,
+ COSE_Header_KDF_U_name = -22,
+ COSE_Header_KDF_U_other = -23,
+ COSE_Header_KDF_V_nonce = -24,
+ COSE_Header_KDF_V_name = -25,
+ COSE_Header_KDF_V_other = -26,
+
+ COSE_Header_KDF_PUB_other = -999,
+ COSE_Header_KDF_PRIV = -998,
} COSE_Header;
typedef enum {
@@ -260,3 +271,10 @@
bool COSE_Sign0_validate(HCOSE_SIGN0 hSign, const cn_cbor * pkey, cose_errback * perr);
cn_cbor * COSE_Sign0_map_get_int(HCOSE_SIGN0 h, int key, int flags, cose_errback * perror);
bool COSE_Sign0_map_put_int(HCOSE_SIGN0 cose, int key, cn_cbor * value, int flags, cose_errback * errp);
+
+
+/*
+*/
+
+extern cn_cbor * cn_cbor_clone(const cn_cbor * pIn, CBOR_CONTEXT_COMMA cn_cbor_errback * perr);
+
diff --git a/src/cose_int.h b/src/cose_int.h
index 65317f4..51609aa 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -169,9 +169,9 @@
extern COSE_RecipientInfo * _COSE_Recipient_Init_From_Object(cn_cbor *, CBOR_CONTEXT_COMMA cose_errback * errp);
extern void _COSE_Recipient_Free(COSE_RecipientInfo *);
-extern bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, int cbitKey, byte * pbKey, cose_errback * errp);
+extern bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, int algIn, int cbitKey, byte * pbKey, cose_errback * errp);
extern bool _COSE_Recipient_encrypt(COSE_RecipientInfo * pRecipient, const byte * pbContent, size_t cbContent, cose_errback * perr);
-extern byte * _COSE_RecipientInfo_generateKey(COSE_RecipientInfo * pRecipient, size_t cbitKeySize, cose_errback * perr);
+extern byte * _COSE_RecipientInfo_generateKey(COSE_RecipientInfo * pRecipient, int algIn, size_t cbitKeySize, cose_errback * perr);
// Signed items
@@ -183,6 +183,11 @@
extern bool _COSE_SignerInfo_Free(COSE_SignerInfo * pSigner);
extern bool _COSE_Signer_validate(COSE_SignMessage * pSign, COSE_SignerInfo * pSigner, const byte * pbContent, size_t cbContent, const byte * pbProtected, size_t cbProtected, cose_errback * perr);
+
+// Sign0 items
+extern HCOSE_SIGN0 _COSE_Sign0_Init_From_Object(cn_cbor * cbor, COSE_Sign0Message * pIn, CBOR_CONTEXT_COMMA cose_errback * perr);
+extern void _COSE_Sign0_Release(COSE_Sign0Message * p);
+
// Mac-ed items
extern HCOSE_MAC _COSE_Mac_Init_From_Object(cn_cbor *, COSE_MacMessage * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
extern bool _COSE_Mac_Release(COSE_MacMessage * p);
diff --git a/src/crypto.h b/src/crypto.h
index 8f7c8df..043c4f9 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -46,6 +46,9 @@
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);
bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbitKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr);
+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);
+bool HKDF_Expand(COSE * pcose, int cbitDigest, const byte * pbPRK, size_t cbPRK, const byte * pbInfo, size_t cbInfo, byte * pbOutput, size_t cbOutput, cose_errback * perr);
+
/**
* Perform a signature operation
*
diff --git a/src/openssl.c b/src/openssl.c
index 4ddfe97..e877bab 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -15,6 +15,7 @@
#include <openssl/ecdsa.h>
#include <openssl/rand.h>
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
bool AES_CCM_Decrypt(COSE_Enveloped * pcose, int TSize, int LSize, const byte * pbKey, int cbKey, const byte * pbCrypto, size_t cbCrypto, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
@@ -536,6 +537,85 @@
}
#endif
+
+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;
+
+ 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);
+
+ HMAC_CTX_init(&ctx);
+ 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, int 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;
+
+ 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;
+ }
+
+ HMAC_CTX_init(&ctx);
+ CHECK_CONDITION(HMAC_Init(&ctx, pbPRK, (int)cbPRK, pmd), COSE_ERR_CRYPTO_FAIL);
+
+ for (ib = 0; ib < cbOutput; ib += cbDigest, bCount += 1) {
+ 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;
+
+}
+
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)
{
HMAC_CTX ctx;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index b1fbb7c..b83ff94 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -29,6 +29,7 @@
enable_testing()
add_test ( NAME cose_test COMMAND cose_test )
+
add_test ( NAME mac-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Mac-02.json )
add_test ( NAME mac-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Mac-04.json )
@@ -37,47 +38,18 @@
add_test ( NAME sig-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Sig-03.json )
add_test ( NAME sig-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Sig-04.json )
+add_test ( NAME enc-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Enc-02.json )
add_test ( NAME enc-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Enc-04.json )
add_test ( NAME enc-05 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Enc-05.json )
-add_test ( NAME hmac-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/hmac-examples )
+add_test ( NAME aes-ccm WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/aes-ccm-examples )
-add_test ( NAME cbc-mac-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-01.json )
-add_test ( NAME cbc-mac-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-02.json )
-add_test ( NAME cbc-mac-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-03.json )
-add_test ( NAME cbc-mac-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-04.json )
+add_test ( NAME aes-gcm WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/aes-gcm-examples )
-add_test ( NAME cbc-mac-enc-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-01.json )
-add_test ( NAME cbc-mac-enc-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-02.json )
-add_test ( NAME cbc-mac-enc-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-03.json )
-add_test ( NAME cbc-mac-enc-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-04.json )
-
-add_test ( NAME aes-gcm-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-01.json )
-add_test ( NAME aes-gcm-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-02.json )
-add_test ( NAME aes-gcm-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-03.json )
-add_test ( NAME aes-gcm-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-04.json )
-
-add_test ( NAME aes-gcm-enc-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-enc-01.json )
-add_test ( NAME aes-gcm-enc-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-enc-02.json )
-add_test ( NAME aes-gcm-enc-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-enc-03.json )
-add_test ( NAME aes-gcm-enc-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-enc-04.json )
-
-add_test ( NAME aes-ccm-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-01.json )
-add_test ( NAME aes-ccm-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-02.json )
-add_test ( NAME aes-ccm-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-03.json )
-add_test ( NAME aes-ccm-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-04.json )
-add_test ( NAME aes-ccm-05 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-05.json )
-add_test ( NAME aes-ccm-06 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-06.json )
-add_test ( NAME aes-ccm-07 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-07.json )
-add_test ( NAME aes-ccm-08 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-08.json )
-
-add_test ( NAME aes-ccm-enc-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-01.json )
-add_test ( NAME aes-ccm-enc-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-02.json )
-add_test ( NAME aes-ccm-enc-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-03.json )
-add_test ( NAME aes-ccm-enc-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-04.json )
-add_test ( NAME aes-ccm-enc-05 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-05.json )
-add_test ( NAME aes-ccm-enc-06 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-06.json )
-add_test ( NAME aes-ccm-enc-07 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-07.json )
-add_test ( NAME aes-ccm-enc-08 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-ccm-examples/aes-ccm-enc-08.json )
+add_test ( NAME cbc-mac WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/cbc-mac-examples )
add_test ( NAME ecdsa WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/ecdsa-examples )
+
+add_test ( NAME hmac WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/hmac-examples )
+
+add_test (NAME hkdf-hmac-sha WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/hkdf-hmac-sha-examples )
diff --git a/test/test.c b/test/test.c
index 11acf5c..43af8e1 100644
--- a/test/test.c
+++ b/test/test.c
@@ -28,7 +28,7 @@
int i;
} NameMap;
-NameMap RgAlgorithmNames[26] = {
+NameMap RgAlgorithmNames[30] = {
{"HS256", COSE_Algorithm_HMAC_256_256},
{"HS256/64", COSE_Algorithm_HMAC_256_64},
{"HS384", COSE_Algorithm_HMAC_384_384},
@@ -55,6 +55,10 @@
{"ES256", COSE_Algorithm_ECDSA_SHA_256},
{"ES384", COSE_Algorithm_ECDSA_SHA_384},
{"ES512", COSE_Algorithm_ECDSA_SHA_512},
+ {"HKDF-HMAC-SHA-256", COSE_Algorithm_Direct_HKDF_HMAC_SHA_256},
+ {"HKDF-HMAC-SHA-512", COSE_Algorithm_Direct_HKDF_HMAC_SHA_512},
+ {"HKDF-AES-128", COSE_Algorithm_Direct_HKDF_AES_128},
+ {"HKDF-AES-256", COSE_Algorithm_Direct_HKDF_AES_256},
};
@@ -82,29 +86,6 @@
return MapName(p, RgAlgorithmNames, _countof(RgAlgorithmNames));
}
-cn_cbor * cn_cbor_clone(const cn_cbor * pIn)
-{
- cn_cbor * pOut = NULL;
- char * sz;
-
- switch (pIn->type) {
- case CN_CBOR_TEXT:
- sz = malloc(pIn->length + 1);
- memcpy(sz, pIn->v.str, pIn->length);
- sz[pIn->length] = 0;
- pOut = cn_cbor_string_create(sz, CBOR_CONTEXT_PARAM_COMMA NULL);
- break;
-
- case CN_CBOR_UINT:
- pOut = cn_cbor_int_create(pIn->v.sint, CBOR_CONTEXT_PARAM_COMMA NULL);
- break;
-
- default:
- break;
- }
-
- return pOut;
-}
byte fromHex(char c)
{
@@ -199,7 +180,8 @@
}
else if (strcmp(pKey->v.str, "ctyp") == 0) {
keyNew = COSE_Header_Content_Type;
- pValueNew = cn_cbor_clone(pValue);;
+ pValueNew = cn_cbor_clone(pValue, CBOR_CONTEXT_PARAM_COMMA NULL);
+ if (pValueNew == NULL) return FALSE;
}
else if (strcmp(pKey->v.str, "IV_hex") == 0) {
keyNew = COSE_Header_IV;
@@ -349,7 +331,7 @@
((RgStringKeys[i].kty == 0) || (RgStringKeys[i].kty == kty))) {
switch (RgStringKeys[i].operation) {
case OPERATION_NONE:
- cn_cbor_mapput_int(pKeyOut, RgStringKeys[i].keyNew, cn_cbor_clone(pValue), CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor_mapput_int(pKeyOut, RgStringKeys[i].keyNew, cn_cbor_clone(pValue, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
break;
case OPERATION_BASE64:
diff --git a/test/test.h b/test/test.h
index b4629b1..b64bc1d 100644
--- a/test/test.h
+++ b/test/test.h
@@ -66,7 +66,6 @@
extern int CFails;
int MapAlgorithmName(const cn_cbor * p);
-cn_cbor * cn_cbor_clone(const cn_cbor * pIn);
byte * GetCBOREncoding(const cn_cbor * pControl, int * pcbEncoded);
bool SetAttributes(HCOSE hHandle, const cn_cbor * pAttributes, int which);
cn_cbor * BuildKey(const cn_cbor * pKeyIn);