Merge pull request #37 from jimsch/master
Merge common encryption/decryption routine
diff --git a/src/Encrypt.c b/src/Encrypt.c
index bd6f25a..8132572 100644
--- a/src/Encrypt.c
+++ b/src/Encrypt.c
@@ -164,42 +164,41 @@
{
COSE_Enveloped * pcose = (COSE_Enveloped *)h;
COSE_RecipientInfo * pRecip = (COSE_RecipientInfo *)hRecip;
- cose_errback error = { 0 };
bool f = false;
CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_HANDLE);
CHECK_CONDITION(IsValidRecipientHandle(hRecip), COSE_ERR_INVALID_HANDLE);
+ CHECK_CONDITION(pcose->m_recipientFirst != NULL, COSE_ERR_INVALID_PARAMETER);
- f = _COSE_Enveloped_decrypt(pcose, pRecip, 0, NULL, &error);
- if (perr != NULL) *perr = error;
+ f = _COSE_Enveloped_decrypt(pcose, pRecip, NULL, 0, "Enveloped", perr);
errorReturn:
return f;
}
-bool _COSE_Enveloped_decrypt(COSE_Enveloped * pcose, COSE_RecipientInfo * pRecip, int cbitKey, byte *pbKeyIn, cose_errback * perr)
+bool _COSE_Enveloped_decrypt(COSE_Enveloped * pcose, COSE_RecipientInfo * pRecip, const byte *pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr)
{
int alg;
const cn_cbor * cn = NULL;
byte * pbKey = pbKeyIn;
+ size_t cbitKey = cbKeyIn * 8;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context;
#endif
byte * pbAuthData = NULL;
size_t cbAuthData;
- byte * pbProtected = NULL;
- ssize_t cbProtected;
#ifdef USE_CBOR_CONTEXT
context = &pcose->m_message.m_allocContext;
#endif
+ CHECK_CONDITION(!((pRecip != NULL) && (pbKeyIn != NULL)), COSE_ERR_INTERNAL);
+
cn = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
if (cn == NULL) {
error:
errorReturn:
- if (pbProtected != NULL) COSE_FREE(pbProtected, context);
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
if ((pbKey != NULL) && (pbKeyIn == NULL)) {
memset(pbKey, 0xff, cbitKey / 8);
@@ -282,36 +281,45 @@
break;
}
- // Allocate the key if we have not already done so
+ //
+ // We are doing the enveloped item - so look for the passed in recipient
+ //
- if (pbKey == NULL) {
- pbKey = COSE_CALLOC(cbitKey / 8, 1, context);
- CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
- }
+ if (pbKeyIn == NULL) {
+ // Allocate the key if we have not already done so
- // If there is a recipient - ask it for the key
+ if (pbKey == NULL) {
+ pbKey = COSE_CALLOC(cbitKey / 8, 1, context);
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
+ }
- for (pRecip = pcose->m_recipientFirst; pRecip != NULL; pRecip = pRecip->m_recipientNext) {
- if (_COSE_Recipient_decrypt(pRecip, alg, cbitKey, pbKey, perr)) break;
- }
+ // If there is a recipient - ask it for the key
- // Build protected headers
+ if (pRecip != NULL) {
+ COSE_RecipientInfo * pRecipX;
- CHECK_CONDITION(pcose->m_message.m_protectedMap != NULL, COSE_ERR_INVALID_PARAMETER);
- if ((pcose->m_message.m_protectedMap != NULL) && (pcose->m_message.m_protectedMap->first_child != NULL)) {
- cbProtected = cn_cbor_encoder_write(RgbDontUse, 0, sizeof(RgbDontUse), pcose->m_message.m_protectedMap);
- pbProtected = (byte *)COSE_CALLOC(cbProtected, 1, context);
- if (pbProtected == NULL) goto error;
- if (cn_cbor_encoder_write(pbProtected, 0, cbProtected, pcose->m_message.m_protectedMap) != cbProtected) goto error;
- }
- else {
- pbProtected = NULL;
- cbProtected = 0;
+ for (pRecipX = pcose->m_recipientFirst; pRecipX != NULL; pRecipX = pRecipX->m_recipientNext) {
+ if (pRecipX == pRecip) {
+ if (!_COSE_Recipient_decrypt(pRecipX, pRecip, alg, cbitKey, pbKey, perr)) goto errorReturn;
+ break;
+ }
+ else if (pRecipX->m_recipientNext != NULL) {
+ if (_COSE_Recipient_decrypt(pRecipX, pRecip, alg, cbitKey, pbKey, perr)) break;
+ }
+ }
+ CHECK_CONDITION(pRecipX != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
+ }
+ else {
+ for (pRecip = pcose->m_recipientFirst; pRecip != NULL; pRecip = pRecip->m_recipientNext) {
+ if (_COSE_Recipient_decrypt(pRecip, NULL, alg, cbitKey, pbKey, perr)) break;
+ }
+ CHECK_CONDITION(pRecip != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
+ }
}
// Build authenticated data
- if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, "Enveloped", perr)) goto errorReturn;
+ if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr)) goto errorReturn;
cn = _COSE_arrayget_int(&pcose->m_message, INDEX_BODY);
CHECK_CONDITION(cn != NULL, COSE_ERR_INVALID_PARAMETER);
@@ -388,7 +396,6 @@
break;
}
- if (pbProtected != NULL) COSE_FREE(pbProtected, context);
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
if ((pbKey != NULL) && (pbKeyIn == NULL)) COSE_FREE(pbKey, context);
if (perr != NULL) perr->err = COSE_ERR_NONE;
@@ -398,6 +405,19 @@
bool COSE_Enveloped_encrypt(HCOSE_ENVELOPED h, cose_errback * perr)
{
+ COSE_Enveloped * pcose = (COSE_Enveloped *)h;
+
+ CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_HANDLE);
+ CHECK_CONDITION(pcose->m_recipientFirst != NULL, COSE_ERR_INVALID_HANDLE);
+
+ return _COSE_Enveloped_encrypt(pcose, NULL, 0, "Enveloped", perr);
+
+errorReturn:
+ return false;
+}
+
+bool _COSE_Enveloped_encrypt(COSE_Enveloped * pcose, const byte * pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr)
+{
int alg;
int t;
COSE_RecipientInfo * pri;
@@ -405,19 +425,12 @@
byte * pbAuthData = NULL;
size_t cbitKey;
#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = NULL;
+ cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
- COSE_Enveloped * pcose = (COSE_Enveloped *) h;
bool fRet = false;
byte * pbKey = NULL;
size_t cbKey = 0;
- CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_HANDLE);
-
-#ifdef USE_CBOR_CONTEXT
- context = &pcose->m_message.m_allocContext;
-#endif // USE_CBOR_CONTEXT
-
cn_Alg = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
if (cn_Alg == NULL) goto errorReturn;
@@ -477,25 +490,42 @@
#endif
#ifdef USE_AES_GCM_128
- case COSE_Algorithm_AES_GCM_128: cbitKey = 128; break;
+ case COSE_Algorithm_AES_GCM_128:
+ cbitKey = 128;
+ break;
#endif
+
#ifdef USE_AES_GCM_192
- case COSE_Algorithm_AES_GCM_192: cbitKey = 192; break;
+ case COSE_Algorithm_AES_GCM_192:
+ cbitKey = 192;
+ break;
#endif
+
#ifdef USE_AES_GCM_256
- case COSE_Algorithm_AES_GCM_256: cbitKey = 256; break;
+ case COSE_Algorithm_AES_GCM_256:
+ cbitKey = 256;
+ break;
#endif
default:
FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
}
- // If we are doing direct encryption - then recipient generates the key
+ // Enveloped or Encrypted?
- if (pbKey == NULL) {
+ if (pbKeyIn != NULL) {
+ CHECK_CONDITION(cbKeyIn == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);
+ pbKey = pbKeyIn;
+ cbKey = cbKeyIn;
+ }
+ else {
+ // If we are doing direct encryption - then recipient generates the key
+
t = 0;
for (pri = pcose->m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
if (pri->m_encrypt.m_message.m_flags & 1) {
+ CHECK_CONDITION(pbKey == NULL, COSE_ERR_INVALID_PARAMETER);
+
t |= 1;
pbKey = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
cbKey = cbitKey / 8;
@@ -506,13 +536,13 @@
}
}
CHECK_CONDITION(t != 3, COSE_ERR_INVALID_PARAMETER);
- }
- if (pbKey == NULL) {
- pbKey = (byte *) COSE_CALLOC(cbitKey/8, 1, context);
- CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
- cbKey = cbitKey / 8;
- rand_bytes(pbKey, cbKey);
+ if (t == 2) {
+ pbKey = (byte *)COSE_CALLOC(cbitKey / 8, 1, context);
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
+ cbKey = cbitKey / 8;
+ rand_bytes(pbKey, cbKey);
+ }
}
// Build protected headers
@@ -523,7 +553,7 @@
// Build authenticated data
size_t cbAuthData = 0;
- if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, "Enveloped", perr)) goto errorReturn;
+ if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr)) goto errorReturn;
switch (alg) {
#ifdef USE_AES_CCM_16_64_128
@@ -606,7 +636,7 @@
errorReturn:
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- if (pbKey != NULL) {
+ if ((pbKey != NULL) && (pbKey != pbKeyIn)) {
memset(pbKey, 0, cbKey);
COSE_FREE(pbKey, context);
}
diff --git a/src/Encrypt0.c b/src/Encrypt0.c
index bca0487..b24fdf2 100644
--- a/src/Encrypt0.c
+++ b/src/Encrypt0.c
@@ -121,7 +121,6 @@
bool COSE_Encrypt_decrypt(HCOSE_ENCRYPT h, const byte * pbKey, size_t cbKey, cose_errback * perr)
{
COSE_Encrypt * pcose = (COSE_Encrypt *)h;
- cose_errback error = { 0 };
bool f;
if (!IsValidEncryptHandle(h)) {
@@ -129,389 +128,19 @@
return false;
}
- f = _COSE_Encrypt_decrypt(pcose, pbKey, cbKey, &error);
- if (perr != NULL) *perr = error;
+ f = _COSE_Enveloped_decrypt(pcose, NULL, pbKey, cbKey, "Encrypted", perr);
return f;
}
-bool _COSE_Encrypt_decrypt(COSE_Encrypt * pcose, const byte * pbKey, size_t cbKey, cose_errback * perr)
-{
- int alg;
- const cn_cbor * cn = NULL;
- size_t cbitKey;
-
-#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context;
-#endif
- byte * pbAuthData = NULL;
- size_t cbAuthData;
- byte * pbProtected = NULL;
- ssize_t cbProtected;
-
-#ifdef USE_CBOR_CONTEXT
- context = &pcose->m_message.m_allocContext;
-#endif
-
- cn = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
- if (cn == NULL) {
- error:
- errorReturn:
- if (pbProtected != NULL) COSE_FREE(pbProtected, context);
- if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- return false;
- }
- CHECK_CONDITION((cn->type == CN_CBOR_UINT) || (cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
- alg = (int) cn->v.uint;
-
- switch (alg) {
-#ifdef USE_AES_CCM_16_64_128
- case COSE_Algorithm_AES_CCM_16_64_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_128
- case COSE_Algorithm_AES_CCM_16_128_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_64_128
- case COSE_Algorithm_AES_CCM_64_64_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_128
- case COSE_Algorithm_AES_CCM_64_128_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_64_256
- case COSE_Algorithm_AES_CCM_64_64_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_256
- case COSE_Algorithm_AES_CCM_16_128_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_256
- case COSE_Algorithm_AES_CCM_64_128_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_64_256
- case COSE_Algorithm_AES_CCM_16_64_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_GCM_128
- case COSE_Algorithm_AES_GCM_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_GCM_192
- case COSE_Algorithm_AES_GCM_192:
- cbitKey = 192;
- break;
-#endif
-
-#ifdef USE_AES_GCM_256
- case COSE_Algorithm_AES_GCM_256:
- cbitKey = 256;
- break;
-#endif
-
- default:
- FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
- break;
- }
-
- CHECK_CONDITION(cbitKey / 8 == cbKey, COSE_ERR_INVALID_PARAMETER);
-
- // Build protected headers
-
- CHECK_CONDITION(pcose->m_message.m_protectedMap != NULL, COSE_ERR_INVALID_PARAMETER);
- if ((pcose->m_message.m_protectedMap != NULL) && (pcose->m_message.m_protectedMap->first_child != NULL)) {
- cbProtected = cn_cbor_encoder_write(RgbDontUse, 0, sizeof(RgbDontUse), pcose->m_message.m_protectedMap);
- pbProtected = (byte *)COSE_CALLOC(cbProtected, 1, context);
- if (pbProtected == NULL) goto error;
- if (cn_cbor_encoder_write(pbProtected, 0, cbProtected, pcose->m_message.m_protectedMap) != cbProtected) goto error;
- }
- else {
- pbProtected = NULL;
- cbProtected = 0;
- }
-
- // Build authenticated data
- if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, "Encrypted", perr)) goto errorReturn;
-
- cn = _COSE_arrayget_int(&pcose->m_message, INDEX_BODY);
- CHECK_CONDITION(cn != NULL, COSE_ERR_INVALID_PARAMETER);
-
- switch (alg) {
-#ifdef USE_AES_CCM_16_64_128
- case COSE_Algorithm_AES_CCM_16_64_128:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 64, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_64_256
- case COSE_Algorithm_AES_CCM_16_64_256:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 64, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_128
- case COSE_Algorithm_AES_CCM_16_128_128:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 128, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_256
- case COSE_Algorithm_AES_CCM_16_128_256:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 128, 16, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_64_128
- case COSE_Algorithm_AES_CCM_64_64_128:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 64, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_64_256
- case COSE_Algorithm_AES_CCM_64_64_256:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 64, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_128
- case COSE_Algorithm_AES_CCM_64_128_128:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 128, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_256
- case COSE_Algorithm_AES_CCM_64_128_256:
- if (!AES_CCM_Decrypt((COSE_Enveloped *)pcose, 128, 64, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_GCM_128
- case COSE_Algorithm_AES_GCM_128:
- if (!AES_GCM_Decrypt((COSE_Enveloped *)pcose, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_GCM_192
- case COSE_Algorithm_AES_GCM_192:
- if (!AES_GCM_Decrypt((COSE_Enveloped *)pcose, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
-#ifdef USE_AES_GCM_256
- case COSE_Algorithm_AES_GCM_256:
- if (!AES_GCM_Decrypt((COSE_Enveloped *)pcose, pbKey, cbitKey / 8, cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) goto error;
- break;
-#endif
-
- default:
- FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
- break;
- }
-
- if (pbProtected != NULL) COSE_FREE(pbProtected, context);
- if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- if (perr != NULL) perr->err = COSE_ERR_NONE;
-
- return true;
-}
-
bool COSE_Encrypt_encrypt(HCOSE_ENCRYPT h, const byte * pbKey, size_t cbKey, cose_errback * perr)
{
- int alg;
- const cn_cbor * cn_Alg = NULL;
- byte * pbAuthData = NULL;
- size_t cbitKey;
-#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = NULL;
-#endif
- COSE_Encrypt * pcose = (COSE_Encrypt *) h;
- bool fRet = false;
+ CHECK_CONDITION(IsValidEncryptHandle(h), COSE_ERR_INVALID_HANDLE);
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_INVALID_PARAMETER);
- CHECK_CONDITION(IsValidEncryptHandle(h), COSE_ERR_INVALID_PARAMETER);
-
-#ifdef USE_CBOR_CONTEXT
- context = &pcose->m_message.m_allocContext;
-#endif // USE_CBOR_CONTEXT
-
- cn_Alg = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
- if (cn_Alg == NULL) goto errorReturn;
-
- CHECK_CONDITION(cn_Alg->type != CN_CBOR_TEXT, COSE_ERR_UNKNOWN_ALGORITHM);
- CHECK_CONDITION((cn_Alg->type == CN_CBOR_UINT) || (cn_Alg->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
- alg = (int) cn_Alg->v.uint;
-
- // Get the key size
-
- switch (alg) {
-#ifdef USE_AES_CCM_64_64_128
- case COSE_Algorithm_AES_CCM_64_64_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_128
- case COSE_Algorithm_AES_CCM_16_128_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_128
- case COSE_Algorithm_AES_CCM_64_128_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_64_128
- case COSE_Algorithm_AES_CCM_16_64_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_64_256
- case COSE_Algorithm_AES_CCM_64_64_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_256
- case COSE_Algorithm_AES_CCM_16_128_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_256
- case COSE_Algorithm_AES_CCM_64_128_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_64_256
- case COSE_Algorithm_AES_CCM_16_64_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_GCM_128
- case COSE_Algorithm_AES_GCM_128: cbitKey = 128; break;
-#endif
-
-#ifdef USE_AES_GCM_192
- case COSE_Algorithm_AES_GCM_192: cbitKey = 192; break;
-#endif
-
-#ifdef USE_AES_GCM_256
- case COSE_Algorithm_AES_GCM_256: cbitKey = 256; break;
-#endif
-
- default:
- FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
- }
-
- // Build protected headers
-
- const cn_cbor * cbProtected = _COSE_encode_protected(&pcose->m_message, perr);
- if (cbProtected == NULL) goto errorReturn;
-
- // Build authenticated data
- size_t cbAuthData = 0;
-
- if (!_COSE_Encrypt_Build_AAD(&pcose->m_message, &pbAuthData, &cbAuthData, "Encrypted", perr)) goto errorReturn;
-
- switch (alg) {
-#ifdef USE_AES_CCM_16_64_128
- case COSE_Algorithm_AES_CCM_16_64_128:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 64, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_64_256
- case COSE_Algorithm_AES_CCM_16_64_256:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 64, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_128
- case COSE_Algorithm_AES_CCM_16_128_128:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 128, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CCM_16_128_256
- case COSE_Algorithm_AES_CCM_16_128_256:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 128, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_64_128
- case COSE_Algorithm_AES_CCM_64_64_128:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 64, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_64_256
- case COSE_Algorithm_AES_CCM_64_64_256:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 64, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_128
- case COSE_Algorithm_AES_CCM_64_128_128:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 128, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CCM_64_128_256
- case COSE_Algorithm_AES_CCM_64_128_256:
- if (!AES_CCM_Encrypt((COSE_Enveloped *)pcose, 128, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_GCM
-#ifdef USE_AES_GCM_128
- case COSE_Algorithm_AES_GCM_128:
-#endif
-#ifdef USE_AES_GCM_192
- case COSE_Algorithm_AES_GCM_192:
-#endif
-#ifdef USE_AES_GCM_256
- case COSE_Algorithm_AES_GCM_256:
-#endif
- if (!AES_GCM_Encrypt((COSE_Enveloped *)pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
- default:
- FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
- }
-
- // Figure out the clean up
-
- fRet = true;
+ return _COSE_Enveloped_encrypt((COSE_Encrypt *)h, pbKey, cbKey, "Encrypted", perr);
errorReturn:
- if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- return fRet;
+ return false;
}
bool COSE_Encrypt_SetContent(HCOSE_ENCRYPT h, const byte * rgb, size_t cb, cose_errback * perror)
diff --git a/src/MacMessage.c b/src/MacMessage.c
index a6a9008..df62f1e 100644
--- a/src/MacMessage.c
+++ b/src/MacMessage.c
@@ -299,6 +299,19 @@
bool COSE_Mac_encrypt(HCOSE_MAC h, cose_errback * perr)
{
+ COSE_MacMessage * pcose = (COSE_MacMessage *)h;
+
+ CHECK_CONDITION(IsValidMacHandle(h), COSE_ERR_INVALID_HANDLE);
+ CHECK_CONDITION(pcose->m_recipientFirst != NULL, COSE_ERR_INVALID_PARAMETER);
+
+ return _COSE_Mac_compute(pcose, NULL, 0, "MAC", perr);
+
+ errorReturn:
+ return false;
+}
+
+bool _COSE_Mac_compute(COSE_MacMessage * pcose, const byte * pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr)
+{
int alg;
int t;
COSE_RecipientInfo * pri;
@@ -306,24 +319,17 @@
byte * pbAuthData = NULL;
size_t cbitKey;
#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = NULL;
+ cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
- COSE_MacMessage * pcose = (COSE_MacMessage *)h;
bool fRet = false;
size_t cbAuthData = 0;
byte * pbKey = NULL;
size_t cbKey = 0;
- CHECK_CONDITION(IsValidMacHandle(h), COSE_ERR_INVALID_PARAMETER);
-
-#ifdef USE_CBOR_CONTEXT
- context = &pcose->m_message.m_allocContext;
-#endif // USE_CBOR_CONTEXT
-
cn_Alg = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
if (cn_Alg == NULL) goto errorReturn;
CHECK_CONDITION(cn_Alg->type != CN_CBOR_TEXT, COSE_ERR_UNKNOWN_ALGORITHM);
- CHECK_CONDITION(((cn_Alg->type == CN_CBOR_UINT || cn_Alg->type == CN_CBOR_INT)), COSE_ERR_UNKNOWN_ALGORITHM);
+ CHECK_CONDITION(((cn_Alg->type == CN_CBOR_UINT || cn_Alg->type == CN_CBOR_INT)), COSE_ERR_INVALID_PARAMETER);
alg = (int) cn_Alg->v.uint;
@@ -384,28 +390,35 @@
// If we are doing direct encryption - then recipient generates the key
- if (pbKey == NULL) {
- t = 0;
- for (pri = pcose->m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
- if (pri->m_encrypt.m_message.m_flags & 1) {
- t |= 1;
- pbKey = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
- cbKey = cbitKey / 8;
- if (pbKey == NULL) goto errorReturn;
- }
- else {
- t |= 2;
- }
- }
- CHECK_CONDITION(t != 3, COSE_ERR_INVALID_PARAMETER);
+ if (pbKeyIn != NULL) {
+ CHECK_CONDITION(cbKeyIn == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);
+ pbKey = pbKeyIn;
+ cbKey = cbKeyIn;
}
+ else {
+ t = 0;
+ for (pri = pcose->m_recipientFirst; pri != NULL; pri = pri->m_recipientNext) {
+ if (pri->m_encrypt.m_message.m_flags & 1) {
+ CHECK_CONDITION(pbKey == NULL, COSE_ERR_INVALID_PARAMETER);
- if (pbKey == NULL) {
- pbKey = (byte *)COSE_CALLOC(cbitKey / 8, 1, context);
- CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
+ t |= 1;
+ pbKey = _COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
+ cbKey = cbitKey / 8;
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
+ }
+ else {
+ t |= 2;
+ }
+ }
+ CHECK_CONDITION(t != 3, COSE_ERR_INVALID_PARAMETER);
- cbKey = cbitKey / 8;
- rand_bytes(pbKey, cbKey);
+ if (t == 2) {
+ pbKey = (byte *)COSE_CALLOC(cbitKey / 8, 1, context);
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ cbKey = cbitKey / 8;
+ rand_bytes(pbKey, cbKey);
+ }
}
// Build protected headers
@@ -415,7 +428,7 @@
// Build authenticated data
- if (!_COSE_Mac_Build_AAD(&pcose->m_message, "MAC", &pbAuthData, &cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!_COSE_Mac_Build_AAD(&pcose->m_message, szContext, &pbAuthData, &cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
switch (alg) {
#ifdef USE_AES_CBC_MAC_128_64
@@ -479,7 +492,7 @@
fRet = true;
errorReturn:
- if (pbKey != NULL) {
+ if ((pbKey != NULL) && (pbKeyIn != pbKey)) {
memset(pbKey, 0, cbKey);
COSE_FREE(pbKey, context);
}
@@ -491,6 +504,17 @@
{
COSE_MacMessage * pcose = (COSE_MacMessage *)h;
COSE_RecipientInfo * pRecip = (COSE_RecipientInfo *)hRecip;
+
+ CHECK_CONDITION(IsValidMacHandle(h) && IsValidRecipientHandle(hRecip), COSE_ERR_INVALID_PARAMETER);
+
+ return _COSE_Mac_validate(pcose, pRecip, NULL, 0, "MAC", perr);
+
+errorReturn:
+ return false;
+}
+
+bool _COSE_Mac_validate(COSE_MacMessage * pcose, COSE_RecipientInfo * pRecip, const byte * pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr)
+{
byte * pbAuthData = NULL;
int cbitKey = 0;
bool fRet = false;
@@ -500,15 +524,11 @@
byte * pbKey = NULL;
#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = NULL;
+ cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
size_t cbAuthData;
- CHECK_CONDITION(IsValidMacHandle(h) && IsValidRecipientHandle(hRecip), COSE_ERR_INVALID_PARAMETER);
-
-#ifdef USE_CBOR_CONTEXT
- context = &pcose->m_message.m_allocContext;
-#endif
+ CHECK_CONDITION(!((pRecip != NULL) && (pbKeyIn != NULL)), COSE_ERR_INTERNAL);
cn = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
if (cn == NULL) goto errorReturn;
@@ -577,26 +597,43 @@
// Allocate the key if we have not already done so
- if (pbKey == NULL) {
- pbKey = COSE_CALLOC(cbitKey / 8, 1, context);
- CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
+ if (pbKeyIn != NULL) {
+ CHECK_CONDITION(cbitKey / 8 == cbKeyIn, COSE_ERR_INVALID_PARAMETER);
+ pbKey = pbKeyIn;
}
+ else {
+ if (pbKey == NULL) {
+ pbKey = COSE_CALLOC(cbitKey / 8, 1, context);
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
+ }
- // If there is a recipient - ask it for the key
+ // 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, alg, cbitKey, pbKey, perr)) break;
+ if (pRecip != NULL) {
+ COSE_RecipientInfo * pRecipX;
+
+ for (pRecipX = pcose->m_recipientFirst; pRecipX != NULL; pRecipX = pRecipX->m_recipientNext) {
+ if (pRecip == pRecipX) {
+ if (!_COSE_Recipient_decrypt(pRecipX, pRecip, alg, cbitKey, pbKey, perr)) goto errorReturn;
+ break;
+ }
+ else if (pRecipX->m_recipientNext != NULL) {
+ if (_COSE_Recipient_decrypt(pRecipX, pRecip, alg, cbitKey, pbKey, perr)) break;
+ }
+ }
+ CHECK_CONDITION(pRecipX != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
+ }
+ else {
+ for (pRecip = pcose->m_recipientFirst; pRecip != NULL; pRecip = pRecip->m_recipientNext) {
+ if (_COSE_Recipient_decrypt(pRecip, NULL, alg, cbitKey, pbKey, perr)) break;
+ }
+ CHECK_CONDITION(pRecip != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
+ }
}
- CHECK_CONDITION(pRecip != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
-
- // Build protected headers
-
- cn_cbor * cnProtected = _COSE_arrayget_int(&pcose->m_message, INDEX_PROTECTED);
- CHECK_CONDITION((cnProtected != NULL) && (cnProtected->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
// Build authenticated data
- if (!_COSE_Mac_Build_AAD(&pcose->m_message, "MAC", &pbAuthData, &cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!_COSE_Mac_Build_AAD(&pcose->m_message, szContext, &pbAuthData, &cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
switch (alg) {
#ifdef USE_HMAC_256_256
@@ -655,7 +692,7 @@
fRet = true;
errorReturn:
- if ((pbKey != NULL)) {
+ if ((pbKey != NULL) && (pbKey != pbKeyIn)) {
memset(pbKey, 0xff, cbitKey / 8);
COSE_FREE(pbKey, context);
}
diff --git a/src/MacMessage0.c b/src/MacMessage0.c
index 11a6542..43df47b 100644
--- a/src/MacMessage0.c
+++ b/src/MacMessage0.c
@@ -200,232 +200,169 @@
bool COSE_Mac0_encrypt(HCOSE_MAC0 h, const byte * pbKey, size_t cbKey, cose_errback * perr)
{
- int alg;
- const cn_cbor * cn_Alg = NULL;
- byte * pbAuthData = NULL;
- size_t cbitKey;
-#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = NULL;
-#endif
COSE_Mac0Message * pcose = (COSE_Mac0Message *)h;
- bool fRet = false;
- size_t cbAuthData;
- CHECK_CONDITION(IsValidMac0Handle(h), COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(IsValidMac0Handle(h), COSE_ERR_INVALID_HANDLE);
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_INVALID_PARAMETER);
-#ifdef USE_CBOR_CONTEXT
- context = &pcose->m_message.m_allocContext;
-#endif // USE_CBOR_CONTEXT
-
- cn_Alg = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
- if (cn_Alg == NULL) goto errorReturn;
- CHECK_CONDITION(cn_Alg->type != CN_CBOR_TEXT, COSE_ERR_UNKNOWN_ALGORITHM);
- CHECK_CONDITION(((cn_Alg->type == CN_CBOR_UINT || cn_Alg->type == CN_CBOR_INT)), COSE_ERR_INVALID_PARAMETER);
-
- alg = (int) cn_Alg->v.uint;
-
- // Get the key size
-
- switch (alg) {
-#ifdef USE_AES_CBC_MAC_128_64
- case COSE_Algorithm_CBC_MAC_128_64:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_128_128
- case COSE_Algorithm_CBC_MAC_128_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_256_64
- case COSE_Algorithm_CBC_MAC_256_64:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_256_128
- case COSE_Algorithm_CBC_MAC_256_128:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_HMAC_256_64
- case COSE_Algorithm_HMAC_256_64:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_HMAC_256_256
- case COSE_Algorithm_HMAC_256_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_HMAC_384_384
- case COSE_Algorithm_HMAC_384_384:
- cbitKey = 384;
- break;
-#endif
-
-#ifdef USE_HMAC_512_512
- case COSE_Algorithm_HMAC_512_512:
- cbitKey = 512;
- break;
-#endif
-
- default:
- FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
- }
-
- // Build protected headers
-
- const cn_cbor * cbProtected = _COSE_encode_protected(&pcose->m_message, perr);
- if (cbProtected == NULL) goto errorReturn;
-
- // Build authenticated data
- if (!_COSE_Mac_Build_AAD(&pcose->m_message, "MAC0", &pbAuthData, &cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
-
- switch (alg) {
-#ifdef USE_AES_CBC_MAC_128_64
- case COSE_Algorithm_CBC_MAC_128_64:
- if (!AES_CBC_MAC_Create((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_256_64
- case COSE_Algorithm_CBC_MAC_256_64:
- if (!AES_CBC_MAC_Create((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_128_128
- case COSE_Algorithm_CBC_MAC_128_128:
- if (!AES_CBC_MAC_Create((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_256_128
- case COSE_Algorithm_CBC_MAC_256_128:
- if (!AES_CBC_MAC_Create((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_HMAC_256_64
- case COSE_Algorithm_HMAC_256_64:
- if (!HMAC_Create((COSE_MacMessage *)pcose, 256, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_HMAC_256_256
- case COSE_Algorithm_HMAC_256_256:
- if (!HMAC_Create((COSE_MacMessage *)pcose, 256, 256, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_HMAC_384_384
- case COSE_Algorithm_HMAC_384_384:
- if (!HMAC_Create((COSE_MacMessage *)pcose, 384, 384, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_HMAC_512_512
- case COSE_Algorithm_HMAC_512_512:
- if (!HMAC_Create((COSE_MacMessage *)pcose, 512, 512, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
- default:
- FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
- }
-
- // Figure out the clean up
-
- fRet = true;
+ return _COSE_Mac_compute(pcose, pbKey, cbKey, "MAC0", perr);
errorReturn:
- if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- return fRet;
+ return false;
}
bool COSE_Mac0_validate(HCOSE_MAC0 h, const byte * pbKey, size_t cbKey, cose_errback * perr)
{
COSE_Mac0Message * pcose = (COSE_Mac0Message *)h;
- byte * pbAuthData = NULL;
- int cbitKey = 0;
- bool fRet = false;
- int alg;
- const cn_cbor * cn = NULL;
+ CHECK_CONDITION(IsValidMac0Handle(h), COSE_ERR_INVALID_HANDLE);
+ CHECK_CONDITION(pbKey != NULL, COSE_ERR_INVALID_PARAMETER);
+
+ return _COSE_Mac_validate(pcose, NULL, pbKey, cbKey, "MAC0", perr);
+
+errorReturn:
+ return false;
+}
+
+#if 0
+ int foo() {
+ COSE_Mac0Message * pcose = (COSE_Mac0Message *)h;
+ byte * pbAuthData = NULL;
+ int cbitKey = 0;
+ bool fRet = false;
+ int alg;
+ const cn_cbor * cn = NULL;
#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = NULL;
+ cn_cbor_context * context = NULL;
#endif
- size_t cbAuthData;
+ size_t cbAuthData;
- CHECK_CONDITION(IsValidMac0Handle(h), COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(IsValidMac0Handle(h), COSE_ERR_INVALID_PARAMETER);
#ifdef USE_CBOR_CONTEXT
- context = &pcose->m_message.m_allocContext;
+ context = &pcose->m_message.m_allocContext;
#endif
- cn = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
- if (cn == NULL) goto errorReturn;
+ cn = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
+ if (cn == NULL) goto errorReturn;
- if (cn->type == CN_CBOR_TEXT) {
+ if (cn->type == CN_CBOR_TEXT) {
FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
- }
- else {
- CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
+ }
+ else {
+ CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
- alg = (int)cn->v.uint;
+ alg = (int)cn->v.uint;
+
+ switch (alg) {
+#ifdef USE_AES_CBC_MAC_128_64
+ case COSE_Algorithm_CBC_MAC_128_64:
+ cbitKey = 128;
+ break;
+#endif
+
+#ifdef USE_AES_CBC_MAC_128_128
+ case COSE_Algorithm_CBC_MAC_128_128:
+ cbitKey = 128;
+ break;
+#endif
+
+#ifdef USE_AES_CBC_MAC_256_64
+ case COSE_Algorithm_CBC_MAC_256_64:
+ cbitKey = 256;
+ break;
+#endif
+
+#ifdef USE_AES_CBC_MAC_256_128
+ case COSE_Algorithm_CBC_MAC_256_128:
+ cbitKey = 256;
+ break;
+#endif
+
+#ifdef USE_HMAC_256_64
+ case COSE_Algorithm_HMAC_256_64:
+ cbitKey = 256;
+ break;
+#endif
+
+#ifdef USE_HMAC_256_256
+ case COSE_Algorithm_HMAC_256_256:
+ cbitKey = 256;
+ break;
+#endif
+
+#ifdef USE_HMAC_384_384
+ case COSE_Algorithm_HMAC_384_384:
+ cbitKey = 384;
+ break;
+#endif
+
+#ifdef USE_HMAC_512_512
+ case COSE_Algorithm_HMAC_512_512:
+ cbitKey = 512;
+ break;
+#endif
+
+ default:
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ break;
+ }
+ }
+
+ // Build protected headers
+
+ cn_cbor * cnProtected = _COSE_arrayget_int(&pcose->m_message, INDEX_PROTECTED);
+ CHECK_CONDITION((cnProtected != NULL) && (cnProtected->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
+
+ // Build authenticated data
+ if (!_COSE_Mac_Build_AAD(&pcose->m_message, "MAC0", &pbAuthData, &cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
switch (alg) {
+#ifdef USE_HMAC_256_256
+ case COSE_Algorithm_HMAC_256_256:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 256, 256, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+#endif
+
+#ifdef USE_HMAC_256_64
+ case COSE_Algorithm_HMAC_256_64:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 256, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+#endif
+
+#ifdef USE_HMAC_384_384
+ case COSE_Algorithm_HMAC_384_384:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 384, 384, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+#endif
+
+#ifdef USE_HMAC_512_512
+ case COSE_Algorithm_HMAC_512_512:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 512, 512, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+#endif
+
#ifdef USE_AES_CBC_MAC_128_64
case COSE_Algorithm_CBC_MAC_128_64:
- cbitKey = 128;
+ if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+#endif
+
+#ifdef USE_AES_CBC_MAC_256_64
+ case COSE_Algorithm_CBC_MAC_256_64:
+ if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
#endif
#ifdef USE_AES_CBC_MAC_128_128
case COSE_Algorithm_CBC_MAC_128_128:
- cbitKey = 128;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_256_64
- case COSE_Algorithm_CBC_MAC_256_64:
- cbitKey = 256;
+ if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
#endif
#ifdef USE_AES_CBC_MAC_256_128
- case COSE_Algorithm_CBC_MAC_256_128:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_HMAC_256_64
- case COSE_Algorithm_HMAC_256_64:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_HMAC_256_256
- case COSE_Algorithm_HMAC_256_256:
- cbitKey = 256;
- break;
-#endif
-
-#ifdef USE_HMAC_384_384
- case COSE_Algorithm_HMAC_384_384:
- cbitKey = 384;
- break;
-#endif
-
-#ifdef USE_HMAC_512_512
- case COSE_Algorithm_HMAC_512_512:
- cbitKey = 512;
+ case COSE_Algorithm_CBC_MAC_256_128:
+ if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
#endif
@@ -433,74 +370,13 @@
FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
break;
}
+
+ fRet = true;
+
+ errorReturn:
+ if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
+
+ return fRet;
}
- // Build protected headers
-
- cn_cbor * cnProtected = _COSE_arrayget_int(&pcose->m_message, INDEX_PROTECTED);
- CHECK_CONDITION((cnProtected != NULL) && (cnProtected->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
-
- // Build authenticated data
- if (!_COSE_Mac_Build_AAD(&pcose->m_message, "MAC0", &pbAuthData, &cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
-
- switch (alg) {
-#ifdef USE_HMAC_256_256
- case COSE_Algorithm_HMAC_256_256:
- if (!HMAC_Validate((COSE_MacMessage *)pcose, 256, 256, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_HMAC_256_64
- case COSE_Algorithm_HMAC_256_64:
- if (!HMAC_Validate((COSE_MacMessage *)pcose, 256, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_HMAC_384_384
- case COSE_Algorithm_HMAC_384_384:
- if (!HMAC_Validate((COSE_MacMessage *)pcose, 384, 384, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_HMAC_512_512
- case COSE_Algorithm_HMAC_512_512:
- if (!HMAC_Validate((COSE_MacMessage *)pcose, 512, 512, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_128_64
- case COSE_Algorithm_CBC_MAC_128_64:
- if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_256_64
- case COSE_Algorithm_CBC_MAC_256_64:
- if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_128_128
- case COSE_Algorithm_CBC_MAC_128_128:
- if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
-#ifdef USE_AES_CBC_MAC_256_128
- case COSE_Algorithm_CBC_MAC_256_128:
- if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-#endif
-
- default:
- FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
- break;
- }
-
- fRet = true;
-
-errorReturn:
- if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
-
- return fRet;
-}
+#endif
\ No newline at end of file
diff --git a/src/Recipient.c b/src/Recipient.c
index a40bef5..ff6cc02 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -220,7 +220,7 @@
return fRet;
}
-bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, int algIn, int cbitKeyOut, byte * pbKeyOut, cose_errback * perr)
+bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, COSE_RecipientInfo * pRecipUse, int algIn, int cbitKeyOut, byte * pbKeyOut, cose_errback * perr)
{
int alg;
const cn_cbor * cn = NULL;
@@ -366,7 +366,7 @@
CHECK_CONDITION(pbKeyX != NULL, COSE_ERR_OUT_OF_MEMORY);
for (pRecip2 = pcose->m_recipientFirst; pRecip2 != NULL; pRecip2 = pRecip->m_recipientNext) {
- if (_COSE_Recipient_decrypt(pRecip2, alg, cbitKeyX, pbKeyX, perr)) break;
+ if (_COSE_Recipient_decrypt(pRecip2, NULL, alg, cbitKeyX, pbKeyX, perr)) break;
}
CHECK_CONDITION(pRecip2 != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
}
diff --git a/src/cose.h b/src/cose.h
index 8add444..ab4c19c 100644
--- a/src/cose.h
+++ b/src/cose.h
@@ -32,7 +32,9 @@
/** Decryption operation failed */
COSE_ERR_DECRYPT_FAILED,
/** Cryptographic failure */
- COSE_ERR_CRYPTO_FAIL
+ COSE_ERR_CRYPTO_FAIL,
+ /** Internal Error */
+ COSE_ERR_INTERNAL
} cose_error;
typedef enum cose_init_flags {
diff --git a/src/cose_int.h b/src/cose_int.h
index 5940398..4fc9254 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -43,11 +43,13 @@
struct _RecipientInfo;
typedef struct _RecipientInfo COSE_RecipientInfo;
+#if 0
typedef struct {
COSE m_message; // The message object
const byte * pbContent;
size_t cbContent;
} COSE_Encrypt;
+#endif
typedef struct {
COSE m_message; // The message object
@@ -56,6 +58,8 @@
COSE_RecipientInfo * m_recipientFirst;
} COSE_Enveloped;
+typedef COSE_Enveloped COSE_Encrypt;
+
struct _RecipientInfo {
COSE_Enveloped m_encrypt;
COSE_RecipientInfo * m_recipientNext;
@@ -68,9 +72,12 @@
COSE_RecipientInfo * m_recipientFirst;
} COSE_MacMessage;
+#if 0
typedef struct {
COSE m_message; // The message object
} COSE_Mac0Message;
+#endif
+typedef COSE_MacMessage COSE_Mac0Message;
#ifdef USE_CBOR_CONTEXT
/**
@@ -155,19 +162,19 @@
extern HCOSE_ENVELOPED _COSE_Enveloped_Init_From_Object(cn_cbor *, COSE_Enveloped * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
extern void _COSE_Enveloped_Release(COSE_Enveloped * p);
-extern bool _COSE_Enveloped_decrypt(COSE_Enveloped * pcose, COSE_RecipientInfo * pRecip, int cbitKey, byte *pbKeyIn, cose_errback * perr);
+extern bool _COSE_Enveloped_decrypt(COSE_Enveloped * pcose, COSE_RecipientInfo * pRecip, const byte *pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr);
+extern bool _COSE_Enveloped_encrypt(COSE_Enveloped * pcose, const byte * pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr);
extern bool _COSE_Enveloped_SetContent(COSE_Enveloped * cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);
extern HCOSE_ENCRYPT _COSE_Encrypt_Init_From_Object(cn_cbor *, COSE_Encrypt * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
extern void _COSE_Encrypt_Release(COSE_Encrypt * p);
-extern bool _COSE_Encrypt_decrypt(COSE_Encrypt * pcose, const byte * pbKey, size_t cbKey, cose_errback * perr);
extern bool _COSE_Encrypt_SetContent(COSE_Encrypt * cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);
extern bool _COSE_Encrypt_Build_AAD(COSE * pMessage, byte ** ppbAAD, size_t * pcbAAD, const char * szContext, cose_errback * perr);
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 algIn, int cbitKey, byte * pbKey, cose_errback * errp);
+extern bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, COSE_RecipientInfo * pRecipUse, 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, int algIn, size_t cbitKeySize, cose_errback * perr);
@@ -190,6 +197,8 @@
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);
extern bool _COSE_Mac_Build_AAD(COSE * pCose, char * szContext, byte ** ppbAuthData, size_t * pcbAuthData, CBOR_CONTEXT_COMMA cose_errback * perr);
+extern bool _COSE_Mac_compute(COSE_MacMessage * pcose, const byte * pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr);
+extern bool _COSE_Mac_validate(COSE_MacMessage * pcose, COSE_RecipientInfo * pRecip, const byte * pbKeyIn, size_t cbKeyIn, const char * szContext, cose_errback * perr);
// MAC0 Items
extern HCOSE_MAC0 _COSE_Mac0_Init_From_Object(cn_cbor *, COSE_Mac0Message * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
diff --git a/src/openssl.c b/src/openssl.c
index ef53f19..82d5296 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -34,7 +34,6 @@
cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
- assert(perr != NULL);
EVP_CIPHER_CTX_init(&ctx);
// Setup the IV/Nonce and put it into the message
@@ -214,7 +213,6 @@
#endif
int TSize = 128 / 8;
- assert(perr != NULL);
EVP_CIPHER_CTX_init(&ctx);
// Setup the IV/Nonce and put it into the message