Merge pull request #5942 from bandi13/evpaesccm

Evpaesccm
This commit is contained in:
John Safranek
2023-01-06 11:25:37 -08:00
committed by GitHub
4 changed files with 833 additions and 94 deletions

View File

@ -39315,7 +39315,7 @@ int wolfSSL_RAND_poll(void)
case AES_192_CBC_TYPE :
case AES_256_CBC_TYPE :
WOLFSSL_MSG("AES CBC");
XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
break;
#endif
#ifdef HAVE_AESGCM
@ -39323,9 +39323,17 @@ int wolfSSL_RAND_poll(void)
case AES_192_GCM_TYPE :
case AES_256_GCM_TYPE :
WOLFSSL_MSG("AES GCM");
XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
break;
#endif /* HAVE_AESGCM */
#ifdef HAVE_AESCCM
case AES_128_CCM_TYPE :
case AES_192_CCM_TYPE :
case AES_256_CCM_TYPE :
WOLFSSL_MSG("AES CCM");
XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
break;
#endif /* HAVE_AESCCM */
#ifdef HAVE_AES_ECB
case AES_128_ECB_TYPE :
case AES_192_ECB_TYPE :

View File

@ -45475,12 +45475,47 @@ static int test_wolfSSL_EVP_md4(void)
static int test_wolfSSL_EVP_aes_256_gcm(void)
{
return TEST_RES_CHECK(wolfSSL_EVP_aes_256_gcm() != NULL);
int res = TEST_SKIPPED;
#ifdef HAVE_AESGCM
res = TEST_RES_CHECK(wolfSSL_EVP_aes_256_gcm() != NULL);
#endif
return res;
}
static int test_wolfSSL_EVP_aes_192_gcm(void)
{
return TEST_RES_CHECK(wolfSSL_EVP_aes_192_gcm() != NULL);
int res = TEST_SKIPPED;
#ifdef HAVE_AESGCM
res = TEST_RES_CHECK(wolfSSL_EVP_aes_192_gcm() != NULL);
#endif
return res;
}
static int test_wolfSSL_EVP_aes_256_ccm(void)
{
int res = TEST_SKIPPED;
#ifdef HAVE_AESCCM
res = TEST_RES_CHECK(wolfSSL_EVP_aes_256_ccm() != NULL);
#endif
return res;
}
static int test_wolfSSL_EVP_aes_192_ccm(void)
{
int res = TEST_SKIPPED;
#ifdef HAVE_AESCCM
res = TEST_RES_CHECK(wolfSSL_EVP_aes_192_ccm() != NULL);
#endif
return res;
}
static int test_wolfSSL_EVP_aes_128_ccm(void)
{
int res = TEST_SKIPPED;
#ifdef HAVE_AESCCM
res = TEST_RES_CHECK(wolfSSL_EVP_aes_128_ccm() != NULL);
#endif
return res;
}
static int test_wolfSSL_EVP_ripemd160(void)
@ -45642,6 +45677,21 @@ static int test_wolfSSL_EVP_CIPHER_block_size(void)
}
#endif
#ifdef HAVE_AESCCM
if (res == TEST_SKIPPED || res == TEST_SUCCESS) {
#ifdef WOLFSSL_AES_128
AssertIntEQ(EVP_CIPHER_block_size(EVP_aes_128_ccm()), 1);
#endif
#ifdef WOLFSSL_AES_192
AssertIntEQ(EVP_CIPHER_block_size(EVP_aes_192_ccm()), 1);
#endif
#ifdef WOLFSSL_AES_256
AssertIntEQ(EVP_CIPHER_block_size(EVP_aes_256_ccm()), 1);
#endif
res = TEST_RES_CHECK(1);
}
#endif
#ifdef WOLFSSL_AES_COUNTER
if (res == TEST_SKIPPED || res == TEST_SUCCESS) {
#ifdef WOLFSSL_AES_128
@ -46151,7 +46201,7 @@ static int test_evp_cipher_aes_gcm(void)
/*
* The call to EVP_CipherInit below (with NULL key) should clear the
* gcmIvGenEnable flag set by EVP_CTRL_GCM_SET_IV_FIXED. As such, a
* authIvGenEnable flag set by EVP_CTRL_GCM_SET_IV_FIXED. As such, a
* subsequent EVP_CTRL_GCM_IV_GEN should fail. This matches OpenSSL
* behavior.
*/
@ -52162,6 +52212,198 @@ static int test_wolfssl_EVP_aes_gcm(void)
return res;
}
static int test_wolfssl_EVP_aes_ccm_zeroLen(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESCCM) && \
!defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
/* Zero length plain text */
byte key[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}; /* align */
byte iv[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}; /* align */
byte plaintxt[1];
int ivSz = 12;
int plaintxtSz = 0;
unsigned char tag[16];
byte ciphertxt[AES_BLOCK_SIZE * 4] = {0};
byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0};
int ciphertxtSz = 0;
int decryptedtxtSz = 0;
int len = 0;
EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();
AssertIntEQ(1, EVP_EncryptInit_ex(en, EVP_aes_256_ccm(), NULL, key, iv));
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
AssertIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt,
plaintxtSz));
AssertIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len));
ciphertxtSz += len;
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_CCM_GET_TAG, 16, tag));
AssertIntEQ(1, EVP_CIPHER_CTX_cleanup(en));
AssertIntEQ(0, ciphertxtSz);
EVP_CIPHER_CTX_init(de);
AssertIntEQ(1, EVP_DecryptInit_ex(de, EVP_aes_256_ccm(), NULL, key, iv));
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
AssertIntEQ(1, EVP_DecryptUpdate(de, NULL, &len, ciphertxt, len));
decryptedtxtSz = len;
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(de, EVP_CTRL_CCM_SET_TAG, 16, tag));
AssertIntEQ(1, EVP_DecryptFinal_ex(de, decryptedtxt, &len));
decryptedtxtSz += len;
AssertIntEQ(0, decryptedtxtSz);
EVP_CIPHER_CTX_free(en);
EVP_CIPHER_CTX_free(de);
res = TEST_RES_CHECK(1);
#endif
return res;
}
static int test_wolfssl_EVP_aes_ccm(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESCCM) && \
!defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
/* A 256 bit key, AES_128 will use the first 128 bit*/
byte *key = (byte*)"01234567890123456789012345678901";
/* A 128 bit IV */
byte *iv = (byte*)"0123456789012";
int ivSz = (int)XSTRLEN((char*)iv);
/* Message to be encrypted */
byte *plaintxt = (byte*)"for things to change you have to change";
/* Additional non-confidential data */
byte *aad = (byte*)"Don't spend major time on minor things.";
unsigned char tag[AES_BLOCK_SIZE] = {0};
int plaintxtSz = (int)XSTRLEN((char*)plaintxt);
int aadSz = (int)XSTRLEN((char*)aad);
byte ciphertxt[AES_BLOCK_SIZE * 4] = {0};
byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0};
int ciphertxtSz = 0;
int decryptedtxtSz = 0;
int len = 0;
int i = 0;
EVP_CIPHER_CTX en[2];
EVP_CIPHER_CTX de[2];
for (i = 0; i < 2; i++) {
EVP_CIPHER_CTX_init(&en[i]);
if (i == 0) {
/* Default uses 96-bits IV length */
#ifdef WOLFSSL_AES_128
AssertIntEQ(1, EVP_EncryptInit_ex(&en[i],
EVP_aes_128_ccm(), NULL, key, iv));
#elif defined(WOLFSSL_AES_192)
AssertIntEQ(1, EVP_EncryptInit_ex(&en[i],
EVP_aes_192_ccm(), NULL, key, iv));
#elif defined(WOLFSSL_AES_256)
AssertIntEQ(1, EVP_EncryptInit_ex(&en[i],
EVP_aes_256_ccm(), NULL, key, iv));
#endif
}
else {
#ifdef WOLFSSL_AES_128
AssertIntEQ(1, EVP_EncryptInit_ex(&en[i],
EVP_aes_128_ccm(), NULL, NULL, NULL));
#elif defined(WOLFSSL_AES_192)
AssertIntEQ(1, EVP_EncryptInit_ex(&en[i],
EVP_aes_192_ccm(), NULL, NULL, NULL));
#elif defined(WOLFSSL_AES_256)
AssertIntEQ(1, EVP_EncryptInit_ex(&en[i],
EVP_aes_256_ccm(), NULL, NULL, NULL));
#endif
/* non-default must to set the IV length first */
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i],
EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
AssertIntEQ(1, EVP_EncryptInit_ex(&en[i],
NULL, NULL, key, iv));
}
AssertIntEQ(1, EVP_EncryptUpdate(&en[i], NULL, &len, aad, aadSz));
AssertIntEQ(1, EVP_EncryptUpdate(&en[i],
ciphertxt, &len, plaintxt, plaintxtSz));
ciphertxtSz = len;
AssertIntEQ(1, EVP_EncryptFinal_ex(&en[i], ciphertxt, &len));
ciphertxtSz += len;
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en[i],
EVP_CTRL_CCM_GET_TAG, AES_BLOCK_SIZE, tag));
AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&en[i]), 1);
EVP_CIPHER_CTX_init(&de[i]);
if (i == 0) {
/* Default uses 96-bits IV length */
#ifdef WOLFSSL_AES_128
AssertIntEQ(1, EVP_DecryptInit_ex(&de[i],
EVP_aes_128_ccm(), NULL, key, iv));
#elif defined(WOLFSSL_AES_192)
AssertIntEQ(1, EVP_DecryptInit_ex(&de[i],
EVP_aes_192_ccm(), NULL, key, iv));
#elif defined(WOLFSSL_AES_256)
AssertIntEQ(1, EVP_DecryptInit_ex(&de[i],
EVP_aes_256_ccm(), NULL, key, iv));
#endif
}
else {
#ifdef WOLFSSL_AES_128
AssertIntEQ(1, EVP_DecryptInit_ex(&de[i],
EVP_aes_128_ccm(), NULL, NULL, NULL));
#elif defined(WOLFSSL_AES_192)
AssertIntEQ(1, EVP_DecryptInit_ex(&de[i],
EVP_aes_192_ccm(), NULL, NULL, NULL));
#elif defined(WOLFSSL_AES_256)
AssertIntEQ(1, EVP_DecryptInit_ex(&de[i],
EVP_aes_256_ccm(), NULL, NULL, NULL));
#endif
/* non-default must to set the IV length first */
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i],
EVP_CTRL_CCM_SET_IVLEN, ivSz, NULL));
AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv));
}
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
AssertIntEQ(1, EVP_DecryptUpdate(&de[i],
decryptedtxt, &len, ciphertxt, ciphertxtSz));
decryptedtxtSz = len;
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i],
EVP_CTRL_CCM_SET_TAG, AES_BLOCK_SIZE, tag));
AssertIntEQ(1, EVP_DecryptFinal_ex(&de[i],
decryptedtxt, &len));
decryptedtxtSz += len;
AssertIntEQ(ciphertxtSz, decryptedtxtSz);
AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));
/* modify tag*/
tag[AES_BLOCK_SIZE-1]+=0xBB;
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i],
EVP_CTRL_CCM_SET_TAG, AES_BLOCK_SIZE, tag));
/* fail due to wrong tag */
AssertIntEQ(1, EVP_DecryptUpdate(&de[i],
decryptedtxt, &len, ciphertxt, ciphertxtSz));
AssertIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
AssertIntEQ(0, len);
AssertIntEQ(wolfSSL_EVP_CIPHER_CTX_cleanup(&de[i]), 1);
}
res = TEST_RES_CHECK(1);
#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESCCM */
return res;
}
static int test_wolfssl_EVP_chacha20_poly1305(void)
{
int res = TEST_SKIPPED;
@ -60090,6 +60332,8 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfssl_EVP_aes_gcm_AAD_2_parts),
TEST_DECL(test_wolfssl_EVP_aes_gcm),
TEST_DECL(test_wolfssl_EVP_aes_gcm_zeroLen),
TEST_DECL(test_wolfssl_EVP_aes_ccm),
TEST_DECL(test_wolfssl_EVP_aes_ccm_zeroLen),
TEST_DECL(test_wolfssl_EVP_chacha20_poly1305),
TEST_DECL(test_wolfssl_EVP_chacha20),
TEST_DECL(test_wolfSSL_EVP_PKEY_hkdf),
@ -60148,6 +60392,9 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_EVP_md4),
TEST_DECL(test_wolfSSL_EVP_aes_256_gcm),
TEST_DECL(test_wolfSSL_EVP_aes_192_gcm),
TEST_DECL(test_wolfSSL_EVP_aes_256_ccm),
TEST_DECL(test_wolfSSL_EVP_aes_192_ccm),
TEST_DECL(test_wolfSSL_EVP_aes_128_ccm),
TEST_DECL(test_wolfSSL_EVP_ripemd160),
TEST_DECL(test_wolfSSL_EVP_get_digestbynid),
TEST_DECL(test_wolfSSL_EVP_MD_nid),

View File

@ -125,6 +125,18 @@
#endif
#endif /* HAVE_AESGCM */
#ifdef HAVE_AESCCM
#ifdef WOLFSSL_AES_128
static const char EVP_AES_128_CCM[] = "AES-128-CCM";
#endif
#ifdef WOLFSSL_AES_192
static const char EVP_AES_192_CCM[] = "AES-192-CCM";
#endif
#ifdef WOLFSSL_AES_256
static const char EVP_AES_256_CCM[] = "AES-256-CCM";
#endif
#endif /* HAVE_AESCCM */
#ifdef WOLFSSL_AES_COUNTER
#ifdef WOLFSSL_AES_128
static const char EVP_AES_128_CTR[] = "AES-128-CTR";
@ -231,6 +243,11 @@ int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c)
case AES_192_GCM_TYPE: return 24;
case AES_256_GCM_TYPE: return 32;
#endif
#if defined(HAVE_AESCCM)
case AES_128_CCM_TYPE: return 16;
case AES_192_CCM_TYPE: return 24;
case AES_256_CCM_TYPE: return 32;
#endif
#if defined(WOLFSSL_AES_COUNTER)
case AES_128_CTR_TYPE: return 16;
case AES_192_CTR_TYPE: return 24;
@ -567,12 +584,12 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,
static int wolfSSL_EVP_CipherUpdate_GCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx,
const unsigned char *in, int inl) {
if (in && inl > 0) {
byte* tmp = (byte*)XREALLOC(ctx->gcmAuthIn,
ctx->gcmAuthInSz + inl, NULL, DYNAMIC_TYPE_OPENSSL);
byte* tmp = (byte*)XREALLOC(ctx->authIn,
ctx->authInSz + inl, NULL, DYNAMIC_TYPE_OPENSSL);
if (tmp) {
ctx->gcmAuthIn = tmp;
XMEMCPY(ctx->gcmAuthIn + ctx->gcmAuthInSz, in, inl);
ctx->gcmAuthInSz += inl;
ctx->authIn = tmp;
XMEMCPY(ctx->authIn + ctx->authInSz, in, inl);
ctx->authInSz += inl;
}
else {
WOLFSSL_MSG("realloc error");
@ -595,13 +612,13 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
/* Buffer input for one-shot API */
if (inl > 0) {
byte* tmp;
tmp = (byte*)XREALLOC(ctx->gcmBuffer,
ctx->gcmBufferLen + inl, NULL,
tmp = (byte*)XREALLOC(ctx->authBuffer,
ctx->authBufferLen + inl, NULL,
DYNAMIC_TYPE_OPENSSL);
if (tmp) {
XMEMCPY(tmp + ctx->gcmBufferLen, in, inl);
ctx->gcmBufferLen += inl;
ctx->gcmBuffer = tmp;
XMEMCPY(tmp + ctx->authBufferLen, in, inl);
ctx->authBufferLen += inl;
ctx->authBuffer = tmp;
*outl = 0;
}
else {
@ -656,6 +673,63 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
}
#endif /* HAVE_AESGCM */
#if defined(HAVE_AESCCM)
static int wolfSSL_EVP_CipherUpdate_CCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx,
const unsigned char *in, int inl) {
if (in && inl > 0) {
byte* tmp = (byte*)XREALLOC(ctx->authIn,
ctx->authInSz + inl, NULL, DYNAMIC_TYPE_OPENSSL);
if (tmp) {
ctx->authIn = tmp;
XMEMCPY(ctx->authIn + ctx->authInSz, in, inl);
ctx->authInSz += inl;
}
else {
WOLFSSL_MSG("realloc error");
return MEMORY_E;
}
}
return 0;
}
static int wolfSSL_EVP_CipherUpdate_CCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
int ret = 0;
*outl = inl;
if (out) {
/* Buffer input for one-shot API */
if (inl > 0) {
byte* tmp;
tmp = (byte*)XREALLOC(ctx->authBuffer,
ctx->authBufferLen + inl, NULL,
DYNAMIC_TYPE_OPENSSL);
if (tmp) {
XMEMCPY(tmp + ctx->authBufferLen, in, inl);
ctx->authBufferLen += inl;
ctx->authBuffer = tmp;
*outl = 0;
}
else {
ret = MEMORY_E;
}
}
}
else {
ret = wolfSSL_EVP_CipherUpdate_CCM_AAD(ctx, in, inl);
}
if (ret != 0) {
*outl = 0;
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#endif /* HAVE_AESCCM */
/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl,
@ -682,9 +756,17 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
case AES_128_GCM_TYPE:
case AES_192_GCM_TYPE:
case AES_256_GCM_TYPE:
/* if out == NULL, in/inl contains the additional authenticated data * for GCM */
/* if out == NULL, in/inl contains the additional auth data */
return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl);
#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */
#if !defined(NO_AES) && defined(HAVE_AESCCM)
case AES_128_CCM_TYPE:
case AES_192_CCM_TYPE:
case AES_256_CCM_TYPE:
/* if out == NULL, in/inl contains the
* additional auth data */
return wolfSSL_EVP_CipherUpdate_CCM(ctx, out, outl, in, inl);
#endif /* !defined(NO_AES) && defined(HAVE_AESCCM) */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
case CHACHA20_POLY1305_TYPE:
if (out == NULL) {
@ -842,8 +924,9 @@ static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff)
return ctx->block_size - n;
}
#if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM)) && \
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
{
int i;
@ -860,8 +943,9 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
{
int fl;
int ret = WOLFSSL_SUCCESS;
#if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM)) && \
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
byte tmp = 0;
#endif
@ -876,36 +960,36 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
case AES_192_GCM_TYPE:
case AES_256_GCM_TYPE:
#ifndef WOLFSSL_AESGCM_STREAM
if ((ctx->gcmBuffer && ctx->gcmBufferLen > 0)
|| (ctx->gcmBufferLen == 0)) {
if ((ctx->authBuffer && ctx->authBufferLen > 0)
|| (ctx->authBufferLen == 0)) {
if (ctx->enc)
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out,
ctx->gcmBuffer, ctx->gcmBufferLen,
ctx->authBuffer, ctx->authBufferLen,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
ctx->gcmAuthIn, ctx->gcmAuthInSz);
ctx->authIn, ctx->authInSz);
else
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out,
ctx->gcmBuffer, ctx->gcmBufferLen,
ctx->authBuffer, ctx->authBufferLen,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
ctx->gcmAuthIn, ctx->gcmAuthInSz);
ctx->authIn, ctx->authInSz);
if (ret == 0) {
ret = WOLFSSL_SUCCESS;
*outl = ctx->gcmBufferLen;
*outl = ctx->authBufferLen;
}
else {
ret = WOLFSSL_FAILURE;
*outl = 0;
}
XFREE(ctx->gcmBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmBuffer = NULL;
ctx->gcmBufferLen = 0;
XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->authBuffer = NULL;
ctx->authBufferLen = 0;
if (ctx->gcmIncIv) {
if (ctx->authIncIv) {
IncCtr((byte*)ctx->cipher.aes.reg,
ctx->cipher.aes.nonceSz);
ctx->gcmIncIv = 0;
ctx->authIncIv = 0;
}
}
else {
@ -921,7 +1005,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
else {
ret = wc_AesGcmDecryptFinal(&ctx->cipher.aes, ctx->authTag,
ctx->authTagSz);
if (ctx->gcmIncIv) {
if (ctx->authIncIv) {
IncCtr((byte*)ctx->cipher.aes.reg, ctx->cipher.aes.nonceSz);
}
}
@ -942,8 +1026,8 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
}
#endif /* WOLFSSL_AESGCM_STREAM */
if (ret == WOLFSSL_SUCCESS) {
if (ctx->gcmIncIv) {
ctx->gcmIncIv = 0;
if (ctx->authIncIv) {
ctx->authIncIv = 0;
}
else {
/* Clear IV, since IV reuse is not recommended for AES GCM. */
@ -956,6 +1040,62 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
break;
#endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
* HAVE_FIPS_VERSION >= 2 */
#if defined(HAVE_AESCCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
case AES_128_CCM_TYPE:
case AES_192_CCM_TYPE:
case AES_256_CCM_TYPE:
if ((ctx->authBuffer && ctx->authBufferLen > 0)
|| (ctx->authBufferLen == 0)) {
if (ctx->enc)
ret = wc_AesCcmEncrypt(&ctx->cipher.aes, out,
ctx->authBuffer, ctx->authBufferLen,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
ctx->authIn, ctx->authInSz);
else
ret = wc_AesCcmDecrypt(&ctx->cipher.aes, out,
ctx->authBuffer, ctx->authBufferLen,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
ctx->authIn, ctx->authInSz);
if (ret == 0) {
ret = WOLFSSL_SUCCESS;
*outl = ctx->authBufferLen;
}
else {
ret = WOLFSSL_FAILURE;
*outl = 0;
}
XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->authBuffer = NULL;
ctx->authBufferLen = 0;
if (ctx->authIncIv) {
IncCtr((byte*)ctx->cipher.aes.reg,
ctx->cipher.aes.nonceSz);
ctx->authIncIv = 0;
}
}
else {
*outl = 0;
}
if (ret == WOLFSSL_SUCCESS) {
if (ctx->authIncIv) {
ctx->authIncIv = 0;
}
else {
/* Clear IV, since IV reuse is not recommended
* for AES CCM. */
XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
}
if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) {
ret = WOLFSSL_FAILURE;
}
}
break;
#endif /* HAVE_AESCCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
* HAVE_FIPS_VERSION >= 2 */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
case CHACHA20_POLY1305_TYPE:
if (wc_ChaCha20Poly1305_Final(&ctx->cipher.chachaPoly,
@ -1029,29 +1169,49 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
}
if (ret == WOLFSSL_SUCCESS) {
#if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM)) && \
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
/*
* This flag needs to retain its value between wolfSSL_EVP_CipherFinal
* calls. wolfSSL_EVP_CipherInit will clear it, so we save and restore
* it here.
*/
if (ctx->cipherType == AES_128_GCM_TYPE ||
if (FALSE
#ifdef HAVE_AESGCM
|| ctx->cipherType == AES_128_GCM_TYPE ||
ctx->cipherType == AES_192_GCM_TYPE ||
ctx->cipherType == AES_256_GCM_TYPE) {
tmp = ctx->gcmIvGenEnable;
ctx->cipherType == AES_256_GCM_TYPE
#endif
#ifdef HAVE_AESCCM
|| ctx->cipherType == AES_128_CCM_TYPE ||
ctx->cipherType == AES_192_CCM_TYPE ||
ctx->cipherType == AES_256_CCM_TYPE
#endif
) {
tmp = ctx->authIvGenEnable;
}
#endif
/* reset cipher state after final */
ret = wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1);
#if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
if (ctx->cipherType == AES_128_GCM_TYPE ||
#if (defined(HAVE_AESGCM) || defined(HAVE_AESCCM)) && \
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
if (FALSE
#ifdef HAVE_AESGCM
|| ctx->cipherType == AES_128_GCM_TYPE ||
ctx->cipherType == AES_192_GCM_TYPE ||
ctx->cipherType == AES_256_GCM_TYPE) {
ctx->gcmIvGenEnable = tmp;
ctx->cipherType == AES_256_GCM_TYPE
#endif
#ifdef HAVE_AESCCM
|| ctx->cipherType == AES_128_CCM_TYPE ||
ctx->cipherType == AES_192_CCM_TYPE ||
ctx->cipherType == AES_256_CCM_TYPE
#endif
) {
ctx->authIvGenEnable = tmp;
}
#endif
}
@ -1125,6 +1285,11 @@ int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx)
case AES_192_GCM_TYPE:
case AES_256_GCM_TYPE:
#endif
#if defined(HAVE_AESCCM)
case AES_128_CCM_TYPE:
case AES_192_CCM_TYPE:
case AES_256_CCM_TYPE:
#endif
#if defined(WOLFSSL_AES_COUNTER)
case AES_128_CTR_TYPE:
case AES_192_CTR_TYPE:
@ -1212,6 +1377,20 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher)
return AES_256_GCM_TYPE;
#endif
#endif /* HAVE_AESGCM */
#if defined(HAVE_AESCCM)
#ifdef WOLFSSL_AES_128
else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_CCM))
return AES_128_CCM_TYPE;
#endif
#ifdef WOLFSSL_AES_192
else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_192_CCM))
return AES_192_CCM_TYPE;
#endif
#ifdef WOLFSSL_AES_256
else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_256_CCM))
return AES_256_CCM_TYPE;
#endif
#endif /* HAVE_AESCCM */
#if defined(WOLFSSL_AES_COUNTER)
#ifdef WOLFSSL_AES_128
else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_CTR))
@ -1339,6 +1518,12 @@ int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher)
case AES_256_GCM_TYPE:
return 1;
#endif
#if defined(HAVE_AESCCM)
case AES_128_CCM_TYPE:
case AES_192_CCM_TYPE:
case AES_256_CCM_TYPE:
return 1;
#endif
#if defined(WOLFSSL_AES_COUNTER)
case AES_128_CTR_TYPE:
case AES_192_CTR_TYPE:
@ -1420,6 +1605,13 @@ unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
return WOLFSSL_EVP_CIPH_GCM_MODE |
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
#endif
#if defined(HAVE_AESCCM)
case AES_128_CCM_TYPE:
case AES_192_CCM_TYPE:
case AES_256_CCM_TYPE:
return WOLFSSL_EVP_CIPH_CCM_MODE |
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
#endif
#if defined(WOLFSSL_AES_COUNTER)
case AES_128_CTR_TYPE:
case AES_192_CTR_TYPE:
@ -4220,6 +4412,18 @@ static const struct cipher{
#endif
#endif
#ifdef HAVE_AESCCM
#ifdef WOLFSSL_AES_128
{AES_128_CCM_TYPE, EVP_AES_128_CCM, NID_aes_128_ccm},
#endif
#ifdef WOLFSSL_AES_192
{AES_192_CCM_TYPE, EVP_AES_192_CCM, NID_aes_192_ccm},
#endif
#ifdef WOLFSSL_AES_256
{AES_256_CCM_TYPE, EVP_AES_256_CCM, NID_aes_256_ccm},
#endif
#endif
#ifdef WOLFSSL_AES_COUNTER
#ifdef WOLFSSL_AES_128
{AES_128_CTR_TYPE, EVP_AES_128_CTR, NID_aes_128_ctr},
@ -4358,6 +4562,20 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name)
{EVP_AES_256_GCM, "id-aes256-GCM"},
#endif
#endif
#ifdef HAVE_AESCCM
#ifdef WOLFSSL_AES_128
{EVP_AES_128_CCM, "aes-128-ccm"},
{EVP_AES_128_CCM, "id-aes128-CCM"},
#endif
#ifdef WOLFSSL_AES_192
{EVP_AES_192_CCM, "aes-192-ccm"},
{EVP_AES_192_CCM, "id-aes192-CCM"},
#endif
#ifdef WOLFSSL_AES_256
{EVP_AES_256_CCM, "aes-256-ccm"},
{EVP_AES_256_CCM, "id-aes256-CCM"},
#endif
#endif
#endif
#ifndef NO_RC4
{EVP_ARC4, "RC4"},
@ -4464,6 +4682,20 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id)
return wolfSSL_EVP_aes_256_gcm();
#endif
#endif
#ifdef HAVE_AESCCM
#ifdef WOLFSSL_AES_128
case NID_aes_128_ccm:
return wolfSSL_EVP_aes_128_ccm();
#endif
#ifdef WOLFSSL_AES_192
case NID_aes_192_ccm:
return wolfSSL_EVP_aes_192_ccm();
#endif
#ifdef WOLFSSL_AES_256
case NID_aes_256_ccm:
return wolfSSL_EVP_aes_256_ccm();
#endif
#endif
#endif
#ifndef NO_DES3
@ -5295,6 +5527,32 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
#endif /* WOLFSSL_AES_256 */
#endif /* HAVE_AESGCM */
#ifdef HAVE_AESCCM
#ifdef WOLFSSL_AES_128
const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ccm(void)
{
WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ccm");
return EVP_AES_128_CCM;
}
#endif /* WOLFSSL_CCM_128 */
#ifdef WOLFSSL_AES_192
const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ccm(void)
{
WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ccm");
return EVP_AES_192_CCM;
}
#endif /* WOLFSSL_AES_192 */
#ifdef WOLFSSL_AES_256
const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ccm(void)
{
WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ccm");
return EVP_AES_256_CCM;
}
#endif /* WOLFSSL_AES_256 */
#endif /* HAVE_AESCCM */
#ifdef WOLFSSL_AES_COUNTER
#ifdef WOLFSSL_AES_128
const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void)
@ -5549,7 +5807,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
case EVP_CTRL_SET_KEY_LENGTH:
ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg);
break;
#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
case EVP_CTRL_AEAD_SET_IVLEN:
if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
break;
@ -5568,6 +5827,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg);
break;
#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
case EVP_CTRL_AEAD_SET_IV_FIXED:
if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
break;
@ -5613,11 +5873,12 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
* command be issued before a EVP_CTRL_GCM_IV_GEN command.
* This flag is used to enforce that.
*/
ctx->gcmIvGenEnable = 1;
ctx->authIvGenEnable = 1;
}
#endif
#endif /* !WC_NO_RNG */
break;
#endif /* HAVE_AESGCM || (HAVE_CHACHA && HAVE_POLY1305) */
#if defined(HAVE_AESGCM) && !defined(_WIN32) && !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(2,0))
/*
@ -5629,7 +5890,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
case EVP_CTRL_GCM_IV_GEN:
if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0)
break;
if (!ctx->gcmIvGenEnable) {
if (!ctx->authIvGenEnable) {
WOLFSSL_MSG("Must use EVP_CTRL_AEAD_SET_IV_FIXED before "
"EVP_CTRL_GCM_IV_GEN");
break;
@ -5657,7 +5918,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
* The gcmIncIV flag indicates that the IV should be incremented
* after the next cipher operation.
*/
ctx->gcmIncIv = 1;
ctx->authIncIv = 1;
ret = WOLFSSL_SUCCESS;
break;
#endif /* HAVE_AESGCM && !_WIN32 && !HAVE_SELFTEST && (!HAVE_FIPS ||
@ -5710,7 +5971,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
ret = WOLFSSL_SUCCESS;
}
break;
#endif /* HAVE_AESGCM || (HAVE_CHACHA && HAVE_POLY1305) */
#endif /* HAVE_AESGCM || HAVE_AESCCM || (HAVE_CHACHA && HAVE_POLY1305) */
default:
WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled");
break;
@ -5732,6 +5993,13 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
wc_AesFree(&ctx->cipher.aes);
}
#endif /* HAVE_AESGCM && WOLFSSL_AESGCM_STREAM */
#if defined(HAVE_AESCCM)
if ((ctx->cipherType == AES_128_CCM_TYPE) ||
(ctx->cipherType == AES_192_CCM_TYPE) ||
(ctx->cipherType == AES_256_CCM_TYPE)) {
wc_AesFree(&ctx->cipher.aes);
}
#endif /* HAVE_AESCCM */
#endif /* not FIPS or FIPS v2+ */
ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
@ -5742,19 +6010,19 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
}
#endif
ctx->keyLen = 0;
#ifdef HAVE_AESGCM
if (ctx->gcmBuffer) {
XFREE(ctx->gcmBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmBuffer = NULL;
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
if (ctx->authBuffer) {
XFREE(ctx->authBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->authBuffer = NULL;
}
ctx->gcmBufferLen = 0;
if (ctx->gcmAuthIn) {
XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmAuthIn = NULL;
ctx->authBufferLen = 0;
if (ctx->authIn) {
XFREE(ctx->authIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->authIn = NULL;
}
ctx->gcmAuthInSz = 0;
ctx->gcmIvGenEnable = 0;
ctx->gcmIncIv = 0;
ctx->authInSz = 0;
ctx->authIvGenEnable = 0;
ctx->authIncIv = 0;
#endif
}
@ -5873,11 +6141,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
{
int ret = WOLFSSL_SUCCESS;
if (ctx->gcmAuthIn) {
XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmAuthIn = NULL;
if (ctx->authIn) {
XFREE(ctx->authIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->authIn = NULL;
}
ctx->gcmAuthInSz = 0;
ctx->authInSz = 0;
ctx->block_size = AES_BLOCK_SIZE;
ctx->authTagSz = AES_BLOCK_SIZE;
@ -5949,7 +6217,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
* If a key is provided, the flag retains its value.
*/
if (ret == WOLFSSL_SUCCESS && key == NULL) {
ctx->gcmIvGenEnable = 0;
ctx->authIvGenEnable = 0;
}
return ret;
@ -5969,19 +6237,19 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
if (ctx->enc) {
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src,
len, ctx->iv, ctx->ivSz, ctx->authTag,
ctx->authTagSz, ctx->gcmAuthIn,
ctx->gcmAuthInSz);
ctx->authTagSz, ctx->authIn,
ctx->authInSz);
}
else {
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src,
len, ctx->iv, ctx->ivSz, ctx->authTag,
ctx->authTagSz, ctx->gcmAuthIn,
ctx->gcmAuthInSz);
ctx->authTagSz, ctx->authIn,
ctx->authInSz);
}
if (ctx->gcmIncIv) {
if (ctx->authIncIv) {
IncCtr((byte*)ctx->cipher.aes.reg,
ctx->cipher.aes.nonceSz);
ctx->gcmIncIv = 0;
ctx->authIncIv = 0;
}
}
#else
@ -6030,7 +6298,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
/* Calculate authentication tag and compare. */
ret = wc_AesGcmDecryptFinal(&ctx->cipher.aes,
ctx->authTag, ctx->authTagSz);
if (ctx->gcmIncIv) {
if (ctx->authIncIv) {
IncCtr((byte*)ctx->cipher.aes.reg,
ctx->cipher.aes.nonceSz);
}
@ -6042,7 +6310,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
WOLFSSL_MSG("wc_AesGcmInit failed");
return WOLFSSL_FATAL_ERROR;
}
ctx->gcmIncIv = 0;
ctx->authIncIv = 0;
}
#endif /* WOLFSSL_AESGCM_STREAM */
if (src == NULL) {
@ -6050,10 +6318,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
* Clear any leftover AAD on final (final is when src is
* NULL).
*/
if (ctx->gcmAuthIn != NULL) {
XMEMSET(ctx->gcmAuthIn, 0, ctx->gcmAuthInSz);
if (ctx->authIn != NULL) {
XMEMSET(ctx->authIn, 0, ctx->authInSz);
}
ctx->gcmAuthInSz = 0;
ctx->authInSz = 0;
}
if (ret == 0) {
ret = len;
@ -6065,6 +6333,128 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
* HAVE_FIPS_VERSION >= 2 */
/* return WOLFSSL_SUCCESS on ok, 0 on failure to match API compatibility */
#if defined(HAVE_AESCCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
static int EvpCipherInitAesCCM(WOLFSSL_EVP_CIPHER_CTX* ctx,
const WOLFSSL_EVP_CIPHER* type,
const byte* key, const byte* iv, int enc)
{
int ret = WOLFSSL_SUCCESS;
if (ctx->authIn) {
XFREE(ctx->authIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->authIn = NULL;
}
ctx->authInSz = 0;
ctx->block_size = AES_BLOCK_SIZE;
ctx->authTagSz = AES_BLOCK_SIZE;
if (ctx->ivSz == 0) {
ctx->ivSz = GCM_NONCE_MID_SZ;
}
ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
ctx->flags |= WOLFSSL_EVP_CIPH_CCM_MODE |
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
if (enc == 0 || enc == 1) {
ctx->enc = enc ? 1 : 0;
}
#ifdef WOLFSSL_AES_128
if (ctx->cipherType == AES_128_CCM_TYPE ||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_CCM))) {
WOLFSSL_MSG("EVP_AES_128_CCM");
ctx->cipherType = AES_128_CCM_TYPE;
ctx->keyLen = AES_128_KEY_SIZE;
}
#endif
#ifdef WOLFSSL_AES_192
if (ctx->cipherType == AES_192_CCM_TYPE ||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_CCM))) {
WOLFSSL_MSG("EVP_AES_192_CCM");
ctx->cipherType = AES_192_CCM_TYPE;
ctx->keyLen = AES_192_KEY_SIZE;
}
#endif
#ifdef WOLFSSL_AES_256
if (ctx->cipherType == AES_256_CCM_TYPE ||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CCM))) {
WOLFSSL_MSG("EVP_AES_256_CCM");
ctx->cipherType = AES_256_CCM_TYPE;
ctx->keyLen = AES_256_KEY_SIZE;
}
#endif
if (ret == WOLFSSL_SUCCESS && key &&
wc_AesCcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
WOLFSSL_MSG("wc_AesCcmSetKey() failed");
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && iv &&
wc_AesCcmSetNonce(&ctx->cipher.aes, iv, ctx->ivSz)) {
WOLFSSL_MSG("wc_AesCcmSetNonce() failed");
ret = WOLFSSL_FAILURE;
}
/*
* OpenSSL clears this flag, which permits subsequent use of
* EVP_CTRL_CCM_IV_GEN, when EVP_CipherInit is called with no key.
* If a key is provided, the flag retains its value.
*/
if (ret == WOLFSSL_SUCCESS && key == NULL) {
ctx->authIvGenEnable = 0;
}
return ret;
}
static int EvpCipherAesCCM(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst,
byte* src, word32 len)
{
int ret = WOLFSSL_FAILURE;
/* No destination means only AAD. */
if (src != NULL && dst == NULL) {
ret = wolfSSL_EVP_CipherUpdate_CCM_AAD(ctx, src, len);
}
else if (src != NULL && dst != NULL) {
if (ctx->enc) {
ret = wc_AesCcmEncrypt(&ctx->cipher.aes, dst, src,
len, ctx->iv, ctx->ivSz, ctx->authTag,
ctx->authTagSz, ctx->authIn,
ctx->authInSz);
}
else {
ret = wc_AesCcmDecrypt(&ctx->cipher.aes, dst, src,
len, ctx->iv, ctx->ivSz, ctx->authTag,
ctx->authTagSz, ctx->authIn,
ctx->authInSz);
}
if (ctx->authIncIv) {
IncCtr((byte*)ctx->cipher.aes.reg,
ctx->cipher.aes.nonceSz);
ctx->authIncIv = 0;
}
}
if (src == NULL) {
/*
* Clear any leftover AAD on final (final is when src is
* NULL).
*/
if (ctx->authIn != NULL) {
XMEMSET(ctx->authIn, 0, ctx->authInSz);
}
ctx->authInSz = 0;
}
if (ret == 0) {
ret = len;
}
return ret;
}
#endif /* HAVE_AESCCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
* HAVE_FIPS_VERSION >= 2 */
/* return WOLFSSL_SUCCESS on ok, 0 on failure to match API compatibility */
int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
const WOLFSSL_EVP_CIPHER* type, const byte* key,
const byte* iv, int enc)
@ -6183,9 +6573,9 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
#if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
if (
if (FALSE
#ifdef WOLFSSL_AES_128
ctx->cipherType == AES_128_GCM_TYPE ||
|| ctx->cipherType == AES_128_GCM_TYPE ||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_GCM))
#endif
#ifdef WOLFSSL_AES_192
@ -6204,6 +6594,30 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
}
#endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
* HAVE_FIPS_VERSION >= 2 */
#if defined(HAVE_AESCCM) && \
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
if (FALSE
#ifdef WOLFSSL_AES_128
|| ctx->cipherType == AES_128_CCM_TYPE ||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_CCM))
#endif
#ifdef WOLFSSL_AES_192
|| ctx->cipherType == AES_192_CCM_TYPE ||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_192_CCM))
#endif
#ifdef WOLFSSL_AES_256
|| ctx->cipherType == AES_256_CCM_TYPE ||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_256_CCM))
#endif
) {
if (EvpCipherInitAesCCM(ctx, type, key, iv, enc)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
}
#endif /* HAVE_AESCCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
* HAVE_FIPS_VERSION >= 2 */
#ifdef WOLFSSL_AES_COUNTER
#ifdef WOLFSSL_AES_128
if (ctx->cipherType == AES_128_CTR_TYPE ||
@ -6935,6 +7349,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
case AES_256_GCM_TYPE :
return NID_aes_256_gcm;
#endif
#ifdef HAVE_AESCCM
case AES_128_CCM_TYPE :
return NID_aes_128_ccm;
case AES_192_CCM_TYPE :
return NID_aes_192_ccm;
case AES_256_CCM_TYPE :
return NID_aes_256_ccm;
#endif
#ifdef HAVE_AES_ECB
case AES_128_ECB_TYPE :
return NID_aes_128_ecb;
@ -7027,7 +7449,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
}
#endif
#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
/* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE */
int wolfSSL_EVP_CIPHER_CTX_set_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* iv,
int ivLen)
@ -7085,9 +7508,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
WOLFSSL_ENTER("wolfSSL_EVP_Cipher");
if (ctx == NULL || ((src == NULL || dst == NULL) &&
(ctx->cipherType != AES_128_GCM_TYPE &&
(TRUE
#ifdef HAVE_AESGCM
&& ctx->cipherType != AES_128_GCM_TYPE &&
ctx->cipherType != AES_192_GCM_TYPE &&
ctx->cipherType != AES_256_GCM_TYPE))) {
ctx->cipherType != AES_256_GCM_TYPE
#endif
#ifdef HAVE_AESCCM
&& ctx->cipherType != AES_128_CCM_TYPE &&
ctx->cipherType != AES_192_CCM_TYPE &&
ctx->cipherType != AES_256_CCM_TYPE
#endif
))) {
WOLFSSL_MSG("Bad argument.");
return WOLFSSL_FATAL_ERROR;
}
@ -7190,6 +7622,16 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
break;
#endif /* HAVE_AESGCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
* HAVE_FIPS_VERSION >= 2 */
#if defined(HAVE_AESCCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
|| FIPS_VERSION_GE(2,0))
case AES_128_CCM_TYPE :
case AES_192_CCM_TYPE :
case AES_256_CCM_TYPE :
WOLFSSL_MSG("AES CCM");
ret = EvpCipherAesCCM(ctx, dst, src, len);
break;
#endif /* HAVE_AESCCM && ((!HAVE_FIPS && !HAVE_SELFTEST) ||
* HAVE_FIPS_VERSION >= 2 */
#ifdef HAVE_AES_ECB
case AES_128_ECB_TYPE :
case AES_192_ECB_TYPE :
@ -8593,6 +9035,16 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
}
return GCM_NONCE_MID_SZ;
#endif
#ifdef HAVE_AESCCM
case AES_128_CCM_TYPE :
case AES_192_CCM_TYPE :
case AES_256_CCM_TYPE :
WOLFSSL_MSG("AES CCM");
if (ctx->ivSz != 0) {
return ctx->ivSz;
}
return CCM_NONCE_MIN_SZ;
#endif
#endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION >= 2 */
#ifdef WOLFSSL_AES_COUNTER
case AES_128_CTR_TYPE :
@ -8705,6 +9157,20 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
return GCM_NONCE_MID_SZ;
#endif
#endif /* HAVE_AESGCM */
#ifdef HAVE_AESCCM
#ifdef WOLFSSL_AES_128
if (XSTRCMP(name, EVP_AES_128_CCM) == 0)
return CCM_NONCE_MIN_SZ;
#endif
#ifdef WOLFSSL_AES_192
if (XSTRCMP(name, EVP_AES_192_CCM) == 0)
return CCM_NONCE_MIN_SZ;
#endif
#ifdef WOLFSSL_AES_256
if (XSTRCMP(name, EVP_AES_256_CCM) == 0)
return CCM_NONCE_MIN_SZ;
#endif
#endif /* HAVE_AESCCM */
#endif /* (HAVE_FIPS && !HAVE_SELFTEST) || HAVE_FIPS_VERSION >= 2 */
#ifdef WOLFSSL_AES_COUNTER
#ifdef WOLFSSL_AES_128

View File

@ -126,6 +126,11 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void);
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_gcm(void);
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_gcm(void);
#endif
#if !defined(NO_AES) && defined(HAVE_AESCCM)
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ccm(void);
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ccm(void);
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ccm(void);
#endif
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void);
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void);
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void);
@ -228,6 +233,7 @@ typedef union {
#define NID_aes_192_cbc 423
#define NID_aes_256_cbc 427
#define NID_aes_128_ccm 896
#define NID_aes_192_ccm 899
#define NID_aes_256_ccm 902
#define NID_aes_128_gcm 895
#define NID_aes_192_gcm 898
@ -395,7 +401,10 @@ enum {
AES_128_XTS_TYPE = 36,
AES_256_XTS_TYPE = 37,
CHACHA20_POLY1305_TYPE = 38,
CHACHA20_TYPE = 39
CHACHA20_TYPE = 39,
AES_128_CCM_TYPE = 40,
AES_192_CCM_TYPE = 41,
AES_256_CCM_TYPE = 42
};
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
@ -423,29 +432,30 @@ struct WOLFSSL_EVP_CIPHER_CTX {
int lastUsed;
#if !defined(NO_AES) || !defined(NO_DES3) || defined(HAVE_AESGCM) || \
defined (WOLFSSL_AES_XTS) || (defined(HAVE_CHACHA) || \
defined(HAVE_POLY1305))
defined(HAVE_POLY1305) || defined(HAVE_AESCCM))
#define HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
int ivSz;
#ifdef HAVE_AESGCM
byte* gcmBuffer;
int gcmBufferLen;
byte* gcmAuthIn;
int gcmAuthInSz;
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
byte* authBuffer;
int authBufferLen;
byte* authIn;
int authInSz;
#endif
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
byte* key; /* used in partial Init()s */
#endif
#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
#ifdef HAVE_AESGCM
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) || \
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
ALIGN16 unsigned char authTag[AES_BLOCK_SIZE];
#else
ALIGN16 unsigned char authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];
#endif
int authTagSz;
#endif
#ifdef HAVE_AESGCM
byte gcmIvGenEnable:1;
byte gcmIncIv:1;
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
byte authIvGenEnable:1;
byte authIncIv:1;
#endif
#endif
};
@ -896,6 +906,9 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
#define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm
#define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm
#define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm
#define EVP_aes_128_ccm wolfSSL_EVP_aes_128_ccm
#define EVP_aes_192_ccm wolfSSL_EVP_aes_192_ccm
#define EVP_aes_256_ccm wolfSSL_EVP_aes_256_ccm
#define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb
#define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb
#define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb
@ -1103,6 +1116,11 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
#define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG
#define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG
#define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED
#define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN
#define EVP_CTRL_CCM_GET_TAG EVP_CTRL_AEAD_GET_TAG
#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_AEAD_SET_TAG
#define EVP_CTRL_CCM_SET_L 0x14
#define EVP_CTRL_CCM_SET_MSGLEN 0x15
#define EVP_PKEY_print_public wolfSSL_EVP_PKEY_print_public
#define EVP_PKEY_print_private(arg1, arg2, arg3, arg4)