@@ -1928,6 +1928,128 @@ int test_dtls13_ch2_rtx_no_ch1(void)
19281928 return EXPECT_RESULT ();
19291929}
19301930
1931+ int test_dtls13_frag_ch2_with_ch1_rtx (void )
1932+ {
1933+ EXPECT_DECLS ;
1934+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && \
1935+ defined(WOLFSSL_DTLS13 ) && defined(WOLFSSL_DTLS ) && \
1936+ defined(WOLFSSL_DTLS_MTU ) && defined(WOLFSSL_DTLS_CH_FRAG )
1937+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
1938+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
1939+ struct test_memio_ctx test_ctx ;
1940+ char hrr [TEST_MEMIO_BUF_SZ ];
1941+ int hrrSz = (int )sizeof (hrr );
1942+ char ch1Rtx [TEST_MEMIO_BUF_SZ ];
1943+ int ch1RtxSz = (int )sizeof (ch1Rtx );
1944+ char ch2 [TEST_MEMIO_BUF_SZ ];
1945+ int ch2Sz = 0 ;
1946+ int ch2MsgCount = 0 ;
1947+ int ch2MsgSizes [TEST_MEMIO_MAX_MSGS ] = {0 };
1948+ /* The DTLS record sequence number occupies the last 8 bytes of the
1949+ * record header. */
1950+ int recordSeqOff = DTLS_RECORD_HEADER_SZ - 8 ;
1951+ int ch2Seq = 0 ;
1952+ int ch1RtxSeq = 0 ;
1953+ int off ;
1954+ int i ;
1955+
1956+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
1957+
1958+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
1959+ wolfDTLSv1_3_client_method , wolfDTLSv1_3_server_method ),
1960+ 0 );
1961+
1962+ /* To force HRR */
1963+ ExpectIntEQ (wolfSSL_NoKeyShares (ssl_c ), WOLFSSL_SUCCESS );
1964+ ExpectIntEQ (wolfSSL_dtls13_allow_ch_frag (ssl_s , 1 ), WOLFSSL_SUCCESS );
1965+
1966+ /* CH1 */
1967+ ExpectIntEQ (wolfSSL_connect (ssl_c ), -1 );
1968+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), WOLFSSL_ERROR_WANT_READ );
1969+
1970+ /* HRR */
1971+ ExpectIntEQ (wolfSSL_accept (ssl_s ), -1 );
1972+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_READ );
1973+ ExpectIntEQ (test_memio_copy_message (& test_ctx , 1 , hrr , & hrrSz , 0 ), 0 );
1974+
1975+ /* Drop HRR, trigger CH1 retransmission, copy and drop it */
1976+ test_memio_clear_buffer (& test_ctx , 1 );
1977+ if (wolfSSL_dtls13_use_quick_timeout (ssl_c ))
1978+ ExpectIntEQ (wolfSSL_dtls_got_timeout (ssl_c ), WOLFSSL_SUCCESS );
1979+ ExpectIntEQ (wolfSSL_dtls_got_timeout (ssl_c ), WOLFSSL_SUCCESS );
1980+ ExpectIntEQ (test_memio_copy_message (& test_ctx , 0 , ch1Rtx , & ch1RtxSz , 0 ), 0 );
1981+ test_memio_clear_buffer (& test_ctx , 0 );
1982+
1983+ /* Force CH2 fragmentation */
1984+ ExpectIntEQ (wolfSSL_dtls_set_mtu (ssl_c , 256 ), WOLFSSL_SUCCESS );
1985+
1986+ /* Forward HRR and let the client create fragmented CH2 */
1987+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 1 , hrr , hrrSz ), 0 );
1988+ ExpectIntEQ (wolfSSL_connect (ssl_c ), -1 );
1989+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), WOLFSSL_ERROR_WANT_READ );
1990+
1991+ ExpectIntGT (test_ctx .s_msg_count , 1 );
1992+ ExpectIntLE (test_ctx .s_msg_count , TEST_MEMIO_MAX_MSGS );
1993+ ExpectIntLE (test_ctx .s_len , (int )sizeof (ch2 ));
1994+ if (EXPECT_SUCCESS ()) {
1995+ ch2Sz = test_ctx .s_len ;
1996+ ch2MsgCount = test_ctx .s_msg_count ;
1997+ XMEMCPY (ch2 , test_ctx .s_buff , ch2Sz );
1998+ XMEMCPY (ch2MsgSizes , test_ctx .s_msg_sizes ,
1999+ sizeof (ch2MsgSizes [0 ]) * (size_t )ch2MsgCount );
2000+
2001+ ch2Seq = ((byte )ch2 [recordSeqOff + 4 ] << 8 ) |
2002+ (byte )ch2 [recordSeqOff + 5 ];
2003+ ch1RtxSeq = ch2Seq + ch2MsgCount ;
2004+
2005+ /* Synthesize a CH1 retransmission that can pass the replay window after
2006+ * the first CH2 fragment makes the server stateful. The handshake
2007+ * message_seq remains the original CH1 value; only the DTLS record
2008+ * sequence is moved past the fragmented CH2 flight */
2009+ ch1Rtx [recordSeqOff + 0 ] = 0 ;
2010+ ch1Rtx [recordSeqOff + 1 ] = 0 ;
2011+ ch1Rtx [recordSeqOff + 2 ] = 0 ;
2012+ ch1Rtx [recordSeqOff + 3 ] = 0 ;
2013+ ch1Rtx [recordSeqOff + 4 ] = (byte )(ch1RtxSeq >> 8 );
2014+ ch1Rtx [recordSeqOff + 5 ] = (byte )ch1RtxSeq ;
2015+ }
2016+
2017+ test_memio_clear_buffer (& test_ctx , 0 );
2018+
2019+ /* Deliver CH2 first fragment only. Now server is stateful */
2020+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 0 , ch2 , ch2MsgSizes [0 ]), 0 );
2021+ ExpectIntEQ (wolfSSL_accept (ssl_s ), -1 );
2022+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_READ );
2023+
2024+ /* Deliver the retransmitted CH1 between CH2 fragments, it should be
2025+ * discarded as rtx */
2026+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 0 , ch1Rtx , ch1RtxSz ), 0 );
2027+ ExpectIntEQ (wolfSSL_accept (ssl_s ), -1 );
2028+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_READ );
2029+ test_memio_clear_buffer (& test_ctx , 1 );
2030+
2031+ /* Deliver the rest of CH2 */
2032+ off = ch2MsgSizes [0 ];
2033+ for (i = 1 ; i < ch2MsgCount && EXPECT_SUCCESS (); i ++ ) {
2034+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 0 , ch2 + off ,
2035+ ch2MsgSizes [i ]), 0 );
2036+ off += ch2MsgSizes [i ];
2037+ }
2038+
2039+ /* Restore MTU so the client's input buffer can hold the full server
2040+ * flight (e.g. an SH carrying a hybrid PQC key share). */
2041+ ExpectIntEQ (wolfSSL_dtls_set_mtu (ssl_c , 1500 ), WOLFSSL_SUCCESS );
2042+
2043+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL ), 0 );
2044+
2045+ wolfSSL_free (ssl_c );
2046+ wolfSSL_CTX_free (ctx_c );
2047+ wolfSSL_free (ssl_s );
2048+ wolfSSL_CTX_free (ctx_s );
2049+ #endif
2050+ return EXPECT_RESULT ();
2051+ }
2052+
19312053int test_dtls_drop_client_ack (void )
19322054{
19332055 EXPECT_DECLS ;
0 commit comments