diff --git a/cyassl/error.h b/cyassl/error.h index 1c3909fe7..e46fed4e5 100644 --- a/cyassl/error.h +++ b/cyassl/error.h @@ -107,6 +107,7 @@ enum CyaSSL_ErrorCodes { SSL_NO_PEM_HEADER = -272, /* no PEM header found */ OUT_OF_ORDER_E = -273, /* out of order message */ BAD_KEA_TYPE_E = -274, /* bad KEA type found */ + SANITY_CIPHER_E = -275, /* sanity check on cipher error */ /* add strings to SetErrorString !!!!! */ /* begin negotiation parameter errors */ diff --git a/src/internal.c b/src/internal.c index b5b76e16d..e70e90ce6 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3033,10 +3033,40 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, } +/* check cipher text size for sanity */ +static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz) +{ + word32 minLength = 0; + + if (ssl->specs.cipher_type == block) { + if (encryptSz % ssl->specs.block_size) { + CYASSL_MSG("Block ciphertext not block size"); + return SANITY_CIPHER_E; + } + minLength = ssl->specs.hash_size + 1; /* pad byte */ + if (ssl->specs.block_size > minLength) + minLength = ssl->specs.block_size; + } + + if (encryptSz < minLength) { + CYASSL_MSG("Ciphertext not minimum size"); + return SANITY_CIPHER_E; + } + + return 0; +} + + /* decrypt input message in place */ static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx) { - int decryptResult = Decrypt(ssl, input, input, sz); + int decryptResult; + int sanityResult = SanityCheckCipherText(ssl, sz); + + if (sanityResult != 0) + return sanityResult; + + decryptResult = Decrypt(ssl, input, input, sz); if (decryptResult == 0) { @@ -4552,6 +4582,10 @@ void SetErrorString(int error, char* str) XSTRNCPY(str, "Bad KEA type found", max); break; + case SANITY_CIPHER_E: + XSTRNCPY(str, "Sanity check on ciphertext failed", max); + break; + default : XSTRNCPY(str, "unknown error number", max); }