Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1449ef1
DTLS: reject WOLFSSL_DTLS_FRAG_POOL_SZ above 255
julek-wolfssl Oct 14, 2026
7140448
DTLS: tighten DtlsMsgSet argument checks
julek-wolfssl Oct 14, 2026
411fe63
DTLS: do not store zero-length fragments
julek-wolfssl Oct 14, 2026
ac79a6f
DTLS: fail on fragment assembly inconsistency
julek-wolfssl Oct 14, 2026
ed9b61f
DTLS 1.3: hash handshake messages longer than 64K
julek-wolfssl Oct 14, 2026
129a54a
Add randomized DTLS fragment bucket test
julek-wolfssl Oct 14, 2026
4b71f26
Keep the original block when wolfSSL_Realloc fails with WOLFSSL_CHECK…
julek-wolfssl Oct 14, 2026
5ddb9ac
DTLS bucket test: cover assembly failure and gate allocation failure …
julek-wolfssl Oct 14, 2026
2a5bc4e
DTLS bucket test: cover remaining error returns
julek-wolfssl Oct 15, 2026
5dbb899
DTLS: guard the fragment bucket copy fallback with WOLFSSL_NO_REALLOC
julek-wolfssl Oct 15, 2026
5cdfc9f
DTLS bucket test: count allocations per fragment
julek-wolfssl Oct 15, 2026
7b9131d
DTLS: purge stored messages the handshake moved past
julek-wolfssl Oct 15, 2026
1459ad4
DTLS 1.3: drop unauthenticated handshake fragments instead of failing
julek-wolfssl Oct 15, 2026
e14ce2a
DTLS: let the latest fragment describe a plaintext message
julek-wolfssl Oct 15, 2026
955cfa8
DTLS: order the rx message list by sequence number alone
julek-wolfssl Oct 15, 2026
5540d01
DTLS: keep a buffered message across a handshake suspend
julek-wolfssl Oct 15, 2026
3947226
Fix XFREE with WOLFSSL_STATIC_MEMORY and WOLFSSL_XFREE_NO_NULLNESS_CHECK
julek-wolfssl Oct 15, 2026
7de41b7
DTLS 1.3: only a complete ServerHello acknowledges the ClientHello
julek-wolfssl Oct 15, 2026
e6a0d10
DTLS: process buffered handshake messages in epoch order
julek-wolfssl Oct 15, 2026
c2cffb3
Store DTLS message epochs as w64wrapper, fix test lint
julek-wolfssl Oct 16, 2026
adef246
Fix CI: use the swdev device in the DTLS 1.3 epoch boundary test
julek-wolfssl Oct 19, 2026
b32de6f
DTLS: keep the fragment hardening to what normal traffic needs
julek-wolfssl Oct 28, 2026
da71eae
DTLS: drop bad handshake messages for the stateless server only again
julek-wolfssl Oct 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 19 additions & 22 deletions src/dtls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,24 +360,18 @@ static void Dtls13MsgWasProcessed(WOLFSSL* ssl, enum HandShakeType hs)

int Dtls13ProcessBufferedMessages(WOLFSSL* ssl)
{
DtlsMsg* msg = ssl->dtls_rx_msg_list;
DtlsMsg* msg;
word32 idx = 0;
int ret = 0;

WOLFSSL_ENTER("Dtls13ProcessBufferedMessages");

while (msg != NULL) {
DtlsMsgListPurge(ssl);

while ((msg = DtlsMsgListNextReady(ssl)) != NULL) {
int downgraded = 0;
idx = 0;

/* message not in order */
if (ssl->keys.dtls_expected_peer_handshake_number != msg->seq)
break;

/* message not complete */
if (!msg->ready)
break;

#ifndef WOLFSSL_DISABLE_EARLY_SANITY_CHECKS
ret = MsgCheckEncryption(ssl, msg->type, msg->encrypted);
if (ret != 0) {
Expand Down Expand Up @@ -421,10 +415,8 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl)
* incremented. */
ssl->keys.dtls_expected_peer_handshake_number++;

ssl->dtls_rx_msg_list = msg->next;
DtlsMsgDelete(msg, ssl->heap);
msg = ssl->dtls_rx_msg_list;
ssl->dtls_rx_msg_list_sz--;
DtlsMsgListRemove(ssl, msg);
DtlsMsgListPurge(ssl);
}

if (ret != 0)
Expand All @@ -438,10 +430,8 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl)

static int Dtls13NextMessageComplete(WOLFSSL* ssl)
{
return ssl->dtls_rx_msg_list != NULL &&
ssl->dtls_rx_msg_list->ready &&
ssl->dtls_rx_msg_list->seq ==
ssl->keys.dtls_expected_peer_handshake_number;
DtlsMsgListPurge(ssl);
return DtlsMsgListNextReady(ssl) != NULL;
}

static WC_INLINE int FragIsInOutputBuffer(WOLFSSL* ssl, const byte* frag)
Expand Down Expand Up @@ -527,7 +517,7 @@ int Dtls13HashClientHello(const WOLFSSL* ssl, byte* hash, int* hashSz,
}

/* Handshake header DTLS only fields are not included in the transcript hash */
int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input, word16 length)
int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input, word32 length)
{
int ret;

Expand All @@ -546,7 +536,7 @@ int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input, word16 length)
input += OPAQUE64_LEN;
length -= OPAQUE64_LEN;

return HashRaw(ssl, input, length);
return HashRaw(ssl, input, (int)length);
}

static int Dtls13SendFragment(WOLFSSL* ssl, byte* output, word16 output_size,
Expand Down Expand Up @@ -864,6 +854,7 @@ static int Dtls13DetectDisruption(WOLFSSL* ssl, word32 fragOffset)
/* is not the next fragment in the message (the check is not 100% perfect,
in the worst case, we don't detect the disruption and wait for the other
peer retransmission) */
DtlsMsgListPurge(ssl);
if (ssl->dtls_rx_msg_list != NULL) {
DtlsFragBucket* last = ssl->dtls_rx_msg_list->fragBucketList;
while (last != NULL && last->m.m.next != NULL)
Expand Down Expand Up @@ -1949,8 +1940,12 @@ static int _Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32 size,
return 0;
}

if (fragOff + fragLength > messageLength)
return BUFFER_ERROR;
/* Same error code as the DTLS 1.2 check so a stateless server drops it */
if (fragOff + fragLength > messageLength) {
WOLFSSL_MSG("Fragment outside of the handshake message");
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
return LENGTH_ERROR;
}

ret = Dtls13RtxMsgRecvd(ssl, (enum HandShakeType)handshakeType, fragOff,
&implicitAck);
Expand Down Expand Up @@ -2016,6 +2011,7 @@ static int _Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32 size,
ssl->keys.dtls_peer_handshake_number >
ssl->keys.dtls_expected_peer_handshake_number ||
usingAsyncCrypto) {
DtlsMsgListPurge(ssl);
if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) {
/* Only ack a fragment we really buffered. */
if (DtlsMsgStore(ssl, (word16)w64GetLow32(ssl->keys.curEpoch64),
Expand All @@ -2028,6 +2024,7 @@ static int _Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32 size,
else {
/* DTLS_POOL_SZ outstanding messages is way more than enough for any
* valid peer */
WOLFSSL_ERROR_VERBOSE(DTLS_TOO_MANY_FRAGMENTS_E);
return DTLS_TOO_MANY_FRAGMENTS_E;
}

Expand Down
Loading
Loading