F-5606: enforce DTLS 1.3 KeyUpdate 2^48-1 sending epoch ceiling

RFC 9147 Section 4.2.1 limits the DTLS 1.3 epoch to 2^48-1.
SendTls13KeyUpdate now refuses to send a KeyUpdate when the sending
epoch is already at the maximum, and Dtls13KeyUpdateAckReceived rejects
an epoch that would exceed the limit after incrementing (previously only
a full 64-bit wrap to zero was checked).
This commit is contained in:
Juliusz Sosinowicz
2026-06-01 18:31:02 +02:00
parent 4c0c093fe9
commit 754f5cfe41
3 changed files with 38 additions and 4 deletions
+12 -2
View File
@@ -2720,17 +2720,27 @@ static int Dtls13RtxIsTrackedByRn(const Dtls13RtxRecord* r, w64wrapper epoch,
static int Dtls13KeyUpdateAckReceived(WOLFSSL* ssl)
{
int ret;
/* Validate on a local copy so ssl->dtls13Epoch is left untouched when a
* check fails. */
w64wrapper newEpoch = ssl->dtls13Epoch;
ret = DeriveTls13Keys(ssl, update_traffic_key, ENCRYPT_SIDE_ONLY, 1);
if (ret != 0)
return ret;
w64Increment(&ssl->dtls13Epoch);
w64Increment(&newEpoch);
/* Epoch wrapped up */
if (w64IsZero(ssl->dtls13Epoch))
if (w64IsZero(newEpoch))
return BAD_STATE_E;
/* RFC 9147 Section 4.2.1: the epoch must not exceed 2^48-1. */
if (w64GT(newEpoch,
w64From32(DTLS13_EPOCH_MAX_HI32, DTLS13_EPOCH_MAX_LO32)))
return BAD_STATE_E;
ssl->dtls13Epoch = newEpoch;
return Dtls13SetEpochKeys(ssl, ssl->dtls13Epoch, ENCRYPT_SIDE_ONLY);
}
+21 -2
View File
@@ -12172,8 +12172,16 @@ int SendTls13KeyUpdate(WOLFSSL* ssl)
WOLFSSL_ENTER("SendTls13KeyUpdate");
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls)
if (ssl->options.dtls) {
/* RFC 9147 Section 4.2.1: do not send a KeyUpdate that would advance
* the sending epoch beyond 2^48-1. */
if (w64GTE(ssl->dtls13Epoch,
w64From32(DTLS13_EPOCH_MAX_HI32, DTLS13_EPOCH_MAX_LO32))) {
WOLFSSL_MSG("DTLS 1.3 sending epoch at maximum; refusing KeyUpdate");
return BAD_STATE_E;
}
i = Dtls13GetRlHeaderLength(ssl, 1) + DTLS_HANDSHAKE_HEADER_SZ;
}
#endif /* WOLFSSL_DTLS13 */
outputSz = OPAQUE8_LEN + MAX_MSG_EXTRA;
@@ -12307,7 +12315,18 @@ static int DoTls13KeyUpdate(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
w64Increment(&ssl->dtls13PeerEpoch);
w64wrapper newEpoch = ssl->dtls13PeerEpoch;
w64Increment(&newEpoch);
/* RFC 9147 Section 4.2.1: the epoch must not exceed 2^48-1. Reject a
* peer KeyUpdate that would advance the receiving epoch past the
* limit. Validate on a local copy so ssl->dtls13PeerEpoch is left
* untouched when the check fails. */
if (w64GT(newEpoch,
w64From32(DTLS13_EPOCH_MAX_HI32, DTLS13_EPOCH_MAX_LO32)))
return BAD_STATE_E;
ssl->dtls13PeerEpoch = newEpoch;
ret = Dtls13SetEpochKeys(ssl, ssl->dtls13PeerEpoch, DECRYPT_SIDE_ONLY);
if (ret != 0)
+5
View File
@@ -5948,6 +5948,11 @@ enum {
DTLS13_EPOCH_TRAFFIC0 = 3
};
/* RFC 9147 Section 4.2.1: the DTLS 1.3 epoch is a 48-bit value and must not
* exceed 2^48-1. Expressed as the high/low 32-bit halves of a w64wrapper. */
#define DTLS13_EPOCH_MAX_HI32 0x0000FFFFU
#define DTLS13_EPOCH_MAX_LO32 0xFFFFFFFFU
/* 64-bit epoch + 64-bit sequence number */
#define DTLS13_RN_SIZE (OPAQUE64_LEN + OPAQUE64_LEN)
/* Maximum number of ACK records allowed in an ACK message */