Skip to content

Commit 476a56d

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 437bca8 commit 476a56d

46 files changed

Lines changed: 3007 additions & 210 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
@@ -53,17 +53,20 @@ if [ "$#" -lt 2 ]; then
5353
exit 1
5454
fi
5555

56-
# Use unique benchmark port so it won't conflict with any other tests
57-
bench_port=11113
56+
# Bind an ephemeral port and read it back from the ready file below, rather
57+
# than hoping a fixed number is free. The ready file is per-run for the same
58+
# reason - a fixed path is shared by any concurrent run.
59+
bench_port=0
60+
ready_file=/tmp/wolfssl_server_ready$$
5861
no_pid=-1
5962
server_pid=$no_pid
6063
counter=0
6164
client_result=-1
6265

6366
remove_ready_file() {
64-
if test -e /tmp/wolfssl_server_ready; then
67+
if test -e "$ready_file"; then
6568
echo "removing existing server_ready file"
66-
rm /tmp/wolfssl_server_ready
69+
rm "$ready_file"
6770
fi
6871
}
6972

@@ -96,27 +99,39 @@ remove_ready_file
9699
if [ $1 -eq 1 ]
97100
then
98101
# start server in loop mode with port
99-
./examples/server/server -i -p $bench_port $4 &
102+
./examples/server/server -i -p $bench_port -R "$ready_file" $4 &
100103
server_pid=$!
101104
fi
102105

103106
# benchmark throughput
104107
if [ $1 -eq 2 ]
105108
then
106109
# start server in loop mode, non-blocking, benchmark throughput with port
107-
./examples/server/server -i -N -B $2 -p $bench_port $4 &
110+
./examples/server/server -i -N -B $2 -p $bench_port -R "$ready_file" $4 &
108111
server_pid=$!
109112
fi
110113

111114
# NOTE: We sleep for 2 seconds below. If timing the execution of this script
112115
# with "time", bear in mind that those 2 seconds will be reflected in
113116
# the "real" time.
114117
echo "Waiting for server_ready file..."
115-
while [ ! -s /tmp/wolfssl_server_ready -a "$counter" -lt 20 ]; do
118+
while [ ! -s "$ready_file" -a "$counter" -lt 20 ]; do
116119
sleep 0.1
117120
counter=$((counter+ 1))
118121
done
119122

123+
if [ ! -s "$ready_file" ]; then
124+
echo "Server never reported a port!"
125+
do_cleanup
126+
exit 1
127+
fi
128+
129+
# sleep for an additional 0.1 to mitigate race on write/read of $ready_file:
130+
sleep 0.1
131+
132+
bench_port=$(cat "$ready_file")
133+
echo "Server listening on port $bench_port"
134+
120135
# benchmark connections
121136
if [ $1 -eq 1 ]
122137
then

0 commit comments

Comments
 (0)