mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-06 06:40:49 +02:00
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:
+12
-2
@@ -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
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user