diff --git a/configure.ac b/configure.ac index 617bb0f43..8a6657e86 100644 --- a/configure.ac +++ b/configure.ac @@ -7468,7 +7468,7 @@ then fi AS_IF([test "x$ENABLED_MAXSTRENGTH" = "xyes"], - [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MAX_STRENGTH"]) + [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MAX_STRENGTH -DWOLFSSL_CIPHER_TEXT_CHECK"]) AS_IF([test "x$ENABLED_MAXSTRENGTH" = "xyes" && \ test "x$ENABLED_OLD_TLS" = "xyes"], diff --git a/src/internal.c b/src/internal.c index 3ba3855b1..7aeb9b458 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15835,6 +15835,13 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, return ENCRYPT_ERROR; } + #ifdef WOLFSSL_CIPHER_TEXT_CHECK + if (ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) { + XMEMCPY(ssl->encrypt.sanityCheck, input, + min(sz, sizeof(ssl->encrypt.sanityCheck))); + } + #endif + #ifdef HAVE_FUZZER if (ssl->fuzzerCb) ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx); @@ -15882,6 +15889,18 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, case CIPHER_STATE_END: { + #ifdef WOLFSSL_CIPHER_TEXT_CHECK + if (ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null && + XMEMCMP(out, ssl->encrypt.sanityCheck, + min(sz, sizeof(ssl->encrypt.sanityCheck))) == 0) { + + WOLFSSL_MSG("Encrypt sanity check failed! Glitch?"); + return ENCRYPT_ERROR; + } + ForceZero(ssl->encrypt.sanityCheck, + sizeof(ssl->encrypt.sanityCheck)); + #endif + #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm || ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) diff --git a/src/tls13.c b/src/tls13.c index 67003b0e0..7e6b15729 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1855,6 +1855,13 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, WOLFSSL_BUFFER(aad, aadSz); #endif + #ifdef WOLFSSL_CIPHER_TEXT_CHECK + if (ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null) { + XMEMCPY(ssl->encrypt.sanityCheck, input, + min(dataSz, sizeof(ssl->encrypt.sanityCheck))); + } + #endif + #ifdef CIPHER_NONCE if (ssl->encrypt.nonce == NULL) ssl->encrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ, @@ -1980,6 +1987,18 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, WOLFSSL_BUFFER(output + dataSz, macSz); #endif + #ifdef WOLFSSL_CIPHER_TEXT_CHECK + if (ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null && + XMEMCMP(output, ssl->encrypt.sanityCheck, + min(dataSz, sizeof(ssl->encrypt.sanityCheck))) == 0) { + + WOLFSSL_MSG("EncryptTls13 sanity check failed! Glitch?"); + return ENCRYPT_ERROR; + } + ForceZero(ssl->encrypt.sanityCheck, + sizeof(ssl->encrypt.sanityCheck)); + #endif + #ifdef CIPHER_NONCE ForceZero(ssl->encrypt.nonce, AEAD_NONCE_SZ); #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2b5d40ebe..7cc28a0d4 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3255,6 +3255,13 @@ enum CipherSrc { }; #endif +#ifdef WOLFSSL_CIPHER_TEXT_CHECK + #ifndef WOLFSSL_CIPHER_CHECK_SZ + /* 64-bits to confirm encrypt operation worked */ + #define WOLFSSL_CIPHER_CHECK_SZ 8 + #endif +#endif + /* cipher for now */ typedef struct Ciphers { #ifdef BUILD_ARC4 @@ -3281,6 +3288,9 @@ typedef struct Ciphers { #endif #if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER) Hmac* hmac; +#endif +#ifdef WOLFSSL_CIPHER_TEXT_CHECK + word32 sanityCheck[WOLFSSL_CIPHER_CHECK_SZ/sizeof(word32)]; #endif byte state; byte setup; /* have we set it up flag for detection */