Change how static static keys are added for sending
diff --git a/src/Cose.c b/src/Cose.c
index 612f761..3b18219 100644
--- a/src/Cose.c
+++ b/src/Cose.c
@@ -328,10 +328,6 @@
break;
case COSE_DONT_SEND:
- if (pCose->m_dontSendMap == NULL) {
- pCose->m_dontSendMap = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA &error);
- CHECK_CONDITION(pCose->m_dontSendMap != NULL, COSE_ERR_OUT_OF_MEMORY);
- }
f = cn_cbor_mapput_int(pCose->m_dontSendMap, key, value, CBOR_CONTEXT_PARAM_COMMA &error);
break;
diff --git a/src/Recipient.c b/src/Recipient.c
index 63b659b..f7ba63e 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -128,7 +128,8 @@
*
* @param[in] COSE * Pointer to COSE Encryption context object
* @param[in] int Alorithm key is being generated for
-* @param[in] cn_cbor * Key used for operation
+* @param[in] cn_cbor * Private key
+* @param[in] cn_cbor * Public Key
* @param[out] byte * Buffer to return new key in
* @param[in] size_t Size of key to create in bits
* @param[in] size_t Size of digest function
@@ -137,7 +138,7 @@
* @return Did the function succeed?
*/
-static bool HKDF_X(COSE * pCose, bool fHMAC, bool fECDH, bool fStatic, bool fSend, int algResult, const cn_cbor * pKey, byte * pbKey, size_t cbitKey, size_t cbitHash, CBOR_CONTEXT_COMMA cose_errback * perr)
+static bool HKDF_X(COSE * pCose, bool fHMAC, bool fECDH, bool fStatic, bool fSend, int algResult, const cn_cbor * pKeyPrivate, const cn_cbor * pKeyPublic, byte * pbKey, size_t cbitKey, size_t cbitHash, CBOR_CONTEXT_COMMA cose_errback * perr)
{
byte * pbContext = NULL;
size_t cbContext;
@@ -150,30 +151,51 @@
if (!BuildContextBytes(pCose, algResult, cbitKey, &pbContext, &cbContext, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
- cn = cn_cbor_mapget_int(pKey, COSE_Key_Type);
- CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);
if (fECDH) {
cn_cbor * pkeyMessage;
- pkeyMessage = _COSE_map_get_int(pCose, fStatic ? COSE_Header_ECDH_STATIC : COSE_Header_ECDH_EPHEMERAL, COSE_BOTH, perr);
+ if (pKeyPrivate != NULL) {
+ cn = cn_cbor_mapget_int(pKeyPrivate, COSE_Key_Type);
+ CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(cn->v.uint == COSE_Key_Type_EC2, COSE_ERR_INVALID_PARAMETER);
+ }
- CHECK_CONDITION(pKey != NULL, COSE_ERR_INVALID_PARAMETER);
+ if (pKeyPublic != NULL) {
+ cn = cn_cbor_mapget_int(pKeyPublic, COSE_Key_Type);
+ CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(cn->v.uint == COSE_Key_Type_EC2, COSE_ERR_INVALID_PARAMETER);
+ }
+
if (fSend) {
- if (!ECDH_ComputeSecret(pCose, &pkeyMessage, pKey, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ CHECK_CONDITION(pKeyPublic != NULL, COSE_ERR_INVALID_PARAMETER);
+ pkeyMessage = pKeyPrivate;
+
+ if (!ECDH_ComputeSecret(pCose, &pkeyMessage, pKeyPublic, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (pkeyMessage->parent == NULL) {
if (!_COSE_map_put(pCose, COSE_Header_ECDH_EPHEMERAL, pkeyMessage, COSE_UNPROTECT_ONLY, perr)) goto errorReturn;
}
}
else {
+
+ pkeyMessage = _COSE_map_get_int(pCose, fStatic ? COSE_Header_ECDH_STATIC : COSE_Header_ECDH_EPHEMERAL, COSE_BOTH, perr);
+
CHECK_CONDITION(pkeyMessage != NULL, COSE_ERR_INVALID_PARAMETER);
- if (!ECDH_ComputeSecret(pCose, (cn_cbor **)&pKey, pkeyMessage, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ CHECK_CONDITION(pKeyPrivate != NULL, COSE_ERR_INVALID_PARAMETER);
+
+ if (!ECDH_ComputeSecret(pCose, (cn_cbor **)&pKeyPrivate, pkeyMessage, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
}
}
else {
+ if (pKeyPrivate != NULL) {
+ cn = cn_cbor_mapget_int(pKeyPrivate, COSE_Key_Type);
+ CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(cn->v.uint == COSE_Key_Type_OCTET, COSE_ERR_INVALID_PARAMETER);
+ }
+
CHECK_CONDITION(cn->v.sint == 4, COSE_ERR_INVALID_PARAMETER);
- cn = cn_cbor_mapget_int(pKey, -1);
+ cn = cn_cbor_mapget_int(pKeyPrivate, -1);
CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
pbSecret = (byte *) cn->v.bytes;
cbSecret = cn->length;
@@ -299,74 +321,74 @@
break;
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
- if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
- if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_Direct_HKDF_AES_128:
- if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 128, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 128, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_Direct_HKDF_AES_256:
- if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_HKDF_256:
- if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_HKDF_512:
- if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_HKDF_256:
- if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_HKDF_512:
- if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn, pRecip->m_pkey, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn, pRecip->m_pkey, NULL, pbKey, cbitKey, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_A128KW:
- if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_128, pRecip->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_128, pRecip->m_pkey, NULL, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 128, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_A192KW:
- if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_192, pRecip->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_192, pRecip->m_pkey, NULL, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 192, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_A256KW:
- if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_256, pRecip->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, false, false, COSE_Algorithm_AES_KW_256, pRecip->m_pkey, NULL, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 256, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_A128KW:
- if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_128, pRecip->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_128, pRecip->m_pkey, NULL, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 128, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_A192KW:
- if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_192, pRecip->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_192, pRecip->m_pkey, NULL, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 192, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_A256KW:
- if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_256, pRecip->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pcose->m_message, true, true, true, false, COSE_Algorithm_AES_KW_256, pRecip->m_pkey, NULL, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 256, cnBody->v.bytes, cnBody->length, pbKey, &cbKey2, perr)) goto errorReturn;
@@ -518,32 +540,32 @@
break;
case COSE_Algorithm_ECDH_ES_A128KW:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_128, pRecipient->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_128, NULL, pRecipient->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Encrypt(pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_A192KW:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_192, pRecipient->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_192, NULL, pRecipient->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Encrypt(pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_A256KW:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_256, pRecipient->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, COSE_Algorithm_AES_KW_256, NULL, pRecipient->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Encrypt(pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_A128KW:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_128, pRecipient->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_128, pRecipient->m_pkeyStatic, pRecipient->m_pkey, rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Encrypt(pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_A192KW:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_192, pRecipient->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_192, pRecipient->m_pkeyStatic, pRecipient->m_pkey, rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Encrypt(pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_A256KW:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_256, pRecipient->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, COSE_Algorithm_AES_KW_256, pRecipient->m_pkeyStatic, pRecipient->m_pkey, rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
if (!AES_KW_Encrypt(pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr)) goto errorReturn;
break;
@@ -603,35 +625,35 @@
break;
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false, true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false, true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_Direct_HKDF_AES_128:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 128, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false, true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 128, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_Direct_HKDF_AES_256:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false, true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_HKDF_256:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, algIn, NULL, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_ES_HKDF_512:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false, true, algIn, NULL, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_HKDF_256:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, algIn, pRecipient->m_pkeyStatic, pRecipient->m_pkey, pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDH_SS_HKDF_512:
- if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, algIn, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+ if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true, true, algIn, pRecipient->m_pkeyStatic, pRecipient->m_pkey, pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
break;
default:
@@ -746,6 +768,97 @@
}
/*!
+* @brief Set the senders static key for ECDH key agreement algorithms
+*
+* Set the Static private key to be used in computing ECDH key agreement
+* operation.
+*
+* Private portion of the key is not zeroed when the recipient object is
+* released.
+*
+* @param h Handle to the recipient object
+* @param pKey pointer to COSE key structure contiaing the private key
+* @param destination 0 - set nothing, 1 - set spk_kid, 2 - set spk
+* @param perr location for return of error code
+* @return true on success
+*/
+
+bool COSE_Recipient_SetSenderKey(HCOSE_RECIPIENT h, const cn_cbor * pKey, int destination, cose_errback * perr)
+{
+ COSE_RecipientInfo * p;
+ bool f = false;
+ cn_cbor * cn;
+ cn_cbor * cn2 = NULL;
+ cn_cbor * cn3 = NULL;
+ cn_cbor_errback cbor_err;
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context;
+#endif;
+
+ CHECK_CONDITION(IsValidRecipientHandle(h), COSE_ERR_INVALID_HANDLE);
+ CHECK_CONDITION(pKey != NULL, COSE_ERR_INVALID_PARAMETER);
+
+ p = (COSE_RecipientInfo *)h;
+
+#ifdef USE_CBOR_CONTEXT
+ context = &p->m_encrypt.m_message.m_allocContext;
+#endif
+
+ switch (destination) {
+ case 0:
+ break;
+
+ case 1:
+ cn = cn_cbor_mapget_int(pKey, COSE_Key_ID);
+ CHECK_CONDITION(cn != NULL, COSE_ERR_INVALID_PARAMETER);
+ cn2 = cn_cbor_clone(cn, CBOR_CONTEXT_PARAM_COMMA &cbor_err);
+ CHECK_CONDITION_CBOR(cn2 != NULL, cbor_err);
+ CHECK_CONDITION(_COSE_map_put(&p->m_encrypt.m_message, COSE_Header_ECDH_SPK_KID, cn2, COSE_UNPROTECT_ONLY, perr), perr->err);
+ cn2 = NULL;
+ break;
+
+ case 2:
+ cn2 = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA &cbor_err);
+ CHECK_CONDITION_CBOR(cn2 != NULL, cbor_err);
+ cn = cn_cbor_mapget_int(pKey, COSE_Key_Type);
+ CHECK_CONDITION(cn != NULL, COSE_ERR_INVALID_PARAMETER);
+ cn3 = cn_cbor_clone(cn, CBOR_CONTEXT_PARAM_COMMA &cbor_err);
+ CHECK_CONDITION_CBOR(cn3 != NULL, cbor_err);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(cn2, COSE_Key_Type, cn3, CBOR_CONTEXT_PARAM_COMMA &cbor_err), cbor_err);
+ cn3 = NULL;
+ cn = cn_cbor_mapget_int(pKey, COSE_Key_EC2_Curve);
+ cn3 = cn_cbor_clone(cn, CBOR_CONTEXT_PARAM_COMMA &cbor_err);
+ CHECK_CONDITION_CBOR(cn3 != NULL, cbor_err);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(cn2, COSE_Key_EC2_Curve, cn3, CBOR_CONTEXT_PARAM_COMMA &cbor_err), cbor_err);
+ cn3 = NULL;
+ cn = cn_cbor_mapget_int(pKey, COSE_Key_EC2_X);
+ cn3 = cn_cbor_clone(cn, CBOR_CONTEXT_PARAM_COMMA &cbor_err);
+ CHECK_CONDITION_CBOR(cn3 != NULL, cbor_err);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(cn2, COSE_Key_EC2_X, cn3, CBOR_CONTEXT_PARAM_COMMA &cbor_err), cbor_err);
+ cn3 = NULL;
+ cn = cn_cbor_mapget_int(pKey, COSE_Key_EC2_Y);
+ cn3 = cn_cbor_clone(cn, CBOR_CONTEXT_PARAM_COMMA &cbor_err);
+ CHECK_CONDITION_CBOR(cn3 != NULL, cbor_err);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(cn2, COSE_Key_EC2_Y, cn3, CBOR_CONTEXT_PARAM_COMMA &cbor_err), cbor_err);
+ cn3 = NULL;
+ CHECK_CONDITION(_COSE_map_put(&p->m_encrypt.m_message, COSE_Header_ECDH_SPK, cn2, COSE_UNPROTECT_ONLY, perr), perr->err);
+ cn2 = NULL;
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
+
+ p->m_pkeyStatic = pKey;
+
+ f = true;
+errorReturn:
+ if (cn2 != NULL) CN_CBOR_FREE(cn2, context);
+ if (cn3 != NULL) CN_CBOR_FREE(cn3, context);
+ return f;
+}
+
+/*!
* @brief Set the application external data for authentication
*
* Recipient data objects support the authentication of external application
diff --git a/src/cose.h b/src/cose.h
index 7232bb6..2df6954 100644
--- a/src/cose.h
+++ b/src/cose.h
@@ -153,15 +153,22 @@
COSE_Header_UseCompressedECDH = -997,
COSE_Header_ECDH_EPHEMERAL = -1,
- COSE_Header_ECDH_STATIC = -2
+ COSE_Header_ECDH_STATIC = -2,
+ COSE_Header_ECDH_EPK = -1,
+ COSE_Header_ECDH_SPK = -2,
+ COSE_Header_ECDH_SPK_KID = -2,
} COSE_Header;
typedef enum {
COSE_Key_Type_EC2 = 2,
+ COSE_Key_Type_OCTET = 4,
COSE_Key_Type = 1,
COSE_Key_ID = 2,
COSE_Parameter_KID = 4,
+ COSE_Key_EC2_Curve=-1,
+ COSE_Key_EC2_X = -2,
+ COSE_Key_EC2_Y = -3
} COSE_Constants;
@@ -197,6 +204,7 @@
bool COSE_Recipient_SetKey_secret(HCOSE_RECIPIENT h, const byte * rgb, int cb, const byte * rgbKid, int cbKid, cose_errback * perr);
bool COSE_Recipient_SetKey(HCOSE_RECIPIENT h, const cn_cbor * pKey, cose_errback * perror);
+bool COSE_Recipient_SetSenderKey(HCOSE_RECIPIENT h, const cn_cbor * pKey, cose_errback * perror);
bool COSE_Recipient_SetExternal(HCOSE_RECIPIENT hcose, const byte * pbExternalData, size_t cbExternalData, cose_errback * perr);
bool COSE_Recipient_map_put(HCOSE_RECIPIENT h, int key, cn_cbor * value, int flags, cose_errback * perror);
diff --git a/src/cose_int.h b/src/cose_int.h
index ead32c2..5940398 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -60,6 +60,7 @@
COSE_Enveloped m_encrypt;
COSE_RecipientInfo * m_recipientNext;
const cn_cbor * m_pkey;
+ const cn_cbor * m_pkeyStatic;
};
typedef struct {
diff --git a/src/openssl.c b/src/openssl.c
index 9ce333f..9a88a7d 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -16,6 +16,8 @@
#include <openssl/ecdh.h>
#include <openssl/rand.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)
@@ -803,16 +805,25 @@
CHECK_CONDITION(ecgroup != NULL, COSE_ERR_INVALID_PARAMETER);
CHECK_CONDITION(EC_KEY_set_group(pNewKey, ecgroup) == 1, COSE_ERR_CRYPTO_FAIL);
- rgbKey[0] = POINT_CONVERSION_UNCOMPRESSED;
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) && (p->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
- CHECK_CONDITION(p->length == *cbGroup, COSE_ERR_INVALID_PARAMETER);
- memcpy(rgbKey + p->length+1, p->v.str, p->length);
+ CHECK_CONDITION((p != NULL), COSE_ERR_INVALID_PARAMETER);
+ if (p->type == CN_CBOR_BYTES) {
+ rgbKey[0] = POINT_CONVERSION_UNCOMPRESSED;
+ 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) {
+ rgbKey[0] = POINT_CONVERSION_COMPRESSED + 1;
+ }
+ else if (p->type == CN_CBOR_FALSE) {
+ 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);
@@ -869,21 +880,42 @@
pPoint = EC_KEY_get0_public_key(pKey);
CHECK_CONDITION(pPoint != NULL, COSE_ERR_INVALID_PARAMETER);
- 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);
-
+ 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;
- 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.
+ 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_EC_Y, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), 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:
@@ -1078,51 +1110,65 @@
RAND_bytes(pb, (int) cb);
}
-bool ECDH_ComputeSecret(COSE * pRecipient, cn_cbor ** ppKeyMe, const cn_cbor * pKeyYou, byte ** ppbSecret, size_t * pcbSecret, CBOR_CONTEXT_COMMA cose_errback *perr)
+/*!
+*
+* @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 * pkeyMe = NULL;
- EC_KEY * pkeyYou = NULL;
+ EC_KEY * peckeyPrivate = NULL;
+ EC_KEY * peckeyPublic = NULL;
int cbGroup;
int cbsecret;
byte * pbsecret = NULL;
+ bool fRet = false;
- pkeyYou = ECKey_From(pKeyYou, &cbGroup, perr);
- if (pkeyYou == NULL) goto errorReturn;
+ peckeyPublic = ECKey_From(pKeyPublic, &cbGroup, perr);
+ if (peckeyPublic == NULL) goto errorReturn;
- if (*ppKeyMe == NULL) {
- pkeyMe = EC_KEY_new();
- EC_KEY_set_group(pkeyMe, EC_KEY_get0_group(pkeyYou));
- CHECK_CONDITION(EC_KEY_generate_key(pkeyMe) == 1, COSE_ERR_CRYPTO_FAIL);
- *ppKeyMe = EC_FromKey(pkeyMe, CBOR_CONTEXT_PARAM_COMMA perr);
- if (*ppKeyMe == 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 {
- pkeyMe = ECKey_From(*ppKeyMe, &cbGroup, perr);
- if (pkeyMe == NULL) goto errorReturn;
+ 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(pkeyYou), pkeyMe, NULL);
+ 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;
- if (pkeyMe != NULL) EC_KEY_free(pkeyMe);
- if (pkeyYou != NULL) EC_KEY_free(pkeyYou);
-
- return true;
+ fRet = true;
errorReturn:
if (pbsecret != NULL) COSE_FREE(pbsecret, context);
- if (pkeyMe != NULL) EC_KEY_free(pkeyMe);
- if (pkeyYou != NULL) EC_KEY_free(pkeyYou);
+ if (peckeyPublic != NULL) EC_KEY_free(peckeyPublic);
+ if (peckeyPrivate != NULL) EC_KEY_free(peckeyPrivate);
- return false;
-
+ return fRet;
}
#endif // USE_OPEN_SSL
diff --git a/test/context.c b/test/context.c
index 3546f04..dbdea88 100644
--- a/test/context.c
+++ b/test/context.c
@@ -1,4 +1,6 @@
#include <stdlib.h>
+#ifdef _MSC_VER
+#endif
#include <stdio.h>
#include <memory.h>
#include <assert.h>
diff --git a/test/encrypt.c b/test/encrypt.c
index 0cf8193..53d0103 100644
--- a/test/encrypt.c
+++ b/test/encrypt.c
@@ -141,6 +141,12 @@
if (!COSE_Enveloped_AddRecipient(hEncObj, hRecip, NULL)) goto returnError;
+ cn_cbor * pSenderKey = cn_cbor_mapget_string(pRecipients, "sender_key");
+ if (pSenderKey != NULL) {
+ cn_cbor * pSendKey = BuildKey(pSenderKey, false);
+ if (!COSE_Recipient_SetSenderKey(hRecip, pSendKey, 2, NULL)) goto returnError;
+ }
+
COSE_Recipient_Free(hRecip);
}
diff --git a/test/mac_test.c b/test/mac_test.c
index dc8ef1c..35014c5 100644
--- a/test/mac_test.c
+++ b/test/mac_test.c
@@ -135,6 +135,12 @@
if (!COSE_Recipient_SetKey(hRecip, pkey, NULL))goto returnError;
+ cn_cbor * pSenderKey = cn_cbor_mapget_string(pRecipients, "sender_key");
+ if (pSenderKey != NULL) {
+ cn_cbor * pSendKey = BuildKey(pSenderKey, false);
+ if (!COSE_Recipient_SetSenderKey(hRecip, pSendKey, 2, NULL)) goto returnError;
+ }
+
if (!COSE_Mac_AddRecipient(hMacObj, hRecip, NULL)) goto returnError;
COSE_Recipient_Free(hRecip);
diff --git a/test/test.c b/test/test.c
index 37bc301..823ed4d 100644
--- a/test/test.c
+++ b/test/test.c
@@ -28,7 +28,7 @@
int i;
} NameMap;
-NameMap RgAlgorithmNames[46] = {
+NameMap RgAlgorithmNames[47] = {
{"HS256", COSE_Algorithm_HMAC_256_256},
{"HS256/64", COSE_Algorithm_HMAC_256_64},
{"HS384", COSE_Algorithm_HMAC_384_384},
@@ -62,6 +62,7 @@
{"ECDH-ES", COSE_Algorithm_ECDH_ES_HKDF_256},
{"ECDH-ES-512",COSE_Algorithm_ECDH_ES_HKDF_512},
{ "ECDH-SS", COSE_Algorithm_ECDH_SS_HKDF_256 },
+{ "ECDH-SS-256", COSE_Algorithm_ECDH_SS_HKDF_256},
{ "ECDH-SS-512",COSE_Algorithm_ECDH_SS_HKDF_512 },
{ "ECDH-ES+A128KW", COSE_Algorithm_ECDH_ES_A128KW },
{ "ECDH-ES+A192KW", COSE_Algorithm_ECDH_ES_A192KW },