@@ -19698,15 +19698,21 @@ static int Dtls13UpdateWindow(WOLFSSL* ssl)
1969819698 /* zero based index */
1969919699 w64Decrement(&diff64);
1970019700
19701- /* FIXME: check that diff64 < DTLS_WORDS_BITS */
19702- diff = w64GetLow32(diff64);
19703- wordIndex = ((int)diff) / DTLS_WORD_BITS;
19704- wordOffset = ((int)diff) % DTLS_WORD_BITS;
19701+ /* If the high 32 bits are non-zero, the gap is >= 2^32 which is far
19702+ * beyond the replay window; truncating via w64GetLow32 would set the
19703+ * wrong bit. Reject such packets as out-of-window. */
19704+ if (w64GetHigh32(diff64) != 0) {
19705+ WOLFSSL_MSG("Invalid sequence number to Dtls13UpdateWindow");
19706+ return BAD_STATE_E;
19707+ }
1970519708
19706- if (wordIndex >= WOLFSSL_DTLS_WINDOW_WORDS) {
19709+ diff = w64GetLow32(diff64);
19710+ if (diff >= (word32)(WOLFSSL_DTLS_WINDOW_WORDS * DTLS_WORD_BITS)) {
1970719711 WOLFSSL_MSG("Invalid sequence number to Dtls13UpdateWindow");
1970819712 return BAD_STATE_E;
1970919713 }
19714+ wordIndex = (int)(diff / DTLS_WORD_BITS);
19715+ wordOffset = (int)(diff % DTLS_WORD_BITS);
1971019716
1971119717 window[wordIndex] |= (1 << wordOffset);
1971219718 return 0;
@@ -19717,6 +19723,13 @@ static int Dtls13UpdateWindow(WOLFSSL* ssl)
1971719723
1971819724 /* as we are considering nextSeq inside the window, we should add + 1 */
1971919725 w64Increment(&diff64);
19726+ /* Same truncation hazard as the seq < nextSeq branch above: if the high
19727+ * 32 bits are non-zero the gap is >= 2^32, beyond anything the window
19728+ * can represent. Reject as out-of-window before truncating. */
19729+ if (w64GetHigh32(diff64) != 0) {
19730+ WOLFSSL_MSG("Invalid sequence number to Dtls13UpdateWindow");
19731+ return BAD_STATE_E;
19732+ }
1972019733 _DtlsUpdateWindowGTSeq(w64GetLow32(diff64), window);
1972119734
1972219735 w64Increment(&seq);
0 commit comments