Add HKDF-AES examples
diff --git a/src/Recipient.c b/src/Recipient.c
index ef6a9fe..0c3b472 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -243,6 +243,24 @@
break;
+ case COSE_Algorithm_Direct_HKDF_AES_128:
+ 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_AES_Expand(&pcose->m_message, 128, cn->v.bytes, cn->length, pbContext, cbContext, pbKey, cbitKey / 8, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_Direct_HKDF_AES_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_AES_Expand(&pcose->m_message, 256, cn->v.bytes, cn->length, pbContext, cbContext, pbKey, cbitKey / 8, perr)) goto errorReturn;
+ break;
+
default:
FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
break;
@@ -282,6 +300,8 @@
case COSE_Algorithm_Direct:
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
+ case COSE_Algorithm_Direct_HKDF_AES_128:
+ case COSE_Algorithm_Direct_HKDF_AES_256:
// This is a NOOP
cbitKey = 0;
CHECK_CONDITION(pRecipient->m_encrypt.m_recipientFirst == NULL, COSE_ERR_INVALID_PARAMETER);
@@ -345,6 +365,8 @@
case COSE_Algorithm_Direct:
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
+ case COSE_Algorithm_Direct_HKDF_AES_128:
+ case COSE_Algorithm_Direct_HKDF_AES_256:
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);
@@ -452,6 +474,32 @@
break;
+ case COSE_Algorithm_Direct_HKDF_AES_128:
+ 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);
+
+ pb = COSE_CALLOC(cbitKeySize / 8, 1, context);
+ CHECK_CONDITION(pb != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ if (!HKDF_AES_Expand(&pRecipient->m_encrypt.m_message, 128, pK->v.bytes, pK->length, pbContext, cbContext, pb, cbitKeySize / 8, perr)) goto errorReturn;
+
+ break;
+
+ case COSE_Algorithm_Direct_HKDF_AES_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);
+
+ pb = COSE_CALLOC(cbitKeySize / 8, 1, context);
+ CHECK_CONDITION(pb != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ if (!HKDF_AES_Expand(&pRecipient->m_encrypt.m_message, 256, pK->v.bytes, pK->length, 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;
diff --git a/src/crypto.h b/src/crypto.h
index 043c4f9..d5a8f46 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -49,6 +49,8 @@
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);
+bool HKDF_AES_Expand(COSE * pcose, int cbitKey, 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 1767bae..efa2480 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -537,6 +537,62 @@
}
#endif
+bool HKDF_AES_Expand(COSE * pcose, int cbitKey, const byte * pbPRK, size_t cbPRK, const byte * pbInfo, size_t cbInfo, byte * pbOutput, size_t cbOutput, cose_errback * perr)
+{
+ const EVP_CIPHER * pcipher = NULL;
+ EVP_CIPHER_CTX ctx;
+ int cbOut;
+ byte rgbIV[16] = { 0 };
+ byte bCount = 1;
+ size_t ib;
+ byte rgbDigest[128 / 8];
+ int cbDigest = 0;
+ byte rgbOut[16];
+
+ switch (cbitKey) {
+ case 128:
+ pcipher = EVP_aes_128_cbc();
+ break;
+
+ case 256:
+ pcipher = EVP_aes_256_cbc();
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
+ CHECK_CONDITION(cbPRK == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);
+
+ // Setup and run the OpenSSL code
+
+ EVP_CIPHER_CTX_init(&ctx);
+
+ for (ib = 0; ib < cbOutput; ib += 16, bCount += 1) {
+ size_t ib2;
+
+ CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, pcipher, NULL, pbPRK, rgbIV), COSE_ERR_CRYPTO_FAIL);
+
+ CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, rgbDigest, cbDigest), COSE_ERR_CRYPTO_FAIL);
+ for (ib2 = 0; ib2 < cbInfo; ib2+=16) {
+ CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pbInfo+ib2, (int) MIN(16, cbInfo-ib2)), COSE_ERR_CRYPTO_FAIL);
+ }
+ CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, &bCount, 1), COSE_ERR_CRYPTO_FAIL);
+ if ((cbInfo + 1) % 16 != 0) {
+ CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, rgbIV, (int) 16-(cbInfo+1)%16), COSE_ERR_CRYPTO_FAIL);
+ }
+ memcpy(rgbDigest, rgbOut, cbOut);
+ cbDigest = cbOut;
+ memcpy(pbOutput + ib, rgbDigest, MIN(16, cbOutput - ib));
+ }
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return true;
+
+errorReturn:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return false;
+}
+
bool HKDF_Extract(COSE * pcose, const byte * pbKey, size_t cbKey, size_t cbitDigest, byte * rgbDigest, size_t * pcbDigest, CBOR_CONTEXT_COMMA cose_errback * perr)
{
diff --git "a/test/.\043CMakeLists.txt" "b/test/.\043CMakeLists.txt"
deleted file mode 100644
index aa6acc4..0000000
--- "a/test/.\043CMakeLists.txt"
+++ /dev/null
@@ -1 +0,0 @@
-jimsch@HEBREWS.9720:1452637464
\ No newline at end of file
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index b83ff94..bfdc058 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -53,3 +53,4 @@
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 )
+add_test (NAME hkdf-aes WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test --dir Examples/hkdf-aes-examples )