Merge pull request #4907 from rizlik/dtls13

DTLSv1.3 support
This commit is contained in:
David Garske
2022-06-15 13:57:02 -07:00
committed by GitHub
35 changed files with 6047 additions and 323 deletions

View File

@@ -266,6 +266,26 @@ if("${FIPS_VERSION}" STREQUAL "v1")
override_cache(WOLFSSL_TLS13 "no")
endif()
# DTLS v1.3
add_option("WOLFSSL_DTLS13"
"Enable wolfSSL DTLS v1.3 (default: disabled)"
"no" "yes;no")
if(WOLFSSL_DTLS13)
if (NOT WOLFSSL_DTLS)
message(FATAL_ERROR "DTLS13 requires DTLS")
endif()
if (NOT WOLFSSL_TLS13)
message(FATAL_ERROR "DTLS13 requires TLS13")
endif()
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS13")
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_W64_WRAPPER")
if (WOLFSSL_AES)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AES_DIRECT")
endif()
endif()
# Post-handshake authentication
add_option("WOLFSSL_POSTAUTH"
"Enable wolfSSL Post-handshake Authentication (default: disabled)"
@@ -1870,6 +1890,7 @@ if(WOLFSSL_EXAMPLES)
tests/hash.c
tests/srp.c
tests/suites.c
tests/w64wrapper.c
tests/unit.c
examples/server/server.c
examples/client/client.c)

View File

@@ -307,6 +307,8 @@
<ClCompile Include="..\..\wolfcrypt\src\signature.c" />
<ClCompile Include="..\..\src\ssl.c" />
<ClCompile Include="..\..\src\tls.c" />
<ClCompile Include="..\..\src\tls13.c" />
<ClCompile Include="..\..\src\dtls13.c" />
<ClCompile Include="..\..\wolfcrypt\src\wc_encrypt.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfmath.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfevent.c" />

View File

@@ -278,6 +278,7 @@
<ClCompile Include="..\..\src\ssl.c" />
<ClCompile Include="..\..\src\tls.c" />
<ClCompile Include="..\..\src\tls13.c" />
<ClCompile Include="..\..\src\dtls13.c" />
<ClCompile Include="..\..\wolfcrypt\src\wc_encrypt.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfcrypt_first.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfcrypt_last.c" />

View File

@@ -41,6 +41,9 @@ function(generate_build_flags)
if(WOLFSSL_TLS13 OR WOLFSSL_USER_SETTINGS)
set(BUILD_TLS13 "yes" PARENT_SCOPE)
endif()
if(WOLFSSL_DTLS13 OR WOLFSSL_USER_SETTINGS)
set(BUILD_DTLS13 "yes" PARENT_SCOPE)
endif()
if(WOLFSSL_RNG OR WOLFSSL_USER_SETTINGS)
set(BUILD_RNG "yes" PARENT_SCOPE)
endif()
@@ -812,6 +815,10 @@ function(generate_lib_src_list LIB_SOURCES)
list(APPEND LIB_SOURCES src/tls13.c)
endif()
if(BUILD_DTLS13)
list(APPEND LIB_SOURCES src/dtls13.c)
endif()
if(BUILD_OCSP)
list(APPEND LIB_SOURCES src/ocsp.c)
endif()

View File

@@ -876,7 +876,6 @@ then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DTLS_MTU"
fi
# TLS v1.3 Draft 18 (Note: only final TLS v1.3 supported, here for backwards build compatibility)
AC_ARG_ENABLE([tls13-draft18],
[AS_HELP_STRING([--enable-tls13-draft18],[Enable wolfSSL TLS v1.3 Draft 18 (default: disabled)])],
@@ -3513,6 +3512,24 @@ else
fi
fi
# DTLSv1.3
AC_ARG_ENABLE([dtls13],
[AS_HELP_STRING([--enable-dtls13],[Enable wolfSSL DTLS v1.3 (default: disabled)])],
[ ENABLED_DTLS13=$enableval ],
[ ENABLED_DTLS13=no ]
)
if test "x$ENABLED_DTLS13" = "xyes"
then
if test "x$ENABLED_DTLS" != "xyes" || test "x$ENABLED_TLS13" != "xyes"
then
AC_MSG_ERROR([You need to enable both DTLS and TLSv1.3 to use DTLSv1.3])
fi
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DTLS13 -DWOLFSSL_W64_WRAPPER"
if test "x$ENABLED_AES" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT"
fi
fi
# CODING
AC_ARG_ENABLE([coding],
@@ -7850,6 +7867,7 @@ AM_CONDITIONAL([BUILD_HMAC],[test "x$ENABLED_HMAC" = "xyes"])
AM_CONDITIONAL([BUILD_ERROR_STRINGS],[test "x$ENABLED_ERROR_STRINGS" = "xyes"])
AM_CONDITIONAL([BUILD_DO178],[test "x$ENABLED_DO178" = "xyes"])
AM_CONDITIONAL([BUILD_PSA],[test "x$ENABLED_PSA" = "xyes"])
AM_CONDITIONAL([BUILD_DTLS13],[test "x$ENABLED_DTLS13" = "xyes"])
if test "$ENABLED_REPRODUCIBLE_BUILD" != "yes" &&
(test "$ax_enable_debug" = "yes" ||
@@ -8169,6 +8187,7 @@ echo " * chrony: $ENABLED_CHRONY"
echo " * strongSwan: $ENABLED_STRONGSWAN"
echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS"
echo " * DTLS: $ENABLED_DTLS"
echo " * DTLS v1.3: $ENABLED_DTLS13"
echo " * SCTP: $ENABLED_SCTP"
echo " * SRTP: $ENABLED_SRTP"
echo " * Indefinite Length: $ENABLED_BER_INDEF"

View File

@@ -3326,6 +3326,47 @@ int wolfSSL_dtls_get_using_nonblock(WOLFSSL*);
\sa wolfSSL_dtls_set_peer
*/
int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl);
/*!
\brief This function returns true if the application should setup a quicker
timeout. When using non-blocking sockets, something in the user code needs
to decide when to check for available data and how long it needs to wait. If
this function returns true, it means that the library already detected some
disruption in the communication, but it wants to wait for a little longer in
case some messages from the other peers are still in flight. Is up to the
application to fine tune the value of this timer, a good one may be
dtls_get_current_timeout() / 4.
\return true if the application code should setup a quicker timeout
\param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new().
\sa wolfSSL_dtls
\sa wolfSSL_dtls_get_peer
\sa wolfSSL_dtls_got_timeout
\sa wolfSSL_dtls_set_peer
\sa wolfSSL_dtls13_set_send_more_acks
*/
int wolfSSL_dtls13_use_quick_timeout(WOLFSSL *ssl);
/*!
\ingroup Setup
\brief This function sets whether the library should send ACKs to the other
peer immediately when detecting disruption or not. Sending ACKs immediately
assures minimum latency but it may consume more bandwidth than necessary. If
the application manages the timer by itself and this option is set to 0 then
application code can use wolfSSL_dtls13_use_quick_timeout() to determine if
it should setup a quicker timeout to send those delayed ACKs.
\param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new().
\param value 1 to set the option, 0 to disable the option
\sa wolfSSL_dtls
\sa wolfSSL_dtls_get_peer
\sa wolfSSL_dtls_got_timeout
\sa wolfSSL_dtls_set_peer
\sa wolfSSL_dtls13_use_quick_timeout
*/
void wolfSSL_dtls13_set_send_more_acks(WOLFSSL *ssl, int value);
/*!
\ingroup Setup
@@ -14044,3 +14085,12 @@ int wolfSSL_RSA_sign_generic_padding(int type, const unsigned char* m,
unsigned int mLen, unsigned char* sigRet,
unsigned int* sigLen, WOLFSSL_RSA* rsa,
int flag, int padding);
/*!
\brief checks if DTLSv1.3 stack has some messages sent but not yet acknowledged
by the other peer
\return 1 if there are pending messages, 0 otherwise
\param ssl A WOLFSSL object pointer
*/
int wolfSSL_dtls13_has_pending_msg(WOLFSSL *ssl);

View File

@@ -905,9 +905,15 @@ static int bench_tls_client(info_t* info)
#ifdef WOLFSSL_DTLS
if (info->doDTLS) {
if (tls13) {
return WOLFSSL_SUCCESS;
#ifdef WOLFSSL_DTLS13
cli_ctx = wolfSSL_CTX_new(wolfDTLSv1_3_client_method());
#endif
}
else {
#ifndef WOLFSSL_NO_TLS12
cli_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
#endif
}
cli_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
}
else
#endif
@@ -1348,9 +1354,15 @@ static int bench_tls_server(info_t* info)
#ifdef WOLFSSL_DTLS
if (info->doDTLS) {
if (tls13) {
return WOLFSSL_SUCCESS;
#ifdef WOLFSSL_DTLS13
srv_ctx = wolfSSL_CTX_new(wolfDTLSv1_3_server_method());
#endif
}
else {
#ifndef WOLFSSL_NO_TLS12
srv_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
#endif
}
srv_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
}
else
#endif

View File

@@ -142,6 +142,10 @@ static int lng_index = 0;
#endif
#ifdef HAVE_SESSION_TICKET
#ifndef SESSION_TICKET_LEN
#define SESSION_TICKET_LEN 256
#endif
static int sessionTicketCB(WOLFSSL* ssl,
const unsigned char* ticket, int ticketSz,
void* ctx)
@@ -803,7 +807,8 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
}
else
#endif
if (err != WOLFSSL_ERROR_WANT_READ) {
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
fprintf(stderr, "SSL_read bench error %d\n", err);
err_sys("SSL_read failed");
}
@@ -1068,7 +1073,9 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
}
}
if (mustRead && err == WOLFSSL_ERROR_WANT_READ) {
if (mustRead &&
(err == WOLFSSL_ERROR_WANT_READ
|| err == WOLFSSL_ERROR_WANT_WRITE)) {
elapsed = current_time(0) - start;
if (elapsed > MAX_NON_BLOCK_SEC) {
fprintf(stderr, "Nonblocking read timeout\n");
@@ -1868,6 +1875,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef WOLFSSL_SRTP
{ "srtp", 2, 260 }, /* optional argument */
#endif
#ifdef WOLFSSL_DTLS13
/* allow waitTicket option even when HAVE_SESSION_TICKET is 0. Otherwise
* tests that use this option will ignore the options following
* --waitTicket in the command line and fail */
{"waitTicket", 0, 261},
#endif /* WOLFSSL_DTLS13 */
{ 0, 0, 0 }
};
#endif
@@ -1994,6 +2007,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
const char* dtlsSrtpProfiles = NULL;
#endif
#ifdef HAVE_SESSION_TICKET
int waitTicket = 0;
#endif /* HAVE_SESSION_TICKET */
char buffer[WOLFSSL_MAX_ERROR_SZ];
int argc = ((func_args*)args)->argc;
@@ -2141,6 +2158,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
break;
#endif
#ifdef WOLFSSL_DTLS13
case 261:
#ifdef HAVE_SESSION_TICKET
waitTicket = 1;
#endif /* HAVE_SESSION_TICKET */
break;
#endif /* WOLFSSL_DTLS13 */
case 'G' :
#ifdef WOLFSSL_SCTP
doDTLS = 1;
@@ -2749,12 +2774,21 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
}
else {
if (doDTLS) {
if (version == 3)
if (version == 3) {
version = -2;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
else if (version == EITHER_DOWNGRADE_VERSION)
else if (version == EITHER_DOWNGRADE_VERSION) {
version = -3;
}
#endif
else if (version == 4) {
#ifdef WOLFSSL_DTLS13
version = -4;
#else
err_sys("Bad DTLS version");
#endif /* WOLFSSL_DTLS13 */
}
else
version = -1;
}
@@ -2833,6 +2867,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
method = wolfDTLSv1_2_client_method_ex;
break;
#endif
#ifdef WOLFSSL_DTLS13
case -4:
method = wolfDTLSv1_3_client_method_ex;
break;
#endif /* WOLFSSL_DTLS13 */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
case -3:
method = wolfDTLSv1_2_method_ex;
@@ -3450,7 +3489,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
if (!helloRetry && version >= 4) {
if (!helloRetry && (version >= 4 || version <= -4)) {
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, usePqc,
pqcAlg, 0);
}
@@ -4029,6 +4068,29 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(void)ClientWrite(ssl, msg, msgSz, "", 0);
#endif
#if defined(HAVE_SESSION_TICKET)
while (waitTicket == 1) {
unsigned char ticketBuf[SESSION_TICKET_LEN];
int zeroReturn = 0;
word32 size;
(void)zeroReturn;
size = sizeof(ticketBuf);
err = wolfSSL_get_SessionTicket(ssl, ticketBuf, &size);
if (err < 0)
err_sys("wolfSSL_get_SessionTicket failed");
if (size == 0) {
err = process_handshake_messages(ssl, !nonBlocking, &zeroReturn);
if (err < 0)
err_sys("error waiting for session ticket ");
}
else {
waitTicket = 0;
}
}
#endif
#ifndef NO_SESSION_CACHE
if (resumeSession) {
session = wolfSSL_get1_session(ssl);

View File

@@ -138,7 +138,11 @@ void echoclient_test(void* args)
#endif
#if defined(CYASSL_DTLS)
#ifdef WOLFSSL_DTLS13
method = wolfDTLSv1_3_client_method();
#elif !defined(WOLFSSL_NO_TLS12)
method = DTLSv1_2_client_method();
#endif
#elif !defined(NO_TLS)
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SNIFFER)
method = CyaTLSv1_2_client_method();

View File

@@ -145,7 +145,11 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
tcp_listen(&sockfd, &port, useAnyAddr, doDTLS, 0);
#if defined(CYASSL_DTLS)
#ifdef WOLFSSL_DTLS13
method = wolfDTLSv1_3_server_method();
#elif !defined(WOLFSSL_NO_TLS12)
method = CyaDTLSv1_2_server_method();
#endif
#elif !defined(NO_TLS)
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SNIFFER)
method = CyaTLSv1_2_server_method();

View File

@@ -416,6 +416,7 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
else
#endif
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE &&
err != WOLFSSL_ERROR_ZERO_RETURN &&
err != APP_DATA_READY) {
fprintf(stderr, "SSL_read echo error %d\n", err);
@@ -546,9 +547,16 @@ static void ServerRead(WOLFSSL* ssl, char* input, int inputLen)
}
else if (SSL_get_error(ssl, 0) == 0 &&
tcp_select(SSL_get_fd(ssl), 0) == TEST_RECV_READY) {
err = wolfSSL_peek(ssl, buffer, 0);
if(err < 0) {
err_sys_ex(runWithErrors, "wolfSSL_peek failed");
}
if (wolfSSL_pending(ssl))
err = WOLFSSL_ERROR_WANT_READ;
}
} while (err == WC_PENDING_E || err == WOLFSSL_ERROR_WANT_READ);
} while (err == WC_PENDING_E
|| err == WOLFSSL_ERROR_WANT_READ
|| err == WOLFSSL_ERROR_WANT_WRITE);
if (ret > 0) {
/* null terminate message */
input[ret] = '\0';
@@ -2160,13 +2168,22 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
}
else {
if (doDTLS) {
if (version == 3)
if (version == 3) {
version = -2;
}
else if (version == 4) {
#ifdef WOLFSSL_DTLS13
version = -4;
#else
err_sys_ex(runWithErrors, "Bad DTLS version");
#endif /* WOLFSSL_DTLS13 */
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
else if (version == EITHER_DOWNGRADE_VERSION)
else if (version == EITHER_DOWNGRADE_VERSION) {
version = -3;
}
#endif
else
else if (version == 2)
version = -1;
}
}
@@ -2225,7 +2242,16 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
case SERVER_DOWNGRADE_VERSION:
method = wolfSSLv23_server_method_ex;
if (!doDTLS) {
method = wolfSSLv23_server_method_ex;
}
else {
#ifdef WOLFSSL_DTLS13
method = wolfDTLS_server_method_ex;
#else
err_sys_ex(runWithErrors, "version not supported");
#endif /* WOLFSSL_DTLS13 */
}
break;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
case EITHER_DOWNGRADE_VERSION:
@@ -2246,6 +2272,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
method = wolfDTLSv1_2_server_method_ex;
break;
#endif
#ifdef WOLFSSL_DTLS13
case -4:
method = wolfDTLSv1_3_server_method_ex;
break;
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
case -3:
method = wolfDTLSv1_2_method_ex;
@@ -2291,6 +2322,19 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
err_sys_ex(catastrophic, "unable to get ctx");
if (minVersion != SERVER_INVALID_VERSION) {
#ifdef WOLFSSL_DTLS13
switch (minVersion) {
case 4:
minVersion = WOLFSSL_DTLSV1_3;
break;
case 3:
minVersion = WOLFSSL_DTLSV1_2;
break;
case 2:
minVersion = WOLFSSL_DTLSV1;
break;
}
#endif /* WOLFSSL_DTLS13 */
wolfSSL_CTX_SetMinVersion(ctx, minVersion);
}
@@ -2789,10 +2833,6 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
if (postHandAuth) {
unsigned int verify_flags = 0;
SSL_set_verify(ssl, WOLFSSL_VERIFY_PEER |
((usePskPlus) ? WOLFSSL_VERIFY_FAIL_EXCEPT_PSK :
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT), 0);
#ifdef TEST_BEFORE_DATE
verify_flags |= WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY;
#endif
@@ -3337,9 +3377,20 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
if (updateKeysIVs)
wolfSSL_update_keys(ssl);
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
if (postHandAuth)
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
if (postHandAuth) {
SSL_set_verify(ssl, WOLFSSL_VERIFY_PEER |
((usePskPlus) ? WOLFSSL_VERIFY_FAIL_EXCEPT_PSK :
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT), 0);
wolfSSL_request_certificate(ssl);
}
#endif
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
if (sendTicket) {
@@ -3389,6 +3440,23 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
Task_yield();
#endif
#if defined(WOLFSSL_DTLS13)
if (wolfSSL_dtls(ssl) && version == -4) {
int zero_return = 0;
while (wolfSSL_dtls13_has_pending_msg(ssl)) {
err =
process_handshake_messages(ssl, !nonBlocking, &zero_return);
if (err < 0) {
/* other peer closes the connection, non fatal */
if (zero_return)
break;
err_sys("Error while processing pending DTLSv1.3 messages");
}
}
}
#endif /* WOLFSSL_DTLS13 */
ret = SSL_shutdown(ssl);
if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
while (tcp_select(wolfSSL_get_fd(ssl), DEFAULT_TIMEOUT_SEC) ==

168
scripts/dtls13.test Executable file
View File

@@ -0,0 +1,168 @@
#!/bin/bash
set -e
cleanup () {
echo
echo "Cleaning up..."
if [ ! -z "$UDP_PROXY_PID" ];then
echo "Killing udp_proxy $UDP_PROXY_PID"
kill $UDP_PROXY_PID
fi
if [ ! -z "$SERVER_PID" ];then
echo "Killing server $SERVER_PID"
kill $SERVER_PID
fi
}
trap cleanup err exit
WOLFSSL_ROOT=$(pwd)
UDP_PROXY_PATH=$WOLFSSL_ROOT/../udp-proxy/udp_proxy
PROXY_PORT=12345
SERVER_PORT=11111
NEW_SESSION_TICKET_SIZE=200
KEY_UPDATE_SIZE=35
(killall udp_proxy || true)
(killall lt-server || true)
(killall lt-client || true)
# $WOLFSSL_ROOT/tests/unit.test tests/test-dtls13.conf
test_dropping_packets () {
for i in $(seq 0 11);do
echo -e "\ndropping packet $i\n" | tee -a /tmp/serr | tee -a /tmp/cerr | tee -a /tmp/udp
$UDP_PROXY_PATH -p $PROXY_PORT -s 127.0.0.1:$SERVER_PORT -f $i -u >>/tmp/udp &
UDP_PROXY_PID=$!
$WOLFSSL_ROOT/examples/server/server -v4 -u -Ta 2>>/tmp/serr &
SERVER_PID=$!
sleep 0.2
now=$(date +%s.%N)
$WOLFSSL_ROOT/examples/client/client -v4 -u -p$PROXY_PORT 2>>/tmp/cerr
elapsed=$(echo $(date +%s.%N) - $now | bc)
echo "it took ${elapsed} sec(s)" >> /tmp/udp
wait $SERVER_PID
SERVER_PID=
kill $UDP_PROXY_PID
UDP_PROXY_PID=
done
echo -e "\nTesting WANT_WRITE\n" | tee -a /tmp/serr | tee -a /tmp/cerr | tee -a /tmp/udp
# dropping last ack would be client error as wolfssl_read doesn't support WANT_WRITE as returned error
for i in $(seq 0 10);do
echo -e "\ndropping packet $i\n" | tee -a /tmp/serr | tee -a /tmp/cerr | tee -a /tmp/udp
$UDP_PROXY_PATH -p $PROXY_PORT -s 127.0.0.1:$SERVER_PORT -f $i -u >>/tmp/udp &
UDP_PROXY_PID=$!
$WOLFSSL_ROOT/examples/server/server -v4 -u -Ta -6 2>>/tmp/serr &
SERVER_PID=$!
sleep 0.2
now=$(date +%s.%N)
$WOLFSSL_ROOT/examples/client/client -v4 -u -p$PROXY_PORT -6 2>>/tmp/cerr
elapsed=$(echo $(date +%s.%N) - $now | bc)
echo "it took ${elapsed} sec(s)" >> /tmp/udp
wait $SERVER_PID
SERVER_PID=
kill $UDP_PROXY_PID
UDP_PROXY_PID=
done
}
# this test is based on detecting newSessionTicket message by its size. This is rather fragile.
test_dropping_new_session_ticket() {
echo -e "\ndropping new session ticket packet of size $NEW_SESSION_TICKET_SIZE\n" | tee -a /tmp/serr | tee -a /tmp/cerr | tee -a /tmp/udp
$UDP_PROXY_PATH -p $PROXY_PORT -s 127.0.0.1:$SERVER_PORT -F $NEW_SESSION_TICKET_SIZE -u >>/tmp/udp &
UDP_PROXY_PID=$!
$WOLFSSL_ROOT/examples/server/server -v4 -w -u 2>>/tmp/serr &
SERVER_PID=$!
sleep 0.2
now=$(date +%s.%N)
$WOLFSSL_ROOT/examples/client/client -v4 -u -p$PROXY_PORT -w --waitTicket 2>>/tmp/cerr
elapsed=$(echo $(date +%s.%N) - $now | bc)
echo "it took ${elapsed} sec(s)" >> /tmp/udp
wait $SERVER_PID
SERVER_PID=
kill $UDP_PROXY_PID
UDP_PROXY_PID=
}
test_permutations () {
SIDE=$1
PERMUTATIONS=$(python3 << EOF
import itertools
for p in itertools.permutations("$2"):
print(''.join(p))
EOF
)
echo "Testing $SIDE msg permutations"
for i in $PERMUTATIONS;do
echo -n "Testing $SIDE order $i"
UDP_LOGFILE=/tmp/udp-$SIDE-$i
$UDP_PROXY_PATH -p $PROXY_PORT -s 127.0.0.1:$SERVER_PORT -u -r $i -l $UDP_LOGFILE -S $SIDE &
UDP_PROXY_PID=$!
$WOLFSSL_ROOT/examples/server/server -v4 -u -Ta -w &> /tmp/serr &
SERVER_PID=$!
sleep 0.2
now=$(date +%s.%N)
$WOLFSSL_ROOT/examples/client/client -v4 -u -p$PROXY_PORT -w &> /tmp/cerr
elapsed=$(echo $(date +%s.%N) - $now | bc)
udp_lines=$(grep -P 'client:|server:' $UDP_LOGFILE | wc -l)
echo " took ${elapsed} sec(s) and produced ${udp_lines} messages"
wait $SERVER_PID
SERVER_PID=
kill $UDP_PROXY_PID
UDP_PROXY_PID=
rm $UDP_LOGFILE
done
echo "All $SIDE msg permutations succeeded"
}
test_time_delays () {
DELAYS=$(python3 << EOF
import itertools
t = [0.1, 0.5, 1.1]
tt = []
for i in itertools.product(t, t, t):
tt.append(i * 15)
for i in tt:
print(','.join(map(lambda x: str(x) , i)))
EOF
)
for DELAY in $DELAYS;do
echo -n "Testing delay $DELAY"
UDP_LOGFILE=/tmp/udp-delay-$DELAY
$UDP_PROXY_PATH -p $PROXY_PORT -s 127.0.0.1:$SERVER_PORT -u -l "$UDP_LOGFILE" -t $DELAY &
UDP_PROXY_PID=$!
$WOLFSSL_ROOT/examples/server/server -v4 -u -Ta -w &> /tmp/serr &
SERVER_PID=$!
sleep 0.2
now=$(date +%s.%N)
$WOLFSSL_ROOT/examples/client/client -v4 -u -p$PROXY_PORT -w &> /tmp/cerr
elapsed=$(echo $(date +%s.%N) - $now | bc)
udp_lines=$(grep -P 'client:|server:' "$UDP_LOGFILE" | wc -l)
echo " took ${elapsed} sec(s) and produced ${udp_lines} messages"
wait $SERVER_PID
SERVER_PID=
kill $UDP_PROXY_PID
UDP_PROXY_PID=
rm "$UDP_LOGFILE"
done
}
test_dropping_packets
test_permutations client 012
test_dropping_new_session_ticket
if [ ! -z $DTLS13_DO_SERVER_PERMUTATION_TEST ];then
test_permutations server 0123456
fi
# TODO: fix udp_proxy to not re-order close alert before app data
if [ ! -z $DTLS13_DO_DELAY_TEST ];then
test_time_delays
fi

View File

@@ -112,3 +112,7 @@ EXTRA_DIST += scripts/dertoc.pl
EXTRA_DIST += scripts/stm32l4-v4_0_1_build.sh
EXTRA_DIST += scripts/cleanup_testfiles.sh
if BUILD_DTLS13
EXTRA_DIST += scripts/dtls13.test
endif

2431
src/dtls13.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -693,6 +693,10 @@ if BUILD_SNIFFER
src_libwolfssl_la_SOURCES += src/sniffer.c
endif
if BUILD_DTLS13
src_libwolfssl_la_SOURCES += src/dtls13.c
endif
endif !BUILD_CRYPTONLY

File diff suppressed because it is too large Load Diff

View File

@@ -2081,6 +2081,15 @@ int SetCipherSpecs(WOLFSSL* ssl)
#endif
}
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls &&
ssl->version.major == DTLS_MAJOR &&
ssl->version.minor <= DTLSv1_3_MINOR) {
ssl->options.tls = 1;
ssl->options.tls1_3 = 1;
}
#endif /* WOLFSSL_DTLS13 */
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
if (IsAtLeastTLSv1_3(ssl->version) || ssl->specs.cipher_type != block)
ssl->options.encThenMac = 0;
@@ -2959,9 +2968,14 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
ssl->heap, ssl->devId, ssl->rng, ssl->options.tls1_3);
}
#ifdef WOLFSSL_DTLS13
if (ret == 0 && ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
ret = Dtls13SetRecordNumberKeys(ssl, side);
#endif /* WOLFSSL_DTLS13 */
#ifdef HAVE_SECURE_RENEGOTIATION
#ifdef WOLFSSL_DTLS
if (ret == 0 && ssl->options.dtls) {
if (ret == 0 && ssl->options.dtls && !ssl->options.tls1_3) {
if (wc_encrypt)
wc_encrypt->src = keys == &ssl->keys ? KEYS : SCR;
if (wc_decrypt)

106
src/ssl.c
View File

@@ -4516,6 +4516,18 @@ static int SetMinVersionHelper(byte* minVersion, int version)
break;
#endif
#ifdef WOLFSSL_DTLS13
case WOLFSSL_DTLSV1:
*minVersion = DTLS_MINOR;
break;
case WOLFSSL_DTLSV1_2:
*minVersion = DTLSv1_2_MINOR;
break;
case WOLFSSL_DTLSV1_3:
*minVersion = DTLSv1_3_MINOR;
break;
#endif /* WOLFSSL_DTLS13 */
default:
WOLFSSL_MSG("Bad function argument");
return BAD_FUNC_ARG;
@@ -11490,6 +11502,30 @@ int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
return timeout;
}
#ifdef WOLFSSL_DTLS13
/*
* This API returns 1 when the user should set a short timeout for receiving
* data. It is recommended that it is at most 1/4 the value returned by
* wolfSSL_dtls_get_current_timeout().
*/
int wolfSSL_dtls13_use_quick_timeout(WOLFSSL* ssl)
{
return ssl->dtls13FastTimeout;
}
/*
* When this is set, a DTLS 1.3 connection will send acks immediately when a
* disruption is detected to shortcut timeouts. This results in potentially
* more traffic but may make the handshake quicker.
*/
void wolfSSL_dtls13_set_send_more_acks(WOLFSSL* ssl, int value)
{
if (ssl != NULL)
ssl->options.dtls13SendMoreAcks = !!value;
}
#endif /* WOLFSSL_DTLS13 */
int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft)
{
if (ssl && timeleft) {
@@ -11560,6 +11596,21 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
if (ssl == NULL)
return WOLFSSL_FATAL_ERROR;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
result = Dtls13RtxTimeout(ssl);
if (result < 0) {
if (result == WANT_WRITE)
ssl->dtls13SendingAckOrRtx = 1;
ssl->error = result;
WOLFSSL_ERROR(result);
return WOLFSSL_FATAL_ERROR;
}
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_DTLS13 */
if ((IsSCR(ssl) || !ssl->options.handShakeDone)) {
if (DtlsMsgPoolTimeout(ssl) < 0){
ssl->error = SOCKET_ERROR_E;
@@ -11782,6 +11833,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
{
#if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
int neededState;
byte advanceState;
#endif
int ret = 0;
@@ -11849,6 +11901,21 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
}
#endif
/* fragOffset is non-zero when sending fragments. On the last
* fragment, fragOffset is zero again, and the state can be
* advanced. */
advanceState = ssl->fragOffset == 0 &&
(ssl->options.connectState == CONNECT_BEGIN ||
ssl->options.connectState == HELLO_AGAIN ||
(ssl->options.connectState >= FIRST_REPLY_DONE &&
ssl->options.connectState <= FIRST_REPLY_FOURTH));
;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
advanceState = advanceState && !ssl->dtls13SendingAckOrRtx;
#endif /* WOLFSSL_DTLS13 */
if (ssl->buffers.outputBuffer.length > 0
#ifdef WOLFSSL_ASYNC_CRYPT
/* do not send buffered or advance state if last error was an
@@ -11856,15 +11923,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
&& ssl->error != WC_PENDING_E
#endif
) {
if ( (ret = SendBuffered(ssl)) == 0) {
/* fragOffset is non-zero when sending fragments. On the last
* fragment, fragOffset is zero again, and the state can be
* advanced. */
if ( (ssl->error = SendBuffered(ssl)) == 0) {
if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
if (ssl->options.connectState == CONNECT_BEGIN ||
ssl->options.connectState == HELLO_AGAIN ||
(ssl->options.connectState >= FIRST_REPLY_DONE &&
ssl->options.connectState <= FIRST_REPLY_FOURTH)) {
if (advanceState) {
ssl->options.connectState++;
WOLFSSL_MSG("connect state: "
"Advanced from last buffered fragment send");
@@ -11935,6 +11996,27 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
#endif
neededState = SERVER_HELLODONE_COMPLETE;
}
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)
&& ssl->dtls13Rtx.sendAcks == 1) {
ssl->dtls13Rtx.sendAcks = 0;
/* we aren't negotiated the version yet, so we aren't sure
* the other end can speak v1.3. On the other side we have
* received a unified records, assuming that the
* ServerHello got lost, we will send an empty ACK. In case
* the server is a DTLS with version less than 1.3, it
* should just ignore the message */
if ((ssl->error = SendDtls13Ack(ssl)) < 0) {
if (ssl->error == WANT_WRITE)
ssl->dtls13SendingAckOrRtx = 1;
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;
}
}
#endif /* WOLFSSL_DTLS13 */
}
ssl->options.connectState = HELLO_AGAIN;
@@ -12088,6 +12170,12 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
WOLFSSL_MSG("connect state: FINISHED_DONE");
FALL_THROUGH;
#ifdef WOLFSSL_DTLS13
case WAIT_FINISHED_ACK:
ssl->options.connectState = FINISHED_DONE;
FALL_THROUGH;
#endif /* WOLFSSL_DTLS13 */
case FINISHED_DONE :
/* get response */
while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
@@ -19806,6 +19894,8 @@ static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
return "DTLS";
case DTLSv1_2_MINOR :
return "DTLSv1.2";
case DTLSv1_3_MINOR :
return "DTLSv1.3";
default:
return "unknown";
}

173
src/tls.c
View File

@@ -5633,6 +5633,58 @@ static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap)
/******************************************************************************/
#ifdef WOLFSSL_TLS13
static WC_INLINE int versionIsGreater(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a < b;
#endif /* WOLFSSL_DTLS */
return a > b;
}
static WC_INLINE int versionIsLesser(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a > b;
#endif /* WOLFSSL_DTLS */
return a < b;
}
static WC_INLINE int versionIsAtLeast(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a <= b;
#endif /* WOLFSSL_DTLS */
return a >= b;
}
static WC_INLINE int versionIsLessEqual(byte isDtls, byte a, byte b)
{
(void)isDtls;
#ifdef WOLFSSL_DTLS
/* DTLS version increases backwards (-1,-2,-3,etc) */
if (isDtls)
return a >= b;
#endif /* WOLFSSL_DTLS */
return a <= b;
}
/* Return the size of the SupportedVersions extension's data.
*
* data The SSL/TLS object.
@@ -5642,12 +5694,23 @@ static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap)
static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
{
WOLFSSL* ssl = (WOLFSSL*)data;
byte tls13Minor, tls12Minor, tls11Minor, isDtls;
/* unused on some configuration */
(void)tls12Minor;
(void)tls13Minor;
(void)tls11Minor;
isDtls = !!ssl->options.dtls;
tls13Minor = (byte)(isDtls ? DTLSv1_3_MINOR : TLSv1_3_MINOR);
tls12Minor = (byte)(isDtls ? DTLSv1_2_MINOR : TLSv1_2_MINOR);
tls11Minor = (byte)(isDtls ? DTLS_MINOR : TLSv1_1_MINOR);
if (msgType == client_hello) {
/* TLS v1.2 and TLS v1.3 */
int cnt = 0;
if ((ssl->options.minDowngrade <= TLSv1_3_MINOR)
if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
@@ -5658,17 +5721,19 @@ static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
if (ssl->options.downgrade) {
#ifndef WOLFSSL_NO_TLS12
if ((ssl->options.minDowngrade <= TLSv1_2_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
if (versionIsLessEqual(
isDtls, ssl->options.minDowngrade, tls12Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
#endif
#endif
) {
cnt++;
}
#endif
#endif
#ifndef NO_OLD_TLS
if ((ssl->options.minDowngrade <= TLSv1_1_MINOR)
if (versionIsLessEqual(
isDtls, ssl->options.minDowngrade, tls11Minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0
@@ -5677,7 +5742,7 @@ static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
cnt++;
}
#ifdef WOLFSSL_ALLOW_TLSV10
if ((ssl->options.minDowngrade <= TLSv1_MINOR)
if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1) == 0
@@ -5714,6 +5779,24 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
WOLFSSL* ssl = (WOLFSSL*)data;
byte major;
byte* cnt;
byte tls13minor, tls12minor, tls11minor, isDtls = 0;
tls13minor = (byte)TLSv1_3_MINOR;
tls12minor = (byte)TLSv1_2_MINOR;
tls11minor = (byte)TLSv1_1_MINOR;
/* unused in some configuration */
(void)tls11minor;
(void)tls12minor;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
tls13minor = (byte)DTLSv1_3_MINOR;
tls12minor = (byte)DTLSv1_2_MINOR;
tls11minor = (byte)DTLS_MINOR;
isDtls = 1;
}
#endif /* WOLFSSL_DTLS13 */
if (msgType == client_hello) {
major = ssl->ctx->method->version.major;
@@ -5721,11 +5804,11 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
cnt = output++;
*cnt = 0;
if ((ssl->options.minDowngrade <= TLSv1_3_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_3) == 0
#endif
#endif
) {
*cnt += OPAQUE16_LEN;
#ifdef WOLFSSL_TLS13_DRAFT
@@ -5735,26 +5818,26 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
*(output++) = TLS_DRAFT_MINOR;
#else
*(output++) = major;
*(output++) = (byte)TLSv1_3_MINOR;
*(output++) = tls13minor;
#endif
}
if (ssl->options.downgrade) {
#ifndef WOLFSSL_NO_TLS12
if ((ssl->options.minDowngrade <= TLSv1_2_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls12minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_2) == 0
#endif
) {
*cnt += OPAQUE16_LEN;
*(output++) = major;
*(output++) = (byte)TLSv1_2_MINOR;
*(output++) = tls12minor;
}
#endif
#ifndef NO_OLD_TLS
if ((ssl->options.minDowngrade <= TLSv1_1_MINOR)
if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls11minor)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1_1) == 0
@@ -5762,10 +5845,10 @@ static int TLSX_SupportedVersions_Write(void* data, byte* output,
) {
*cnt += OPAQUE16_LEN;
*(output++) = major;
*(output++) = (byte)TLSv1_1_MINOR;
*(output++) = tls11minor;
}
#ifdef WOLFSSL_ALLOW_TLSV10
if ((ssl->options.minDowngrade <= TLSv1_MINOR)
if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_WPAS_SMALL)
&& (ssl->options.mask & SSL_OP_NO_TLSv1) == 0
@@ -5811,6 +5894,20 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
int newMinor = 0;
int set = 0;
int ret;
int tls13minor;
int tls12minor;
byte isDtls;
tls13minor = TLSv1_3_MINOR;
tls12minor = TLSv1_2_MINOR;
isDtls = ssl->options.dtls == 1;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls) {
tls13minor = DTLSv1_3_MINOR;
tls12minor = DTLSv1_2_MINOR;
}
#endif /* WOLFSSL_DTLS13 */
if (msgType == client_hello) {
/* Must contain a length and at least one version. */
@@ -5844,23 +5941,27 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
continue;
/* No upgrade allowed. */
if (minor > ssl->version.minor)
if (versionIsGreater(isDtls, minor, ssl->version.minor))
continue;
/* Check downgrade. */
if (minor < ssl->version.minor) {
if (versionIsLesser(isDtls, minor, ssl->version.minor)) {
if (!ssl->options.downgrade)
continue;
if (minor < ssl->options.minDowngrade)
if (versionIsLesser(
isDtls, minor, ssl->options.minDowngrade))
continue;
if (newMinor == 0 && minor > ssl->options.oldMinor) {
if (newMinor == 0 &&
versionIsGreater(
isDtls, minor, ssl->options.oldMinor)) {
/* Downgrade the version. */
ssl->version.minor = minor;
}
}
if (minor >= TLSv1_3_MINOR) {
if (versionIsAtLeast(isDtls, minor, tls13minor)) {
if (!ssl->options.tls1_3) {
ssl->options.tls1_3 = 1;
ret = TLSX_Prepend(&ssl->extensions,
@@ -5870,12 +5971,13 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
}
TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
}
if (minor > newMinor) {
if (versionIsGreater(isDtls, minor, newMinor)) {
ssl->version.minor = minor;
newMinor = minor;
}
}
else if (minor > ssl->options.oldMinor)
else if (versionIsGreater(
isDtls, minor, ssl->options.oldMinor))
ssl->options.oldMinor = minor;
set = 1;
@@ -5901,25 +6003,26 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input,
return VERSION_ERROR;
/* Can't downgrade with this extension below TLS v1.3. */
if (minor < TLSv1_3_MINOR)
if (versionIsLesser(isDtls, minor, tls13minor))
return VERSION_ERROR;
/* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
if (ssl->options.downgrade && ssl->version.minor == TLSv1_2_MINOR) {
if (ssl->options.downgrade && ssl->version.minor == tls12minor) {
/* Set minor version back to TLS v1.3+ */
ssl->version.minor = ssl->ctx->method->version.minor;
}
/* No upgrade allowed. */
if (ssl->version.minor < minor)
if (versionIsLesser(isDtls, ssl->version.minor, minor))
return VERSION_ERROR;
/* Check downgrade. */
if (ssl->version.minor > minor) {
if (versionIsGreater(isDtls, ssl->version.minor, minor)) {
if (!ssl->options.downgrade)
return VERSION_ERROR;
if (minor < ssl->options.minDowngrade)
if (versionIsLesser(
isDtls, minor, ssl->options.minDowngrade))
return VERSION_ERROR;
/* Downgrade the version. */
@@ -12412,7 +12515,9 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
(void)heap;
WOLFSSL_ENTER("DTLS_client_method_ex");
if (method) {
#if !defined(WOLFSSL_NO_TLS12)
#if defined(WOLFSSL_DTLS13)
InitSSL_Method(method, MakeDTLSv1_3());
#elif !defined(WOLFSSL_NO_TLS12)
InitSSL_Method(method, MakeDTLSv1_2());
#elif !defined(NO_OLD_TLS)
InitSSL_Method(method, MakeDTLSv1());
@@ -12773,7 +12878,9 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
(void)heap;
WOLFSSL_ENTER("DTLS_server_method_ex");
if (method) {
#if !defined(WOLFSSL_NO_TLS12)
#if defined(WOLFSSL_DTLS13)
InitSSL_Method(method, MakeDTLSv1_3());
#elif !defined(WOLFSSL_NO_TLS12)
InitSSL_Method(method, MakeDTLSv1_2());
#elif !defined(NO_OLD_TLS)
InitSSL_Method(method, MakeDTLSv1());

File diff suppressed because it is too large Load Diff

View File

@@ -381,6 +381,7 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
int recvd;
int sd = dtlsCtx->rfd;
int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
byte doDtlsTimeout;
SOCKADDR_S peer;
XSOCKLENT peerSz = sizeof(peer);
@@ -388,16 +389,41 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
/* Don't use ssl->options.handShakeDone since it is true even if
* we are in the process of renegotiation */
if (ssl->options.handShakeState == HANDSHAKE_DONE)
doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE;
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
doDtlsTimeout =
doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL ||
(ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL);
}
#endif /* WOLFSSL_DTLS13 */
if (!doDtlsTimeout)
dtls_timeout = 0;
if (!wolfSSL_get_using_nonblock(ssl)) {
#ifdef USE_WINDOWS_API
DWORD timeout = dtls_timeout * 1000;
#ifdef WOLFSSL_DTLS13
if (wolfSSL_dtls13_use_quick_timeout(ssl) &&
IsAtLeastTLSv1_3(ssl->version))
timeout /= 4;
#endif /* WOLFSSL_DTLS13 */
#else
struct timeval timeout;
XMEMSET(&timeout, 0, sizeof(timeout));
timeout.tv_sec = dtls_timeout;
#ifdef WOLFSSL_DTLS13
if (wolfSSL_dtls13_use_quick_timeout(ssl) &&
IsAtLeastTLSv1_3(ssl->version)) {
if (dtls_timeout >= 4)
timeout.tv_sec = dtls_timeout / 4;
else
timeout.tv_usec = dtls_timeout * 1000000 / 4;
}
else
#endif /* WOLFSSL_DTLS13 */
timeout.tv_sec = dtls_timeout;
#endif
if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
sizeof(timeout)) != 0) {

View File

@@ -10,6 +10,7 @@ tests_unit_test_SOURCES = \
tests/api.c \
tests/suites.c \
tests/hash.c \
tests/w64wrapper.c \
tests/srp.c \
examples/client/client.c \
examples/server/server.c
@@ -39,6 +40,9 @@ EXTRA_DIST += tests/unit.h \
tests/test-dtls-sha2.conf \
tests/test-dtls-srtp.conf \
tests/test-dtls-srtp-fails.conf \
tests/test-dtls13.conf \
tests/test-dtls13-downgrade.conf \
tests/test-dtls13-psk.conf \
tests/test-sctp.conf \
tests/test-sctp-sha2.conf \
tests/test-sig.conf \

View File

@@ -1088,6 +1088,42 @@ int SuiteTest(int argc, char** argv)
strcpy(argv0[2], "");
#endif
#ifdef WOLFSSL_DTLS13
args.argc = 2;
strcpy(argv0[1], "tests/test-dtls13.conf");
printf("starting DTLSv1.3 suite\n");
test_harness(&args);
if (args.return_code != 0) {
printf("error from script %d\n", args.return_code);
args.return_code = EXIT_FAILURE;
goto exit;
}
#ifndef WOLFSSL_NO_TLS12
args.argc = 2;
strcpy(argv0[1], "tests/test-dtls13-downgrade.conf");
printf("starting DTLSv1.3 suite - downgrade\n");
test_harness(&args);
if (args.return_code != 0) {
printf("error from script %d\n", args.return_code);
args.return_code = EXIT_FAILURE;
goto exit;
}
#endif /* WOLFSSL_NO_TLS12 */
#ifndef NO_PSK
XSTRLCPY(argv0[1], "tests/test-dtls13-psk.conf", sizeof(argv0[1]));
printf("starting DTLS 1.3 psk suite tests\n");
test_harness(&args);
if (args.return_code != 0) {
printf("error from script %d\n", args.return_code);
args.return_code = EXIT_FAILURE;
goto exit;
}
#endif /* NO_PSK */
#endif /* WOLFSSL_DTLS13 */
#endif
#ifdef WOLFSSL_SCTP
/* add dtls-sctp extra suites */

View File

@@ -0,0 +1,11 @@
# server DTLSv1.3 allow downgrading
-vd
-7 2
-u
-l TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
# client TLSv1.2 group message
-v 3
-u
-l TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
-f

View File

@@ -0,0 +1,54 @@
# server TLSv1.3 PSK
# Use AES128-GCM and SHA256
-v 4
-u
-s
-l TLS13-AES128-GCM-SHA256
-d
# client TLSv1.3 PSK
# Use AES128-GCM and SHA256
-v 4
-u
-s
-l TLS13-AES128-GCM-SHA256
# server TLSv1.3 PSK plus
-v 4
-u
-j
-l TLS13-AES128-GCM-SHA256
-d
# client TLSv1.3 PSK
-v 4
-u
-s
-l TLS13-AES128-GCM-SHA256
# server TLSv1.3 PSK
-v 4
-u
-j
-l TLS13-AES128-GCM-SHA256
-d
# client TLSv1.3 not-PSK
-v 4
-u
-l TLS13-AES128-GCM-SHA256
# server TLSv1.3 PSK
# AES256-GCM and SHA384
-v 4
-u
-s
-l TLS13-AES256-GCM-SHA384
-d
# client TLSv1.3 PSK
# AES256-GCM and SHA384
-v 4
-u
-s
-l TLS13-AES256-GCM-SHA384

262
tests/test-dtls13.conf Normal file
View File

@@ -0,0 +1,262 @@
# server DTLSv1.3 defaults
-u
-v 4
-l TLS_AES_128_GCM_SHA256
# client DTLSv1.3 defaults
-u
-v 4
-l TLS_AES_128_GCM_SHA256
# server DTLSv1.3 defaults async I/O
-u
-v 4
-l TLS_AES_128_GCM_SHA256
-6
# client DTLSv1.3 defaults async I/O
-u
-v 4
-l TLS_AES_128_GCM_SHA256
-6
# server DTLSv1.3 TLS13-CHACHA20-POLY1305-SHA256
-u
-v 4
-l TLS13-CHACHA20-POLY1305-SHA256
# client DTLSv1.3 TLS13-CHACHA20-POLY1305-SHA256
-u
-v 4
-l TLS13-CHACHA20-POLY1305-SHA256
# server DTLSv1.3 TLS13-AES128-CCM-SHA256
-v 4
-u
-l TLS13-AES128-CCM-SHA256
# client DTLSv1.3 TLS13-AES128-CCM-SHA256
-u
-v 4
-u
-l TLS13-AES128-CCM-SHA256
# server DTLSv1.3 resumption
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-r
# client DTLSv1.3 resumption
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-r
# server DTLSv1.3 resumption - SHA384
-v 4
-u
-l TLS13-AES256-GCM-SHA384
-r
# client DTLSv1.3 resumption - SHA384
-v 4
-u
-l TLS13-AES256-GCM-SHA384
-r
# server DTLSv1.3 PSK without (EC)DHE
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-r
# client DTLSv1.3 PSK without (EC)DHE
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-r
-K
# server DTLSv1.3 accepting EarlyData
-u
-v 4
-l TLS13-AES128-GCM-SHA256
-r
-0
# client DTLSv1.3 sending EarlyData
-u
-v 4
-l TLS13-AES128-GCM-SHA256
-r
-0
# client DTLSv1.3 sending EarlyData
-u
-v 4
-l TLS13-AES128-GCM-SHA256
-r
-0
# server DTLSv1.3 not accepting EarlyData
-u
-v 4
-l TLS13-AES128-GCM-SHA256
-r
# server DTLSv1.3 accepting EarlyData
-u
-v 4
-l TLS13-AES128-GCM-SHA256
-r
-0
# client DTLSv1.3 not sending EarlyData
-u
-v 4
-l TLS13-AES128-GCM-SHA256
-r
# server DTLSv1.3
-u
-v 4
-l TLS13-AES128-GCM-SHA256
# client DTLSv1.3 HelloRetryRequest to negotiate Key Exchange algorithm
-u
-v 4
-l TLS13-AES128-GCM-SHA256
-J
# server DTLSv1.3
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-J
# client DTLSv1.3 HelloRetryRequest with cookie
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-J
# server DTLSv1.3
-v 4
-u
-l TLS13-AES128-GCM-SHA256
# client DTLSv1.3 DH key exchange
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-y
# server DTLSv1.3
-v 4
-l TLS13-AES128-GCM-SHA256
# client DTLSv1.3 ECC key exchange
-v 4
-l TLS13-AES128-GCM-SHA256
-Y
# server DTLSv1.3 multiple cipher suites
-v 4
-l TLS13-AES128-GCM-SHA256:TLS13-AES256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-CCM-SHA256:TLS13-AES128-CCM-8-SHA256
# client DTLSv1.3
-v 4
-l TLS13-AES128-GCM-SHA256:TLS13-AES256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-CCM-SHA256:TLS13-AES128-CCM-8-SHA256
# server DTLSv1.3 KeyUpdate
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-U
# client DTLSv1.3 KeyUpdate
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-I
# server DTLSv1.3 KeyUpdate
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-U
# client DTLSv1.3 KeyUpdate
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-I
# server DTLSv1.3 No session ticket
-v 4
-l TLS13-AES128-GCM-SHA256
-u
-T
# client DTLSv1.3 No session ticket
-v 4
-u
-l TLS13-AES128-GCM-SHA256
# server DTLSv1.3 No session ticket
-v 4
-l TLS13-AES128-GCM-SHA256
-u
# client DTLSv1.3 wait ticket
-v 4
-u
-l TLS13-AES128-GCM-SHA256
--waitTicket
# server DTLSv1.3 Post-Handshake Authentication
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-Q
# client DTLSv1.3 Post-Handshake Authentication
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-Q
# server DTLSv1.3 group messages
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-f
# client DTLSv1.3 group message
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-f
# server DTLSv1.3 group messages
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-f
# client DTLSv1.3
-v 4
-u
-l TLS13-AES128-GCM-SHA256
# server DTLSv1.3
-v 4
-u
-l TLS13-AES128-GCM-SHA256
# client DTLSv1.3 group message
-v 4
-u
-l TLS13-AES128-GCM-SHA256
-f

View File

@@ -163,6 +163,14 @@ int unit_test(int argc, char** argv)
printf("hash test failed with %d\n", ret);
goto exit;
}
#ifdef WOLFSSL_W64_WRAPPER
if ((ret = w64wrapper_test()) != 0) {
printf("w64wrapper test failed with %d\n", ret);
goto exit;
}
#endif /* WOLFSSL_W64_WRAPPER */
}
#ifndef NO_WOLFSSL_CIPHER_SUITE_TEST

View File

@@ -107,6 +107,7 @@ void ApiTest(void);
int SuiteTest(int argc, char** argv);
int HashTest(void);
void SrpTest(void);
int w64wrapper_test(void);
#endif /* CyaSSL_UNIT_H */

218
tests/w64wrapper.c Normal file
View File

@@ -0,0 +1,218 @@
/* w64wrapper.c w64wrapper unit tests
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <tests/unit.h>
#ifdef WOLFSSL_W64_WRAPPER
#ifndef NO_INLINE
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#else
#include <wolfssl/wolfcrypt/misc.h>
#endif
int w64wrapper_test(void)
{
w64wrapper a, b, c;
byte wrap, raw[8];
a = w64From32(0x01020304, 0x05060708);
#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_W64_WRAPPER_TEST)
if (a.n != 0x0102030405060708)
return -1;
#else
if (a.n[0] != 0x01020304 || a.n[1] != 0x05060708)
return -1;
#endif /* WORD64_AVAILABLE && WOLFSSL_W64_WRAPPER_TEST */
if (w64GetLow32(a) != 0x05060708)
return -2;
if (w64GetHigh32(a) != 0x01020304)
return -3;
w64SetLow32(&a, 0xabcdefff);
if (w64GetLow32(a) != 0xabcdefff || w64GetHigh32(a) != 0x01020304)
return -4;
a = w64From32(0,0);
w64Increment(&a);
if (w64GetLow32(a) != 1 || w64GetHigh32(a) != 0)
return -5;
a = w64From32(0, 0xffffffff);
w64Increment(&a);
if (w64GetLow32(a) != 0 || w64GetHigh32(a) != 1)
return -6;
a = w64From32(0,1);
w64Decrement(&a);
if (w64GetLow32(a) != 0 || w64GetHigh32(a) != 0)
return -7;
a = w64From32(1,0);
w64Decrement(&a);
if (w64GetLow32(a) != 0xffffffff || w64GetHigh32(a) != 0)
return -8;
a = w64From32(0xabcdef, 0xdeed);
b = w64From32(0xabcdef, 0xdeed);
if (!w64Equal(a, b))
return -9;
a = w64From32(1, 1);
b = w64From32(0, 1);
if (w64Equal(a, b))
return -10;
wrap = 0;
a = w64From32(0x0, 0x1);
b = w64Add32(a, 0x1, &wrap);
if (w64GetLow32(b) != 0x2 || w64GetHigh32(b) != 0x0 || wrap)
return -11;
wrap = 0;
a = w64From32(0x0, 0xffffffff);
b = w64Add32(a, 0x1, &wrap);
if (w64GetLow32(b) != 0x0 || w64GetHigh32(b) != 0x01 || wrap)
return -12;
wrap = 0;
a = w64From32(0xffffffff, 0xffffffff);
b = w64Add32(a, 0x1, &wrap);
if (w64GetLow32(b) != 0x0 || w64GetHigh32(b) != 0x00 || !wrap)
return -13;
wrap = 0;
a = w64From32(0x0, 0x1);
b = w64Sub32(a, 0x1, &wrap);
if (w64GetLow32(b) != 0x0 || w64GetHigh32(b) != 0x00 || wrap)
return -14;
wrap = 0;
a = w64From32(0xffffffff, 0x0);
b = w64Sub32(a, 0x1, &wrap);
if (w64GetLow32(b) != 0xffffffff ||
w64GetHigh32(b) != 0xfffffffe || wrap)
return -15;
wrap = 0;
a = w64From32(0x0, 0x0);
b = w64Sub32(a, 0x1, &wrap);
if (w64GetLow32(b) != 0xffffffff ||
w64GetHigh32(b) != 0xffffffff || !wrap)
return -16;
a = w64From32(0x0, 0x0);
b = w64From32(0x0, 0x0);
if (w64GT(a,b) || w64GT(b,a) || !w64GTE(a,b) || w64LT(a,b) || w64LT(b,a))
return -17;
a = w64From32(0x0, 0x1);
b = w64From32(0x0, 0x0);
if (!w64GT(a, b) || w64GT(b, a) || !w64GTE(a, b) || w64GTE(b, a) ||
w64LT(a, b) || !w64LT(b, a))
return -18;
a = w64From32(0x1, 0x0);
b = w64From32(0x0, 0x0);
if (!w64GT(a, b) || w64GT(b, a) || !w64GTE(a, b) || w64GTE(b, a) ||
!w64LT(b, a) || w64LT(a, b))
return -19;
a = w64From32(0x1, 0x0);
b = w64From32(0x1, 0x0);
if (w64GT(a,b) || w64GT(b,a) || !w64GTE(a,b) || w64LT(a,b))
return -20;
a = w64From32(0x1, 0x1);
b = w64From32(0x1, 0x0);
if (!w64GT(a, b) || w64GT(b, a) || !w64GTE(a, b) || w64GTE(b, a) ||
w64LT(a, b) || !w64LT(b, a))
return -21;
a = w64From32(0x2, 0x1);
b = w64From32(0x1, 0x3);
if (!w64GT(a, b) || w64GT(b, a) || !w64GTE(a, b) || w64GTE(b, a) ||
w64LT(a, b) || !w64LT(b, a))
return -22;
a = w64From32(0x0, 0x0);
if (!w64IsZero(a))
return -23;
a = w64From32(0x01020304, 0x05060708);
c64toa(&a, raw);
if (raw[0] != 0x01
||raw[1] != 0x02
||raw[2] != 0x03
||raw[3] != 0x04
||raw[4] != 0x05
||raw[5] != 0x06
||raw[6] != 0x07
||raw[7] != 0x08) {
return -24;
}
b = w64From32(0x0,0x0);
ato64(raw, &b);
if (w64GetHigh32(b) != 0x01020304 || w64GetLow32(b) != 0x05060708)
return -25;
w64Zero(&b);
if (w64GetHigh32(b) != 0x0 || w64GetLow32(b) != 0x0)
return -26;
b = w64From32(0x0, 0xffffffff);
w64Increment(&b);
if (w64GetHigh32(b) != 0x1 || w64GetLow32(b) != 0x0)
return -27;
b = w64From32(0xffffffff, 0xffffffff);
w64Increment(&b);
if (w64GetHigh32(b) != 0x0 || w64GetLow32(b) != 0x0)
return -28;
b = w64From32(0xffffffff, 0x0);
w64Decrement(&b);
if (w64GetHigh32(b) != 0xfffffffe || w64GetLow32(b) != 0xffffffff)
return -29;
a = w64From32(0x01, 0x20);
b = w64From32(0x01, 0x10);
c = w64Sub(a,b);
if (w64GetHigh32(c) != 0x0 || w64GetLow32(c) != 0x10)
return -30;
c = w64Sub(b,a);
if (w64GetHigh32(c) != 0xffffffff || w64GetLow32(c) != 0xfffffff0)
return -31;
a = w64From32(0x01, 0x10);
b = w64From32(0x00, 0x20);
c = w64Sub(a,b);
if (w64GetHigh32(c) != 0x00000000 || w64GetLow32(c) != 0xfffffff0)
return -32;
return 0;
}
#endif /* WOLFSSL_W64_WRAPPER */

View File

@@ -546,6 +546,250 @@ WC_STATIC WC_INLINE byte ctSetLTE(int a, int b)
}
#endif
#if defined(WOLFSSL_W64_WRAPPER)
#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_W64_WRAPPER_TEST)
WC_STATIC WC_INLINE void w64Increment(w64wrapper *n) {
n->n++;
}
WC_STATIC WC_INLINE void w64Decrement(w64wrapper *n) {
n->n--;
}
WC_STATIC WC_INLINE byte w64Equal(w64wrapper a, w64wrapper b) {
return (a.n == b.n);
}
WC_STATIC WC_INLINE word32 w64GetLow32(w64wrapper n) {
return (word32)n.n;
}
WC_STATIC WC_INLINE word32 w64GetHigh32(w64wrapper n) {
return (word32)(n.n >> 32);
}
WC_STATIC WC_INLINE void w64SetLow32(w64wrapper *n, word32 low) {
n->n = (n->n & (~(word64)(0xffffffff))) | low;
}
WC_STATIC WC_INLINE w64wrapper w64Add32(w64wrapper a, word32 b, byte *wrap) {
a.n = a.n + b;
if (a.n < b && wrap != NULL)
*wrap = 1;
return a;
}
WC_STATIC WC_INLINE w64wrapper w64Sub32(w64wrapper a, word32 b, byte *wrap)
{
if (a.n < b && wrap != NULL)
*wrap = 1;
a.n = a.n - b;
return a;
}
WC_STATIC WC_INLINE byte w64GT(w64wrapper a, w64wrapper b)
{
return a.n > b.n;
}
WC_STATIC WC_INLINE byte w64IsZero(w64wrapper a)
{
return a.n == 0;
}
WC_STATIC WC_INLINE void c64toa(const w64wrapper *a, byte *out)
{
#ifdef BIG_ENDIAN_ORDER
XMEMCPY(out, &a->n, sizeof(a->n));
#else
word64 _out;
_out = ByteReverseWord64(a->n);
XMEMCPY(out, &_out, sizeof(_out));
#endif /* BIG_ENDIAN_ORDER */
}
WC_STATIC WC_INLINE void ato64(const byte *in, w64wrapper *w64)
{
#ifdef BIG_ENDIAN_ORDER
XMEMCPY(&w64->n, in, sizeof(w64->n));
#else
word64 _in;
XMEMCPY(&_in, in, sizeof(_in));
w64->n = ByteReverseWord64(_in);
#endif /* BIG_ENDIAN_ORDER */
}
WC_STATIC WC_INLINE w64wrapper w64From32(word32 hi, word32 lo)
{
w64wrapper ret;
ret.n = ((word64)hi << 32) | lo;
return ret;
}
WC_STATIC WC_INLINE byte w64GTE(w64wrapper a, w64wrapper b)
{
return a.n >= b.n;
}
WC_STATIC WC_INLINE byte w64LT(w64wrapper a, w64wrapper b)
{
return a.n < b.n;
}
WC_STATIC WC_INLINE w64wrapper w64Sub(w64wrapper a, w64wrapper b)
{
a.n -= b.n;
return a;
}
WC_STATIC WC_INLINE void w64Zero(w64wrapper *a)
{
a->n = 0;
}
#else
WC_STATIC WC_INLINE void w64Increment(w64wrapper *n)
{
n->n[1]++;
if (n->n[1] == 0)
n->n[0]++;
}
WC_STATIC WC_INLINE void w64Decrement(w64wrapper *n) {
if (n->n[1] == 0)
n->n[0]--;
n->n[1]--;
}
WC_STATIC WC_INLINE byte w64Equal(w64wrapper a, w64wrapper b)
{
return (a.n[0] == b.n[0] && a.n[1] == b.n[1]);
}
WC_STATIC WC_INLINE word32 w64GetLow32(w64wrapper n) {
return n.n[1];
}
WC_STATIC WC_INLINE word32 w64GetHigh32(w64wrapper n) {
return n.n[0];
}
WC_STATIC WC_INLINE void w64SetLow32(w64wrapper *n, word32 low)
{
n->n[1] = low;
}
WC_STATIC WC_INLINE w64wrapper w64Add32(w64wrapper a, word32 b, byte *wrap)
{
a.n[1] = a.n[1] + b;
if (a.n[1] < b) {
a.n[0]++;
if (wrap != NULL && a.n[0] == 0)
*wrap = 1;
}
return a;
}
WC_STATIC WC_INLINE w64wrapper w64Sub32(w64wrapper a, word32 b, byte *wrap)
{
byte _underflow = 0;
if (a.n[1] < b)
_underflow = 1;
a.n[1] -= b;
if (_underflow) {
if (a.n[0] == 0 && wrap != NULL)
*wrap = 1;
a.n[0]--;
}
return a;
}
WC_STATIC WC_INLINE w64wrapper w64Sub(w64wrapper a, w64wrapper b)
{
if (a.n[1] < b.n[1])
a.n[0]--;
a.n[1] -= b.n[1];
a.n[0] -= b.n[0];
return a;
}
WC_STATIC WC_INLINE void w64Zero(w64wrapper *a)
{
a->n[0] = a->n[1] = 0;
}
WC_STATIC WC_INLINE byte w64GT(w64wrapper a, w64wrapper b)
{
if (a.n[0] > b.n[0])
return 1;
if (a.n[0] == b.n[0])
return a.n[1] > b.n[1];
return 0;
}
WC_STATIC WC_INLINE byte w64GTE(w64wrapper a, w64wrapper b)
{
if (a.n[0] > b.n[0])
return 1;
if (a.n[0] == b.n[0])
return a.n[1] >= b.n[1];
return 0;
}
WC_STATIC WC_INLINE byte w64IsZero(w64wrapper a)
{
return a.n[0] == 0 && a.n[1] == 0;
}
WC_STATIC WC_INLINE void c64toa(w64wrapper *a, byte *out)
{
#ifdef BIG_ENDIAN_ORDER
word32 *_out = (word32*)(out);
_out[0] = a->n[0];
_out[1] = a->n[1];
#else
c32toa(a->n[0], out);
c32toa(a->n[1], out + 4);
#endif /* BIG_ENDIAN_ORDER */
}
WC_STATIC WC_INLINE void ato64(const byte *in, w64wrapper *w64)
{
#ifdef BIG_ENDIAN_ORDER
const word32 *_in = (const word32*)(in);
w64->n[0] = *_in;
w64->n[1] = *(_in + 1);
#else
ato32(in, &w64->n[0]);
ato32(in + 4, &w64->n[1]);
#endif /* BIG_ENDIAN_ORDER */
}
WC_STATIC WC_INLINE w64wrapper w64From32(word32 hi, word32 lo)
{
w64wrapper w64;
w64.n[0] = hi;
w64.n[1] = lo;
return w64;
}
WC_STATIC WC_INLINE byte w64LT(w64wrapper a, w64wrapper b)
{
if (a.n[0] < b.n[0])
return 1;
if (a.n[0] == b.n[0])
return a.n[1] < b.n[1];
return 0;
}
#endif /* WORD64_AVAILABLE && !WOLFSSL_W64_WRAPPER_TEST */
#endif /* WOLFSSL_W64_WRAPPER */
#undef WC_STATIC
#endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */

View File

@@ -1179,6 +1179,7 @@ enum Misc {
DTLS_MAJOR = 0xfe, /* DTLS major version number */
DTLS_MINOR = 0xff, /* DTLS minor version number */
DTLSv1_2_MINOR = 0xfd, /* DTLS minor version number */
DTLSv1_3_MINOR = 0xfc, /* DTLS minor version number */
SSLv3_MAJOR = 3, /* SSLv3 and TLSv1+ major version number */
SSLv3_MINOR = 0, /* TLSv1 minor version number */
TLSv1_MINOR = 1, /* TLSv1 minor version number */
@@ -1293,6 +1294,8 @@ enum Misc {
DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */
DTLS_RECORD_HEADER_SZ = 13, /* normal + epoch(2) + seq_num(6) */
DTLS_UNIFIED_HEADER_MIN_SZ = 2,
DTLS_RECORD_HEADER_MAX_SZ = 13,
DTLS_HANDSHAKE_EXTRA = 8, /* diff from normal */
DTLS_RECORD_EXTRA = 8, /* diff from normal */
DTLS_HANDSHAKE_SEQ_SZ = 2, /* handshake header sequence number */
@@ -1497,6 +1500,11 @@ enum Misc {
#endif
#endif
/* minimum DTLS Downgrade Minor version */
#ifndef WOLFSSL_MIN_DTLS_DOWNGRADE
#define WOLFSSL_MIN_DTLS_DOWNGRADE DTLS_MINOR;
#endif
/* Set max implicit IV size for AEAD cipher suites */
#define AEAD_MAX_IMP_SZ 12
@@ -1625,7 +1633,7 @@ enum Misc {
typedef char _args_test[sizeof((x)) >= sizeof((y)) ? 1 : -1]; \
(void)sizeof(_args_test)
/* states */
/* states. Adding state before HANDSHAKE_DONE will break session importing */
enum states {
NULL_STATE = 0,
@@ -1646,7 +1654,12 @@ enum states {
CLIENT_CHANGECIPHERSPEC_COMPLETE,
CLIENT_FINISHED_COMPLETE,
HANDSHAKE_DONE
HANDSHAKE_DONE,
#ifdef WOLFSSL_DTLS13
SERVER_FINISHED_ACKED,
#endif /* WOLFSSL_DTLS13 */
};
/* SSL Version */
@@ -1666,6 +1679,10 @@ WOLFSSL_LOCAL ProtocolVersion MakeTLSv1_3(void);
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1(void);
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_2(void);
#ifdef WOLFSSL_DTLS13
WOLFSSL_LOCAL ProtocolVersion MakeDTLSv1_3(void);
#endif /* WOLFSSL_DTLS13 */
#endif
#ifdef WOLFSSL_SESSION_EXPORT
WOLFSSL_LOCAL int wolfSSL_session_export_internal(WOLFSSL* ssl, byte* buf,
@@ -1799,6 +1816,10 @@ WOLFSSL_LOCAL int DoTls13ServerHello(WOLFSSL* ssl, const byte* input,
word32* inOutIdx, word32 helloSz,
byte* extMsgType);
WOLFSSL_LOCAL int RestartHandshakeHash(WOLFSSL* ssl);
WOLFSSL_LOCAL int Tls13DeriveKey(WOLFSSL *ssl, byte *output, int outputLen,
const byte *secret, const byte *label, word32 labelLen, int hashAlgo,
int includeMsgs);
#endif
int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int macSz,
int pLen, int content);
@@ -2228,6 +2249,11 @@ typedef struct Keys {
byte aead_dec_imp_IV[AEAD_MAX_IMP_SZ];
#endif
#ifdef WOLFSSL_DTLS13
byte client_sn_key[MAX_SYM_KEY_SIZE];
byte server_sn_key[MAX_SYM_KEY_SIZE];
#endif /* WOLFSSL_DTLS13 */
word32 peer_sequence_number_hi;
word32 peer_sequence_number_lo;
word32 sequence_number_hi;
@@ -2237,6 +2263,12 @@ typedef struct Keys {
word16 curEpoch; /* Received epoch in current record */
word16 curSeq_hi; /* Received sequence in current record */
word32 curSeq_lo;
#ifdef WOLFSSL_DTLS13
w64wrapper curEpoch64; /* Received epoch in current record */
w64wrapper curSeq;
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_MULTICAST
byte curPeerId; /* Received peer group ID in current record */
#endif
@@ -3300,6 +3332,16 @@ typedef struct Ciphers {
#endif
} Ciphers;
#ifdef WOLFSSL_DTLS13
typedef struct RecordNumberCiphers {
#if defined(BUILD_AES) || defined(BUILD_AESGCM)
Aes *aes;
#endif /* BUILD_AES || BUILD_AESGCM */
#ifdef HAVE_CHACHA
ChaCha *chacha;
#endif
} RecordNumberCiphers;
#endif /* WOLFSSL_DTLS13 */
#ifdef HAVE_ONE_TIME_AUTH
/* Ciphers for one time authentication such as poly1305 */
@@ -3519,7 +3561,12 @@ enum ConnectState {
FIRST_REPLY_THIRD,
FIRST_REPLY_FOURTH,
FINISHED_DONE,
SECOND_REPLY_DONE
SECOND_REPLY_DONE,
#ifdef WOLFSSL_DTLS13
WAIT_FINISHED_ACK
#endif /* WOLFSSL_DTLS13 */
};
@@ -3799,6 +3846,10 @@ typedef struct Options {
#endif
word16 buildingMsg:1; /* If set then we need to re-enter the
* handshake logic. */
#ifdef WOLFSSL_DTLS13
word16 dtls13SendMoreAcks:1; /* Send more acks during the
* handshake process */
#endif
/* need full byte values for this section */
byte processReply; /* nonblocking resume */
@@ -4288,6 +4339,92 @@ typedef enum EarlyDataState {
} EarlyDataState;
#endif
#ifdef WOLFSSL_DTLS13
typedef struct Dtls13UnifiedHdrInfo {
word16 recordLength;
word16 headerLength;
byte seqLo;
byte seqHi;
byte seqHiPresent:1;
byte epochBits;
} Dtls13UnifiedHdrInfo;
enum {
DTLS13_EPOCH_EARLYDATA = 1,
DTLS13_EPOCH_HANDSHAKE = 2,
DTLS13_EPOCH_TRAFFIC0 = 3
};
typedef struct Dtls13Epoch {
w64wrapper epochNumber;
w64wrapper nextSeqNumber;
w64wrapper nextPeerSeqNumber;
word32 window[WOLFSSL_DTLS_WINDOW_WORDS];
/* key material for the epoch */
byte client_write_key[MAX_SYM_KEY_SIZE];
byte server_write_key[MAX_SYM_KEY_SIZE];
byte client_write_IV[MAX_WRITE_IV_SZ];
byte server_write_IV[MAX_WRITE_IV_SZ];
byte aead_exp_IV[AEAD_MAX_EXP_SZ];
byte aead_enc_imp_IV[AEAD_MAX_IMP_SZ];
byte aead_dec_imp_IV[AEAD_MAX_IMP_SZ];
byte client_sn_key[MAX_SYM_KEY_SIZE];
byte server_sn_key[MAX_SYM_KEY_SIZE];
byte isValid;
byte side;
} Dtls13Epoch;
#ifndef DTLS13_EPOCH_SIZE
#define DTLS13_EPOCH_SIZE 4
#endif
#ifndef DTLS13_RETRANS_RN_SIZE
#define DTLS13_RETRANS_RN_SIZE 3
#endif
enum Dtls13RtxFsmState {
DTLS13_RTX_FSM_PREPARING = 0,
DTLS13_RTX_FSM_SENDING,
DTLS13_RTX_FSM_WAITING,
DTLS13_RTX_FSM_FINISHED
};
typedef struct Dtls13RtxRecord {
struct Dtls13RtxRecord *next;
word16 length;
byte *data;
w64wrapper epoch;
w64wrapper seq[DTLS13_RETRANS_RN_SIZE];
byte rnIdx;
byte handshakeType;
} Dtls13RtxRecord;
typedef struct Dtls13RecordNumber {
struct Dtls13RecordNumber *next;
w64wrapper epoch;
w64wrapper seq;
} Dtls13RecordNumber;
typedef struct Dtls13Rtx {
enum Dtls13RtxFsmState state;
Dtls13RtxRecord *rtxRecords;
Dtls13RtxRecord **rtxRecordTailPtr;
Dtls13RecordNumber *seenRecords;
byte triggeredRtxs;
byte sendAcks:1;
byte retransmit:1;
word32 lastRtx;
} Dtls13Rtx;
#endif /* WOLFSSL_DTLS13 */
/* wolfSSL ssl type */
struct WOLFSSL {
WOLFSSL_CTX* ctx;
@@ -4482,6 +4619,29 @@ struct WOLFSSL {
* (selected profiles - up to 16) */
word16 dtlsSrtpId; /* DTLS-with-SRTP profile ID selected */
#endif
#ifdef WOLFSSL_DTLS13
RecordNumberCiphers dtlsRecordNumberEncrypt;
RecordNumberCiphers dtlsRecordNumberDecrypt;
Dtls13Epoch dtls13Epochs[DTLS13_EPOCH_SIZE];
Dtls13Epoch *dtls13EncryptEpoch;
Dtls13Epoch *dtls13DecryptEpoch;
w64wrapper dtls13Epoch;
w64wrapper dtls13PeerEpoch;
word16 dtls13CurRlLength;
/* used to store the message if it needs to be fragmented */
buffer dtls13FragmentsBuffer;
byte dtls13SendingFragments:1;
byte dtls13SendingAckOrRtx:1;
byte dtls13FastTimeout:1;
byte dtls13WaitKeyUpdateAck:1;
word32 dtls13MessageLength;
word32 dtls13FragOffset;
byte dtls13FragHandshakeType;
Dtls13Rtx dtls13Rtx;
#endif /* WOLFSSL_DTLS13 */
#endif /* WOLFSSL_DTLS */
#ifdef WOLFSSL_CALLBACKS
TimeoutInfo timeoutInfo; /* info saved during handshake */
@@ -4765,7 +4925,10 @@ enum ContentType {
change_cipher_spec = 20,
alert = 21,
handshake = 22,
application_data = 23
application_data = 23,
#ifdef WOLFSSL_DTLS13
ack = 26,
#endif /* WOLFSSL_DTLS13 */
};
@@ -4989,6 +5152,8 @@ WOLFSSL_LOCAL void DoCertFatalAlert(WOLFSSL* ssl, int ret);
#endif
#endif
WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl);
#ifndef NO_WOLFSSL_CLIENT
WOLFSSL_LOCAL int SendClientHello(WOLFSSL* ssl);
#ifdef WOLFSSL_TLS13
@@ -5027,6 +5192,10 @@ WOLFSSL_LOCAL void DoCertFatalAlert(WOLFSSL* ssl, int ret);
WOLFSSL_LOCAL int VerifyForTxDtlsMsgDelete(WOLFSSL* ssl, DtlsMsg* item);
WOLFSSL_LOCAL void DtlsMsgPoolReset(WOLFSSL* ssl);
WOLFSSL_LOCAL int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket);
WOLFSSL_LOCAL int GetDtlsHandShakeHeader(WOLFSSL *ssl, const byte *input,
word32 *inOutIdx, byte *type, word32 *size, word32 *fragOffset,
word32 *fragSz, word32 totalSz);
WOLFSSL_LOCAL int DtlsMsgDrain(WOLFSSL *ssl);
#endif /* WOLFSSL_DTLS */
#if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS)
@@ -5218,6 +5387,59 @@ WOLFSSL_LOCAL int oid2nid(word32 oid, int grp);
WOLFSSL_LOCAL word32 nid2oid(int nid, int grp);
#endif
#ifdef WOLFSSL_DTLS13
WOLFSSL_LOCAL struct Dtls13Epoch* Dtls13GetEpoch(WOLFSSL* ssl,
w64wrapper epochNumber);
WOLFSSL_LOCAL int Dtls13NewEpoch(WOLFSSL* ssl, w64wrapper epochNumber,
int side);
WOLFSSL_LOCAL int Dtls13SetEpochKeys(WOLFSSL* ssl, w64wrapper epochNumber,
enum encrypt_side side);
WOLFSSL_LOCAL int Dtls13GetSeq(WOLFSSL* ssl, int order, word32* seq,
byte increment);
WOLFSSL_LOCAL int Dtls13DoScheduledWork(WOLFSSL* ssl);
WOLFSSL_LOCAL int Dtls13DeriveSnKeys(WOLFSSL* ssl, int provision);
WOLFSSL_LOCAL int Dtls13SetRecordNumberKeys(WOLFSSL* ssl,
enum encrypt_side side);
WOLFSSL_LOCAL int Dtls13AddHeaders(byte* output, word32 length,
enum HandShakeType hs_type, WOLFSSL* ssl);
WOLFSSL_LOCAL word16 Dtls13GetHeadersLength(enum HandShakeType type);
WOLFSSL_LOCAL word16 Dtls13GetRlHeaderLength(byte is_encrypted);
WOLFSSL_LOCAL int Dtls13RlAddCiphertextHeader(WOLFSSL* ssl, byte* out,
word16 length);
WOLFSSL_LOCAL int Dtls13RlAddPlaintextHeader(WOLFSSL* ssl, byte* out,
enum ContentType content_type, word16 length);
WOLFSSL_LOCAL int Dtls13EncryptRecordNumber(WOLFSSL* ssl, byte* hdr,
word16 recordLength);
WOLFSSL_LOCAL int Dtls13IsUnifiedHeader(byte header_flags);
WOLFSSL_LOCAL int Dtls13ParseUnifiedRecordLayer(WOLFSSL* ssl, const byte* input,
word16 input_size, Dtls13UnifiedHdrInfo* hdrInfo);
WOLFSSL_LOCAL int Dtls13HandshakeSend(WOLFSSL* ssl, byte* output,
word16 output_size, word16 length, enum HandShakeType handshake_type,
int hash_output);
WOLFSSL_LOCAL int Dtls13RecordRecvd(WOLFSSL* ssl);
WOLFSSL_LOCAL int Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input,
word32* inOutIdx, word32 totalSz);
WOLFSSL_LOCAL int Dtls13HandshakeAddHeader(WOLFSSL* ssl, byte* output,
enum HandShakeType msg_type, word32 length);
#define EE_MASK (0x3)
WOLFSSL_LOCAL int Dtls13FragmentsContinue(WOLFSSL* ssl);
WOLFSSL_LOCAL int DoDtls13Ack(WOLFSSL* ssl, const byte* input, word32 inputSize,
word32* processedSize);
WOLFSSL_LOCAL int Dtls13ReconstructEpochNumber(WOLFSSL* ssl, byte epochBits,
w64wrapper* epoch);
WOLFSSL_LOCAL int Dtls13ReconstructSeqNumber(WOLFSSL* ssl,
Dtls13UnifiedHdrInfo* hdrInfo, w64wrapper* out);
WOLFSSL_LOCAL int SendDtls13Ack(WOLFSSL* ssl);
WOLFSSL_LOCAL int Dtls13RtxProcessingCertificate(WOLFSSL* ssl, byte* input,
word32 inputSize);
WOLFSSL_LOCAL int Dtls13HashHandshake(WOLFSSL* ssl, const byte* output,
word16 length);
WOLFSSL_LOCAL void Dtls13FreeFsmResources(WOLFSSL* ssl);
WOLFSSL_LOCAL int Dtls13RtxTimeout(WOLFSSL* ssl);
#endif /* WOLFSSL_DTLS13 */
#ifdef WOLFSSL_STATIC_EPHEMERAL
WOLFSSL_LOCAL int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr);
#endif

View File

@@ -865,6 +865,13 @@ WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_client_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method_ex(void* heap);
#ifdef WOLFSSL_DTLS13
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_client_method_ex(void* heap);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_server_method_ex(void* heap);
WOLFSSL_API int wolfSSL_dtls13_has_pending_msg(WOLFSSL *ssl);
#endif
#endif
/* CTX Method Constructor Functions */
@@ -899,6 +906,12 @@ WOLFSSL_ABI WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_2_client_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_client_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_2_server_method(void);
#ifdef WOLFSSL_DTLS13
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_client_method(void);
WOLFSSL_API WOLFSSL_METHOD *wolfDTLSv1_3_server_method(void);
#endif
#endif
#ifdef HAVE_POLY1305
@@ -1298,6 +1311,8 @@ WOLFSSL_API int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl);
#define wolfSSL_get_using_nonblock wolfSSL_dtls_get_using_nonblock
/* The old names are deprecated. */
WOLFSSL_API int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_dtls13_use_quick_timeout(WOLFSSL* ssl);
WOLFSSL_API void wolfSSL_dtls13_set_send_more_acks(WOLFSSL* ssl, int value);
WOLFSSL_API int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl,
WOLFSSL_TIMEVAL* timeleft);
WOLFSSL_API void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl,
@@ -2995,6 +3010,7 @@ enum {
WOLFSSL_TLSV1_3 = 4,
WOLFSSL_DTLSV1 = 5,
WOLFSSL_DTLSV1_2 = 6,
WOLFSSL_DTLSV1_3 = 7,
WOLFSSL_USER_CA = 1, /* user added as trusted */
WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */

View File

@@ -350,6 +350,10 @@
#endif
#endif
#ifndef DEFAULT_TIMEOUT_SEC
#define DEFAULT_TIMEOUT_SEC 2
#endif
/* all certs relative to wolfSSL home directory now */
#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
#define caCertFile "certs/ca-cert.pem"
@@ -5299,6 +5303,67 @@ static WC_INLINE void EarlyDataStatus(WOLFSSL* ssl)
}
#endif /* WOLFSSL_EARLY_DATA */
#if defined(HAVE_SESSION_TICKET) || defined (WOLFSSL_DTLS13)
static WC_INLINE int process_handshake_messages(WOLFSSL* ssl, int blocking,
int* zero_return)
{
int timeout = DEFAULT_TIMEOUT_SEC;
char foo[1];
int ret = 0;
int dtls;
(void)dtls;
if (zero_return == NULL || ssl == NULL)
return -1;
dtls = wolfSSL_dtls(ssl);
*zero_return = 0;
if (!blocking) {
#ifdef WOLFSSL_DTLS
if (dtls) {
timeout = wolfSSL_dtls_get_current_timeout(ssl);
#ifdef WOLFSSL_DTLS13
if (timeout > 4 && wolfSSL_dtls13_use_quick_timeout(ssl))
timeout /= 4;
#endif /* WOLFSSL_DTLS13 */
}
#endif /* WOLFSSL_DTLS */
ret = tcp_select(wolfSSL_get_fd(ssl), timeout);
if (ret == TEST_ERROR_READY) {
err_sys("tcp_select error");
return -1;
}
if (ret == TEST_TIMEOUT) {
#ifdef WOLFSSL_DTLS
if (dtls) {
ret = wolfSSL_dtls_got_timeout(ssl);
if (ret != WOLFSSL_SUCCESS && !wolfSSL_want_write(ssl) &&
!wolfSSL_want_read(ssl)) {
err_sys("got timeout error");
return -1;
}
}
#endif /* WOLFSSL_DTLS */
/* do the peek to detect if the peer closed the connection*/
}
}
ret = wolfSSL_peek(ssl, foo, 0);
if (ret < 0 && !wolfSSL_want_read(ssl) && !wolfSSL_want_write(ssl)) {
ret = wolfSSL_get_error(ssl, ret);
if (ret == WOLFSSL_ERROR_ZERO_RETURN)
*zero_return = 1;
return -1;
}
return 0;
}
#endif /* HAVE_SESSION_TICKET || WOLFSSL_DTLS13 */
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
defined(DEBUG_UNIT_TEST_CERTS)

View File

@@ -2700,6 +2700,22 @@ extern void uITRON4_free(void *p) ;
#define NO_SESSION_CACHE_REF
#endif
/* DTLS v1.3 requires 64-bit number wrappers */
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_W64_WRAPPER)
#define WOLFSSL_W64_WRAPPER
#endif
/* DTLS v1.3 requires AES ECB if using AES */
#if defined(WOLFSSL_DTLS13) && !defined(NO_AES) && \
!defined(WOLFSSL_AES_DIRECT)
#define WOLFSSL_AES_DIRECT
#endif
#if defined(WOLFSSL_DTLS13) && (!defined(WOLFSSL_DTLS) || \
!defined(WOLFSSL_TLS13))
#error "DTLS v1.3 requires both WOLFSSL_TLS13 and WOLFSSL_DTLS"
#endif
/* ---------------------------------------------------------------------------
* Depricated Algorithm Handling

View File

@@ -218,6 +218,14 @@ decouple library dependencies with standard string, memory and so on.
mp_digit, no 64 bit type so make mp_digit 16 bit */
#endif
typedef struct w64wrapper {
#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_W64_WRAPPER_TEST)
word64 n;
#else
word32 n[2];
#endif /* WORD64_AVAILABLE && WOLFSSL_W64_WRAPPER_TEST */
} w64wrapper;
#ifdef WC_PTR_TYPE /* Allow user suppied type */
typedef WC_PTR_TYPE wc_ptr_t;
#elif defined(HAVE_UINTPTR_T)