blob: ac3fab5c3fa24d210899c9a80bb90e9f28a13325 [file] [log] [blame]
#include "cose.h"
#include "configure.h"
#include "cose_int.h"
#include "crypto.h"
#ifdef USE_OPEN_SSL
#include <openssl\evp.h>
#include <openssl\rand.h>
bool AES_CCM_Decrypt(COSE_Encrypt * pcose, int TSize, int LSize, const byte * pbAuthData, int cbAuthData)
{
EVP_CIPHER_CTX ctx;
int cbOut;
byte * rgbOut = NULL;
ssize_t NSize = 15 - LSize;
int outl = 0;
byte rgbIV[15] = { 0 };
const cn_cbor * pIV = NULL;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
// Setup the IV/Nonce and put it into the message
pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL);
if ((pIV == NULL) || (pIV->type!= CN_CBOR_BYTES)) {
error:
if (rgbOut != NULL) COSE_FREE(rgbOut, context);
return false;
}
if (pIV->length > NSize) goto error;
memcpy(&rgbIV[NSize - pIV->length], pIV->v.str, pIV->length);
// Setup and run the OpenSSL code
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_ccm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_L, LSize, 0);
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, NSize, 0);
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, TSize, NULL); // Say we are doing an 8 byte tag
EVP_EncryptInit(&ctx, 0, pcose->pbKey, rgbIV);
EVP_EncryptUpdate(&ctx, 0, &cbOut, 0, pcose->cbContent);
EVP_EncryptUpdate(&ctx, NULL, &outl, pbAuthData, cbAuthData);
rgbOut = (byte *)COSE_CALLOC(cbOut + TSize, 1, context);
if (rgbOut == NULL) goto error;
EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pcose->pbContent, pcose->cbContent);
EVP_EncryptFinal_ex(&ctx, &rgbOut[cbOut], &cbOut);
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, TSize, &rgbOut[pcose->cbContent]);
cn_cbor_mapput_int(pcose->m_message.m_cbor, COSE_Header_Ciphertext, cn_cbor_data_create(rgbOut, pcose->cbContent + TSize, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
return true;
}
bool AES_CCM_Encrypt(COSE_Encrypt * pcose, int TSize, int LSize, const byte * pbAuthData, int cbAuthData)
{
EVP_CIPHER_CTX ctx;
int cbOut;
byte * rgbOut = NULL;
ssize_t NSize = 15 - LSize;
int outl = 0;
byte rgbIV[15] = { 0 };
const cn_cbor * cbor_iv = NULL;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif
// Setup the IV/Nonce and put it into the message
cbor_iv = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL);
if ((cbor_iv == NULL) || (cbor_iv->type != CN_CBOR_BYTES)) {
error:
if (rgbOut != NULL) COSE_FREE(rgbOut, context);
return false;
}
if (cbor_iv->length > NSize) goto error;
memcpy(&rgbIV[NSize-cbor_iv->length], cbor_iv->v.str, cbor_iv->length);
#if 0
if (!cn_cbor_mapput_int(pcose->m_message.m_cbor, COSE_Header_IV, cn_cbor_data_create(rgbIV, NSize, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL)) {
goto error;
}
#endif
// Setup and run the OpenSSL code
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_ccm(), NULL, NULL, NULL);
TSize /= 8; // Comes in in bits not bytes.
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_L, LSize, 0);
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, NSize, 0);
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, TSize, NULL); // Say we are doing an 8 byte tag
EVP_EncryptInit(&ctx, 0, pcose->pbKey, rgbIV);
EVP_EncryptUpdate(&ctx, 0, &cbOut, 0, pcose->cbContent);
EVP_EncryptUpdate(&ctx, NULL, &outl, pbAuthData, cbAuthData);
rgbOut = (byte *)COSE_CALLOC(cbOut + TSize, 1, context);
if (rgbOut == NULL) goto error;
EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pcose->pbContent, pcose->cbContent);
EVP_EncryptFinal_ex(&ctx, &rgbOut[cbOut], &cbOut);
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, TSize, &rgbOut[pcose->cbContent]);
cn_cbor_mapput_int(pcose->m_message.m_cbor, COSE_Header_Ciphertext, cn_cbor_data_create(rgbOut, pcose->cbContent + TSize, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
return true;
}
void rand_bytes(byte * pb, size_t cb)
{
RAND_bytes(pb, cb);
}
#endif // USE_OPEN_SSL