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
This commit is contained in:
Marco Oliverio 2023-05-09 13:22:39 +00:00
parent 1a8f09d013
commit 6c8811a737

View File

@ -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