From fc845da9f0ae651f1eafc8448970a9273d3abee5 Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Wed, 23 Dec 2020 13:50:35 -0600 Subject: [PATCH] Fix issue with DoHandShakeMsgType/ShrinkInputBuffer when encryption is on (e.g. during renegotiation). This issue was brought to light by ZD 10911. When encryption is on (indicated by the return value of IsEncryptionOn), DoHandShakeMsgType will finish up by incrementing the input buffer index past the padding and MAC (if encrypt-then- mac is enabled). In ProcessReply, if there are more messages to be read, the index is decremented back before the padding and MAC. The issue arises when ShrinkInputBuffer is called in between and copies data from the dynamic input buffer to the static one. That function will get called with the index post- increment, and thus the padding and MAC won't get copied into the static buffer, which isn't what we want, since ProcessReply is going to decrement the index since it thinks the padding and MAC are still there. This commit makes it so the padding and MAC get included in the call to ShrinkInputBuffer when encryption is on. --- src/internal.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 7208feb81..5702513ce 100644 --- a/src/internal.c +++ b/src/internal.c @@ -12950,7 +12950,25 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, && ssl->error != WC_PENDING_E && ssl->error != OCSP_WANT_READ #endif ) { - ShrinkInputBuffer(ssl, NO_FORCED_FREE); + if (IsEncryptionOn(ssl, 0)) { + word32 extra = ssl->keys.padSz; + + #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) + if (ssl->options.startedETMRead) + extra += MacSize(ssl); + #endif + + if (extra > ssl->buffers.inputBuffer.idx) + return BUFFER_E; + + ssl->buffers.inputBuffer.idx -= extra; + ShrinkInputBuffer(ssl, NO_FORCED_FREE); + ssl->buffers.inputBuffer.idx += extra; + } + else { + ShrinkInputBuffer(ssl, NO_FORCED_FREE); + } + } #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)