|
@@ -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
|