Skip to content

Commit 30c8aea

Browse files
committed
Regression testing fixes
Fix guard around inclunde of chacha20_poly1305.h in internal.h for when session ticket is not ChaCha20-Poly1305. Fix port allocation and readiness testing in scripts. Fix other issues in the scripts as well. Update test.h code around ready file. For LTO compiles, all functions must be used. Make sure the assembly functions are marked as 'used' when not called internally. Fix a race in the example client that intermittently failed scripts/unit.test on TLS 1.3 non-blocking session resumption. RISC-V 64-bit: s0 needed but functions need to omit frame pointer. Have source matching generated code again.
1 parent c5c63c0 commit 30c8aea

46 files changed

Lines changed: 3006 additions & 211 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cmake/functions.cmake

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,10 @@ function(generate_lib_src_list LIB_SOURCES)
468468

469469
if(BUILD_AESNI)
470470
list(APPEND LIB_SOURCES wolfcrypt/src/aes_asm.S)
471+
# 32-bit x86 AES-XTS. The file guards its own contents on
472+
# WOLFSSL_AES_XTS and WOLFSSL_X86_BUILD, so it compiles to
473+
# nothing on any other target or without XTS.
474+
list(APPEND LIB_SOURCES wolfcrypt/src/aes_xts_x86_asm.S)
471475

472476
if(BUILD_INTELASM)
473477
list(APPEND LIB_SOURCES wolfcrypt/src/aes_gcm_asm.S)
@@ -914,9 +918,13 @@ function(generate_lib_src_list LIB_SOURCES)
914918
endif()
915919

916920
if(NOT BUILD_FIPS_V2 AND BUILD_AESNI)
921+
# aes_xts_x86_asm.S guards its own contents on WOLFSSL_AES_XTS and
922+
# WOLFSSL_X86_BUILD, so it compiles to nothing on any other target
923+
# or without XTS.
917924
list(APPEND LIB_SOURCES
918925
wolfcrypt/src/aes_asm.S
919-
wolfcrypt/src/aes_gcm_asm.S)
926+
wolfcrypt/src/aes_gcm_asm.S
927+
wolfcrypt/src/aes_xts_x86_asm.S)
920928
endif()
921929

922930
if(BUILD_CAMELLIA)

configure.ac

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,10 +1215,13 @@ if (test "$host_cpu" = "x86_64" || test "$host_cpu" = "amd64") &&
12151215
then
12161216
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_X86_64_BUILD"
12171217
fi
1218-
if test "$host_cpu" = "x86"
1219-
then
1218+
# config.sub normalises 32-bit x86 to i386/i486/i586/i686, so matching only
1219+
# "x86" never fires for a real host triple.
1220+
case "$host_cpu" in
1221+
x86 | i?86)
12201222
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_X86_BUILD"
1221-
fi
1223+
;;
1224+
esac
12221225

12231226

12241227
AC_ARG_ENABLE([leanpsk],
@@ -4801,11 +4804,12 @@ then
48014804
then
48024805
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_X86_64_BUILD"
48034806
fi
4804-
if test "$host_cpu" = "x86"
4805-
then
4807+
case "$host_cpu" in
4808+
x86 | i?86)
48064809
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_X86_BUILD"
48074810
ENABLED_X86_ASM=yes
4808-
fi
4811+
;;
4812+
esac
48094813
fi
48104814
AC_SUBST([ENABLED_AESNI])
48114815
AC_SUBST([ENABLED_AESNI_WITH_AVX])

examples/client/client.c

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ static const char *wolfsentry_config_path = NULL;
8989
#ifndef MAX_NON_BLOCK_SEC
9090
#define MAX_NON_BLOCK_SEC 10
9191
#endif
92+
/* How long a single wait for the socket blocks before the loop re-checks its
93+
* overall budget. Short enough that the budget is still honoured closely. */
94+
#define NON_BLOCK_POLL_SEC 1
9295

9396
#define OCSP_STAPLING 1
9497
#define OCSP_STAPLINGV2 2
@@ -1124,12 +1127,28 @@ static int ClientWrite(WOLFSSL* ssl, const char* msg, int msgSz, const char* str
11241127
return err;
11251128
}
11261129

1127-
static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
1128-
const char* str, int exitWithRet)
1130+
/* Read a reply. On a non-blocking socket a WANT_READ only means the reply has
1131+
* not arrived yet, so wait for it rather than returning on the first poll -
1132+
* returning early lets the caller shut the connection down while the peer is
1133+
* still writing, which the peer then reports as a transport error.
1134+
*
1135+
* replyRequired says whether a missing reply is a failure, not whether one is
1136+
* worth waiting for: it selects the wait budget and controls whether giving up
1137+
* is reported as an error. */
1138+
static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen,
1139+
int replyRequired, const char* str, int exitWithRet)
11291140
{
11301141
int ret, err;
11311142
char buffer[WOLFSSL_MAX_ERROR_SZ];
11321143
double start = current_time(1), elapsed;
1144+
/* A required reply gets the full non-blocking budget, an optional one the
1145+
* shorter of the two - MAX_NON_BLOCK_SEC is overridable and may be set
1146+
* below DEFAULT_TIMEOUT_SEC, which would otherwise invert the two. */
1147+
double maxWait = MAX_NON_BLOCK_SEC;
1148+
1149+
if (!replyRequired && DEFAULT_TIMEOUT_SEC < MAX_NON_BLOCK_SEC) {
1150+
maxWait = DEFAULT_TIMEOUT_SEC;
1151+
}
11331152

11341153
do {
11351154
err = 0; /* reset error */
@@ -1158,17 +1177,49 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
11581177
}
11591178
}
11601179

1161-
if (mustRead &&
1162-
(err == WOLFSSL_ERROR_WANT_READ
1163-
|| err == WOLFSSL_ERROR_WANT_WRITE)) {
1180+
if (err == WOLFSSL_ERROR_WANT_READ
1181+
|| err == WOLFSSL_ERROR_WANT_WRITE) {
1182+
int selectRet;
1183+
11641184
elapsed = current_time(0) - start;
1165-
if (elapsed > MAX_NON_BLOCK_SEC) {
1166-
LOG_ERROR("Nonblocking read timeout\n");
1185+
if (elapsed > maxWait) {
1186+
if (replyRequired) {
1187+
LOG_ERROR("Nonblocking read timeout\n");
1188+
}
1189+
ret = WOLFSSL_FATAL_ERROR;
1190+
break;
1191+
}
1192+
1193+
/* Wait for the socket instead of spinning on it. */
1194+
if (err == WOLFSSL_ERROR_WANT_WRITE) {
1195+
selectRet = tcp_select_tx(wolfSSL_get_fd(ssl),
1196+
NON_BLOCK_POLL_SEC);
1197+
}
1198+
else {
1199+
selectRet = tcp_select(wolfSSL_get_fd(ssl),
1200+
NON_BLOCK_POLL_SEC);
1201+
}
1202+
1203+
#ifdef WOLFSSL_DTLS
1204+
/* A DTLS timeout means the peer's datagram was lost - let the
1205+
* library retransmit rather than waiting for something that is
1206+
* never coming (see NonBlockingSSL_Connect). */
1207+
if (selectRet == TEST_TIMEOUT && wolfSSL_dtls(ssl)) {
1208+
if (wolfSSL_dtls_got_timeout(ssl) != WOLFSSL_SUCCESS) {
1209+
err = wolfSSL_get_error(ssl, WOLFSSL_FATAL_ERROR);
1210+
break;
1211+
}
1212+
}
1213+
else
1214+
#endif
1215+
/* select() itself failed - retrying would spin, not wait. */
1216+
if (selectRet == TEST_SELECT_FAIL) {
1217+
LOG_ERROR("%s tcp_select error\n", str);
11671218
ret = WOLFSSL_FATAL_ERROR;
11681219
break;
11691220
}
11701221
}
1171-
} while ((mustRead && err == WOLFSSL_ERROR_WANT_READ)
1222+
} while (err == WOLFSSL_ERROR_WANT_READ
11721223
|| err == WOLFSSL_ERROR_WANT_WRITE
11731224
#ifdef WOLFSSL_ASYNC_CRYPT
11741225
|| err == WC_NO_ERR_TRACE(WC_PENDING_E)
@@ -1183,11 +1234,15 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
11831234
return err;
11841235
}
11851236

1237+
/* replyRequired: whether a missing reply fails the exchange. See ClientRead. */
11861238
static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
1187-
char* reply, int replyLen, int mustRead,
1239+
char* reply, int replyLen, int replyRequired,
11881240
const char* str, int exitWithRet)
11891241
{
11901242
int ret = 0;
1243+
/* Which half of the exchange the error below came from - the message used
1244+
* to say SSL_write for a failure returned by ClientRead. */
1245+
const char* stage = "SSL_write";
11911246

11921247
do {
11931248
ret = ClientWrite(ssl, msg, msgSz, str, exitWithRet);
@@ -1207,15 +1262,17 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
12071262
}
12081263
else {
12091264
LOG_ERROR("%s tcp_select error\n", str);
1265+
stage = "tcp_select";
12101266
if (!exitWithRet)
12111267
err_sys("tcp_select failed");
12121268
else
12131269
ret = WOLFSSL_FATAL_ERROR;
12141270
break;
12151271
}
12161272
}
1217-
ret = ClientRead(ssl, reply, replyLen, mustRead, str, exitWithRet);
1218-
if (mustRead && ret != 0) {
1273+
stage = "SSL_read";
1274+
ret = ClientRead(ssl, reply, replyLen, replyRequired, str, exitWithRet);
1275+
if (replyRequired && ret != 0) {
12191276
if (!exitWithRet)
12201277
err_sys("ClientRead failed");
12211278
else
@@ -1224,9 +1281,11 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
12241281
break;
12251282
} while (1);
12261283

1227-
if (ret != 0) {
1284+
/* A failed optional read is not an error - the caller asked for the reply
1285+
* only if one turned up - so do not log one. */
1286+
if (ret != 0 && (replyRequired || XSTRCMP(stage, "SSL_read") != 0)) {
12281287
char buffer[WOLFSSL_MAX_ERROR_SZ];
1229-
LOG_ERROR("SSL_write%s msg error %d, %s\n", str, ret,
1288+
LOG_ERROR("%s%s msg error %d, %s\n", stage, str, ret,
12301289
wolfSSL_ERR_error_string((unsigned long)ret, buffer));
12311290
}
12321291

scripts/benchmark.test

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,20 @@ if [ "$#" -lt 2 ]; then
4242
exit 1
4343
fi
4444

45-
# Use unique benchmark port so it won't conflict with any other tests
46-
bench_port=11113
45+
# Bind an ephemeral port and read it back from the ready file below, rather
46+
# than hoping a fixed number is free. The ready file is per-run for the same
47+
# reason - a fixed path is shared by any concurrent run.
48+
bench_port=0
49+
ready_file=/tmp/wolfssl_server_ready$$
4750
no_pid=-1
4851
server_pid=$no_pid
4952
counter=0
5053
client_result=-1
5154

5255
remove_ready_file() {
53-
if test -e /tmp/wolfssl_server_ready; then
56+
if test -e "$ready_file"; then
5457
echo "removing existing server_ready file"
55-
rm /tmp/wolfssl_server_ready
58+
rm "$ready_file"
5659
fi
5760
}
5861

@@ -85,27 +88,39 @@ remove_ready_file
8588
if [ $1 -eq 1 ]
8689
then
8790
# start server in loop mode with port
88-
./examples/server/server -i -p $bench_port $4 &
91+
./examples/server/server -i -p $bench_port -R "$ready_file" $4 &
8992
server_pid=$!
9093
fi
9194

9295
# benchmark throughput
9396
if [ $1 -eq 2 ]
9497
then
9598
# start server in loop mode, non-blocking, benchmark throughput with port
96-
./examples/server/server -i -N -B $2 -p $bench_port $4 &
99+
./examples/server/server -i -N -B $2 -p $bench_port -R "$ready_file" $4 &
97100
server_pid=$!
98101
fi
99102

100103
# NOTE: We sleep for 2 seconds below. If timing the execution of this script
101104
# with "time", bear in mind that those 2 seconds will be reflected in
102105
# the "real" time.
103106
echo "Waiting for server_ready file..."
104-
while [ ! -s /tmp/wolfssl_server_ready -a "$counter" -lt 20 ]; do
107+
while [ ! -s "$ready_file" -a "$counter" -lt 20 ]; do
105108
sleep 0.1
106109
counter=$((counter+ 1))
107110
done
108111

112+
if [ ! -s "$ready_file" ]; then
113+
echo "Server never reported a port!"
114+
do_cleanup
115+
exit 1
116+
fi
117+
118+
# sleep for an additional 0.1 to mitigate race on write/read of $ready_file:
119+
sleep 0.1
120+
121+
bench_port=$(cat "$ready_file")
122+
echo "Server listening on port $bench_port"
123+
109124
# benchmark connections
110125
if [ $1 -eq 1 ]
111126
then

0 commit comments

Comments
 (0)