mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 12:14:38 +02:00
Merge pull request #2928 from julek-wolfssl/evp-aes-gcm-fix
Fix AES-GCM in EVP layer to have compatiblity with OpenSSL
This commit is contained in:
@@ -440,7 +440,7 @@ AC_ARG_ENABLE([mcast],
|
|||||||
|
|
||||||
# List of open source project defines using our openssl compatibility layer:
|
# List of open source project defines using our openssl compatibility layer:
|
||||||
# openssh (--enable-openssh) WOLFSSL_OPENSSH
|
# openssh (--enable-openssh) WOLFSSL_OPENSSH
|
||||||
# openvpn (--enable-openvpn)
|
# openvpn (--enable-openvpn) WOLFSSL_OPENVPN
|
||||||
# nginix (--enable-nginx) WOLFSSL_NGINX
|
# nginix (--enable-nginx) WOLFSSL_NGINX
|
||||||
# haproxy (--enable-haproxy) WOLFSSL_HAPROXY
|
# haproxy (--enable-haproxy) WOLFSSL_HAPROXY
|
||||||
# wpa_supplicant (--enable-wpas) WOLFSSL_WPAS
|
# wpa_supplicant (--enable-wpas) WOLFSSL_WPAS
|
||||||
@@ -3543,7 +3543,7 @@ fi
|
|||||||
|
|
||||||
if test "$ENABLED_OPENVPN" = "yes"
|
if test "$ENABLED_OPENVPN" = "yes"
|
||||||
then
|
then
|
||||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DES_ECB -DHAVE_EX_DATA -DWOLFSSL_KEY_GEN"
|
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DES_ECB -DHAVE_EX_DATA -DWOLFSSL_KEY_GEN -DWOLFSSL_OPENVPN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
@@ -30844,10 +30844,10 @@ static void test_wolfssl_EVP_aes_gcm(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
|
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
|
||||||
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag));
|
|
||||||
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz));
|
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz));
|
||||||
decryptedtxtSz = len;
|
decryptedtxtSz = len;
|
||||||
AssertIntGT(EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len), 0);
|
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag));
|
||||||
|
AssertIntEQ(1, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
|
||||||
decryptedtxtSz += len;
|
decryptedtxtSz += len;
|
||||||
AssertIntEQ(ciphertxtSz, decryptedtxtSz);
|
AssertIntEQ(ciphertxtSz, decryptedtxtSz);
|
||||||
AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));
|
AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz));
|
||||||
@@ -30857,7 +30857,8 @@ static void test_wolfssl_EVP_aes_gcm(void)
|
|||||||
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
|
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz));
|
||||||
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag));
|
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag));
|
||||||
/* fail due to wrong tag */
|
/* fail due to wrong tag */
|
||||||
AssertIntEQ(0, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz));
|
AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz));
|
||||||
|
AssertIntEQ(0, EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len));
|
||||||
AssertIntEQ(0, len);
|
AssertIntEQ(0, len);
|
||||||
}
|
}
|
||||||
printf(resultFmt, passed);
|
printf(resultFmt, passed);
|
||||||
|
@@ -417,47 +417,6 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
ret = wc_AesCbcDecrypt(&ctx->cipher.aes, out, in, inl);
|
ret = wc_AesCbcDecrypt(&ctx->cipher.aes, out, in, inl);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_AESGCM)
|
|
||||||
case AES_128_GCM_TYPE:
|
|
||||||
case AES_192_GCM_TYPE:
|
|
||||||
case AES_256_GCM_TYPE:
|
|
||||||
if (ctx->enc) {
|
|
||||||
if (out){
|
|
||||||
/* encrypt confidential data*/
|
|
||||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, in, inl,
|
|
||||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
|
||||||
NULL, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* authenticated, non-confidential data */
|
|
||||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0,
|
|
||||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
|
||||||
in, inl);
|
|
||||||
/* Reset partial authTag error for AAD*/
|
|
||||||
if (ret == AES_GCM_AUTH_E)
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (out){
|
|
||||||
/* decrypt confidential data*/
|
|
||||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out, in, inl,
|
|
||||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
|
||||||
NULL, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* authenticated, non-confidential data*/
|
|
||||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0,
|
|
||||||
ctx->iv, ctx->ivSz,
|
|
||||||
ctx->authTag, ctx->authTagSz,
|
|
||||||
in, inl);
|
|
||||||
/* Reset partial authTag error for AAD*/
|
|
||||||
if (ret == AES_GCM_AUTH_E)
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if defined(WOLFSSL_AES_COUNTER)
|
#if defined(WOLFSSL_AES_COUNTER)
|
||||||
case AES_128_CTR_TYPE:
|
case AES_128_CTR_TYPE:
|
||||||
case AES_192_CTR_TYPE:
|
case AES_192_CTR_TYPE:
|
||||||
@@ -575,10 +534,60 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
unsigned char *out, int *outl,
|
unsigned char *out, int *outl,
|
||||||
const unsigned char *in, int inl)
|
const unsigned char *in, int inl)
|
||||||
{
|
{
|
||||||
/* process blocks */
|
int ret = 0;
|
||||||
if (evpCipherBlock(ctx, out, in, inl) == 0)
|
|
||||||
return WOLFSSL_FAILURE;
|
|
||||||
*outl = inl;
|
*outl = inl;
|
||||||
|
if (ctx->enc) {
|
||||||
|
if (out) {
|
||||||
|
/* encrypt confidential data*/
|
||||||
|
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, in, inl,
|
||||||
|
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||||
|
NULL, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* authenticated, non-confidential data */
|
||||||
|
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
|
||||||
|
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0,
|
||||||
|
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||||
|
in, inl);
|
||||||
|
/* Reset partial authTag error for AAD*/
|
||||||
|
if (ret == AES_GCM_AUTH_E)
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (out) {
|
||||||
|
byte* tmp;
|
||||||
|
tmp = (byte*)XREALLOC(ctx->gcmDecryptBuffer,
|
||||||
|
ctx->gcmDecryptBufferLen + inl, NULL,
|
||||||
|
DYNAMIC_TYPE_OPENSSL);
|
||||||
|
if (tmp) {
|
||||||
|
XMEMCPY(tmp + ctx->gcmDecryptBufferLen, in, inl);
|
||||||
|
ctx->gcmDecryptBufferLen += inl;
|
||||||
|
ctx->gcmDecryptBuffer = tmp;
|
||||||
|
*outl = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* authenticated, non-confidential data*/
|
||||||
|
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0,
|
||||||
|
ctx->iv, ctx->ivSz,
|
||||||
|
ctx->authTag, ctx->authTagSz,
|
||||||
|
in, inl);
|
||||||
|
/* Reset partial authTag error for AAD*/
|
||||||
|
if (ret == AES_GCM_AUTH_E)
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
*outl = 0;
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
return WOLFSSL_SUCCESS;
|
return WOLFSSL_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -739,22 +748,39 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
|
|
||||||
WOLFSSL_ENTER("wolfSSL_EVP_CipherFinal");
|
WOLFSSL_ENTER("wolfSSL_EVP_CipherFinal");
|
||||||
|
|
||||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
|
||||||
switch (ctx->cipherType) {
|
switch (ctx->cipherType) {
|
||||||
|
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||||
case AES_128_GCM_TYPE:
|
case AES_128_GCM_TYPE:
|
||||||
case AES_192_GCM_TYPE:
|
case AES_192_GCM_TYPE:
|
||||||
case AES_256_GCM_TYPE:
|
case AES_256_GCM_TYPE:
|
||||||
|
if (!ctx->enc && ctx->gcmDecryptBuffer &&
|
||||||
|
ctx->gcmDecryptBufferLen > 0) {
|
||||||
|
/* decrypt confidential data*/
|
||||||
|
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out,
|
||||||
|
ctx->gcmDecryptBuffer, ctx->gcmDecryptBufferLen,
|
||||||
|
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||||
|
NULL, 0);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = WOLFSSL_SUCCESS;
|
||||||
|
*outl = ctx->gcmDecryptBufferLen;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = WOLFSSL_FAILURE;
|
||||||
*outl = 0;
|
*outl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFREE(ctx->gcmDecryptBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||||
|
ctx->gcmDecryptBuffer = NULL;
|
||||||
|
ctx->gcmDecryptBufferLen = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*outl = 0;
|
||||||
|
}
|
||||||
/* Clear IV, since IV reuse is not recommended for AES GCM. */
|
/* Clear IV, since IV reuse is not recommended for AES GCM. */
|
||||||
XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
|
XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
|
||||||
return WOLFSSL_SUCCESS;
|
|
||||||
default:
|
|
||||||
/* fall-through */
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
#endif /* !NO_AES && HAVE_AESGCM */
|
#endif /* !NO_AES && HAVE_AESGCM */
|
||||||
|
default:
|
||||||
if (!out)
|
if (!out)
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
|
|
||||||
@@ -795,7 +821,8 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
XMEMCPY(out, ctx->lastBlock, fl);
|
XMEMCPY(out, ctx->lastBlock, fl);
|
||||||
*outl = fl;
|
*outl = fl;
|
||||||
if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
|
if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
|
||||||
/* return error in cases where the block length is incorrect */
|
/* return error in cases where the block length is
|
||||||
|
* incorrect */
|
||||||
WOLFSSL_MSG("Final Cipher Block bad length");
|
WOLFSSL_MSG("Final Cipher Block bad length");
|
||||||
ret = WOLFSSL_FAILURE;
|
ret = WOLFSSL_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -805,10 +832,14 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
|
else if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
|
||||||
/* return error in cases where the block length is incorrect */
|
/* return error in cases where the block length is
|
||||||
|
* incorrect */
|
||||||
ret = WOLFSSL_FAILURE;
|
ret = WOLFSSL_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == WOLFSSL_SUCCESS) {
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
/* reset cipher state after final */
|
/* reset cipher state after final */
|
||||||
wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1);
|
wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1);
|
||||||
@@ -4040,6 +4071,13 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
|||||||
if (ctx) {
|
if (ctx) {
|
||||||
ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */
|
ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */
|
||||||
ctx->keyLen = 0;
|
ctx->keyLen = 0;
|
||||||
|
#ifdef HAVE_AESGCM
|
||||||
|
if (ctx->gcmDecryptBuffer) {
|
||||||
|
XFREE(ctx->gcmDecryptBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||||
|
ctx->gcmDecryptBuffer = NULL;
|
||||||
|
}
|
||||||
|
ctx->gcmDecryptBufferLen = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return WOLFSSL_SUCCESS;
|
return WOLFSSL_SUCCESS;
|
||||||
@@ -4266,7 +4304,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
|||||||
ctx->authTagSz = AES_BLOCK_SIZE;
|
ctx->authTagSz = AES_BLOCK_SIZE;
|
||||||
ctx->ivSz = GCM_NONCE_MID_SZ;
|
ctx->ivSz = GCM_NONCE_MID_SZ;
|
||||||
|
|
||||||
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
|
|
||||||
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
|
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
|
||||||
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
|
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
@@ -4291,7 +4328,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
|||||||
ctx->authTagSz = AES_BLOCK_SIZE;
|
ctx->authTagSz = AES_BLOCK_SIZE;
|
||||||
ctx->ivSz = GCM_NONCE_MID_SZ;
|
ctx->ivSz = GCM_NONCE_MID_SZ;
|
||||||
|
|
||||||
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
|
|
||||||
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
|
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
|
||||||
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
|
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
@@ -4316,7 +4352,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
|||||||
ctx->authTagSz = AES_BLOCK_SIZE;
|
ctx->authTagSz = AES_BLOCK_SIZE;
|
||||||
ctx->ivSz = GCM_NONCE_MID_SZ;
|
ctx->ivSz = GCM_NONCE_MID_SZ;
|
||||||
|
|
||||||
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
|
|
||||||
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
|
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
|
||||||
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
|
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
|
@@ -353,6 +353,10 @@ struct WOLFSSL_EVP_CIPHER_CTX {
|
|||||||
defined(HAVE_AESGCM) || defined (WOLFSSL_AES_XTS)
|
defined(HAVE_AESGCM) || defined (WOLFSSL_AES_XTS)
|
||||||
#define HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
|
#define HAVE_WOLFSSL_EVP_CIPHER_CTX_IV
|
||||||
int ivSz;
|
int ivSz;
|
||||||
|
#ifdef HAVE_AESGCM
|
||||||
|
byte* gcmDecryptBuffer;
|
||||||
|
int gcmDecryptBufferLen;
|
||||||
|
#endif
|
||||||
ALIGN16 unsigned char authTag[AES_BLOCK_SIZE];
|
ALIGN16 unsigned char authTag[AES_BLOCK_SIZE];
|
||||||
int authTagSz;
|
int authTagSz;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -31,10 +31,10 @@
|
|||||||
#define OPENSSL_VERSION_NUMBER 0x10100000L
|
#define OPENSSL_VERSION_NUMBER 0x10100000L
|
||||||
#elif defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) || \
|
#elif defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) || \
|
||||||
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
|
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
|
||||||
defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_QT)
|
defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENVPN)
|
||||||
/* version number can be increased for Lighty after compatibility for ECDH
|
/* version number can be increased for Lighty after compatibility for ECDH
|
||||||
is added */
|
is added */
|
||||||
#define OPENSSL_VERSION_NUMBER 0x1000100fL
|
#define OPENSSL_VERSION_NUMBER 0x10001040L
|
||||||
#else
|
#else
|
||||||
#define OPENSSL_VERSION_NUMBER 0x0090810fL
|
#define OPENSSL_VERSION_NUMBER 0x0090810fL
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user