From 6c8811a7373693813d0c31316f0419a08a2bd04f Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 9 May 2023 13:22:39 +0000 Subject: [PATCH] dtls13: fix: check plaintext record header epoch is 0 In DTLS v1.3 the normal (plaintext) record header can be used only with unprotected message (epoch == 0). Protected messages use the unified header. Check this invariant using `IsAtLeastTLSv1_3` instead of `ssl->options.tls1_3` because the latter is false before version negotiation. In DTLSv1.2 the DTLS normal header is used for all the epoch, this check doesn't interfere because: 1. the first CH's epoch must be zero in all DTLS versions 2. In case of downgrade after version negotiation `IsAtLeastTLSv1_3` is false --- src/internal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/internal.c b/src/internal.c index 411671f18..079ce16f7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10421,16 +10421,19 @@ static int GetDtlsRecordHeader(WOLFSSL* ssl, word32* inOutIdx, ENUM_LEN + VERSION_SZ); *inOutIdx += ENUM_LEN + VERSION_SZ; ato16(ssl->buffers.inputBuffer.buffer + *inOutIdx, &ssl->keys.curEpoch); + #ifdef WOLFSSL_DTLS13 /* only non protected message can use the DTLSPlaintext record header */ - if (ssl->options.tls1_3 && ssl->keys.curEpoch != 0) + if (IsAtLeastTLSv1_3(ssl->version)) { + if (ssl->keys.curEpoch != 0) return SEQUENCE_ERROR; - w64Zero(&ssl->keys.curEpoch64); - if (!w64IsZero(ssl->dtls13DecryptEpoch->epochNumber)) - Dtls13SetEpochKeys(ssl, ssl->keys.curEpoch64, DECRYPT_SIDE_ONLY); - + w64Zero(&ssl->keys.curEpoch64); + if (!w64IsZero(ssl->dtls13DecryptEpoch->epochNumber)) + Dtls13SetEpochKeys(ssl, ssl->keys.curEpoch64, DECRYPT_SIDE_ONLY); + } #endif /* WOLFSSL_DTLS13 */ + *inOutIdx += OPAQUE16_LEN; if (ssl->options.haveMcast) { #ifdef WOLFSSL_MULTICAST