Fixes for sniffer handling of TCP spurious retransmission (#4372)

* Fix for sniffer to better handle spurious retransmission edge case. ZD 12852

* Fix for sniffer to not send alerts during application data processing.

* Fix for missing semi-colon on XFREE.

* Fix for `bench_stats_print` with stack variable name used in `bench_ecc`. Improve benchmark thread cleanup, CPU count calcuation and stat blocking logic.
This commit is contained in:
David Garske
2021-09-07 16:40:58 -07:00
committed by GitHub
parent 078e0a7379
commit b6665df6a8
5 changed files with 75 additions and 51 deletions

View File

@@ -15803,7 +15803,7 @@ int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int macSz,
#endif
int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff)
{
word32 msgSz = ssl->keys.encryptSz;
word32 idx = *inOutIdx;
@@ -15831,7 +15831,9 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
}
if (!process) {
WOLFSSL_MSG("Received App data before a handshake completed");
SendAlert(ssl, alert_fatal, unexpected_message);
if (sniff == NO_SNIFF) {
SendAlert(ssl, alert_fatal, unexpected_message);
}
return OUT_OF_ORDER_E;
}
}
@@ -15839,7 +15841,9 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
#endif
if (ssl->options.handShakeDone == 0) {
WOLFSSL_MSG("Received App data before a handshake completed");
SendAlert(ssl, alert_fatal, unexpected_message);
if (sniff == NO_SNIFF) {
SendAlert(ssl, alert_fatal, unexpected_message);
}
return OUT_OF_ORDER_E;
}
@@ -15862,13 +15866,17 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
#endif
if (dataSz < 0) {
WOLFSSL_MSG("App data buffer error, malicious input?");
SendAlert(ssl, alert_fatal, unexpected_message);
if (sniff == NO_SNIFF) {
SendAlert(ssl, alert_fatal, unexpected_message);
}
return BUFFER_ERROR;
}
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData > early_data_ext) {
if (ssl->earlyDataSz + dataSz > ssl->options.maxEarlyDataSz) {
SendAlert(ssl, alert_fatal, unexpected_message);
if (sniff == NO_SNIFF) {
SendAlert(ssl, alert_fatal, unexpected_message);
}
return WOLFSSL_FATAL_ERROR;
}
ssl->earlyDataSz += dataSz;
@@ -17168,8 +17176,8 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
#endif
if ((ret = DoApplicationData(ssl,
ssl->buffers.inputBuffer.buffer,
&ssl->buffers.inputBuffer.idx))
!= 0) {
&ssl->buffers.inputBuffer.idx,
NO_SNIFF)) != 0) {
WOLFSSL_ERROR(ret);
return ret;
}

View File

@@ -4796,8 +4796,13 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
}
}
}
else
return 1;
else {
/* This can happen with out of order packets, or possible spurious
* retransmission. If packet has data attempt to process packet */
if (*sslBytes == 0) {
return 1;
}
}
}
else if (real > *expected) {
Trace(OUT_OF_ORDER_STR);
@@ -5306,6 +5311,16 @@ doMessage:
recordEnd = sslFrame + rhSize; /* may have more than one record */
inRecordEnd = recordEnd;
/* Make sure cipher is on for client, if we get an application data packet
* and handhsake is done for server. This workaround is required if client
* handshake packets were missed, retransmitted or sent out of order. */
if ((enum ContentType)rh.type == application_data &&
ssl->options.handShakeDone && session->flags.serverCipherOn) {
session->flags.clientCipherOn = 1;
session->sslClient->options.handShakeState = HANDSHAKE_DONE;
session->sslClient->options.handShakeDone = 1;
}
/* decrypt if needed */
if ((session->flags.side == WOLFSSL_SERVER_END &&
session->flags.serverCipherOn)
@@ -5401,7 +5416,7 @@ doPart:
{
word32 inOutIdx = 0;
ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx);
ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx, SNIFF);
if (ret == 0) {
ret = ssl->buffers.clearOutputBuffer.length;
TraceGotData(ret);

View File

@@ -33181,7 +33181,7 @@ WOLFSSL_API int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa,
}
if (ret < 0 && preAllocated == 0) {
XFREE(*out, key->heap, DYNAMIC_TYPE_OPENSSL)
XFREE(*out, key->heap, DYNAMIC_TYPE_OPENSSL);
}
WOLFSSL_LEAVE("wolfSSL_i2d_DSAparams", ret);

View File

@@ -1072,10 +1072,13 @@ typedef enum bench_stat_type {
BENCH_STAT_SYM,
} bench_stat_type_t;
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING)
#ifndef BENCH_MAX_NAME_SZ
#define BENCH_MAX_NAME_SZ 24
#endif
typedef struct bench_stats {
struct bench_stats* next;
struct bench_stats* prev;
const char* algo;
char algo[BENCH_MAX_NAME_SZ]; /* may not be static, so make copy */
const char* desc;
double perfsec;
int strength;
@@ -1101,7 +1104,10 @@ typedef enum bench_stat_type {
/* locate existing in list */
for (bstat = bench_stats_head; bstat != NULL; bstat = bstat->next) {
/* match based on algo, strength and desc */
if (bstat->algo == algo && bstat->strength == strength && bstat->desc == desc && bstat->doAsync == doAsync) {
if (XSTRNCMP(bstat->algo, algo, BENCH_MAX_NAME_SZ) == 0 &&
bstat->strength == strength &&
bstat->desc == desc &&
bstat->doAsync == doAsync) {
break;
}
}
@@ -1124,10 +1130,9 @@ typedef enum bench_stat_type {
bench_stats_tail = bstat; /* add to the end either way */
}
}
if (bstat) {
bstat->type = type;
bstat->algo = algo;
XSTRNCPY(bstat->algo, algo, BENCH_MAX_NAME_SZ);
bstat->strength = strength;
bstat->desc = desc;
bstat->doAsync = doAsync;
@@ -1136,17 +1141,8 @@ typedef enum bench_stat_type {
bstat->perftype = perftype;
if (bstat->lastRet > ret)
bstat->lastRet = ret; /* track last error */
pthread_mutex_unlock(&bench_lock);
/* wait until remaining are complete */
while (bstat->finishCount < g_threadCount) {
wc_AsyncThreadYield();
}
}
else {
pthread_mutex_unlock(&bench_lock);
}
pthread_mutex_unlock(&bench_lock);
return bstat;
}
@@ -2018,28 +2014,10 @@ exit:
XFREE(bench_iv, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
#endif
#ifdef WOLF_CRYPTO_CB
#ifdef HAVE_INTEL_QA_SYNC
wc_CryptoCb_CleanupIntelQa(&devId);
#endif
#ifdef HAVE_CAVIUM_OCTEON_SYNC
wc_CryptoCb_CleanupOcteon(&devId);
#endif
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
/* free event queue */
wolfEventQueue_Free(&eventQueue);
#endif
#if defined(HAVE_LOCAL_RNG)
wc_FreeRng(&gRng);
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
wolfAsync_DevClose(&devId);
#endif
/* cleanup the thread if fixed point cache is enabled and have thread local */
#if defined(HAVE_THREAD_LS) && defined(HAVE_ECC) && defined(FP_ECC)
wc_ecc_fp_free();
@@ -2104,6 +2082,29 @@ int benchmark_free(void)
{
int ret;
if (gPrintStats || devId != INVALID_DEVID) {
bench_stats_print();
}
bench_stats_free();
#ifdef WOLF_CRYPTO_CB
#ifdef HAVE_INTEL_QA_SYNC
wc_CryptoCb_CleanupIntelQa(&devId);
#endif
#ifdef HAVE_CAVIUM_OCTEON_SYNC
wc_CryptoCb_CleanupOcteon(&devId);
#endif
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
/* free event queue */
wolfEventQueue_Free(&eventQueue);
/* close device */
wolfAsync_DevClose(&devId);
#endif
#ifdef HAVE_WNR
ret = wc_FreeNetRandom();
if (ret < 0) {
@@ -2111,12 +2112,6 @@ int benchmark_free(void)
}
#endif
if (gPrintStats || devId != INVALID_DEVID) {
bench_stats_print();
}
bench_stats_free();
if ((ret = wolfCrypt_Cleanup()) != 0) {
printf("error %d with wolfCrypt_Cleanup\n", ret);
}
@@ -2152,8 +2147,14 @@ int benchmark_test(void *args)
g_threadCount = WC_ASYNC_BENCH_THREAD_COUNT;
#else
g_threadCount = wc_AsyncGetNumberOfCpus();
if (g_threadCount > 0) {
g_threadCount /= 2; /* use physical core count */
}
#endif
}
if (g_threadCount <= 0) {
g_threadCount = 1;
}
printf("CPUs: %d\n", g_threadCount);
@@ -5497,7 +5498,6 @@ void bench_eccMakeKey(int doAsync, int curveId)
double start;
const char**desc = bench_desc_words[lng_index];
#ifdef WOLFSSL_ASYNC_CRYPT
deviceID = doAsync ? devId : INVALID_DEVID;
#else

View File

@@ -1749,7 +1749,8 @@ WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_LOCAL int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 size, word32 totalSz, int sniff);
#endif
WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx);
WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx,
int sniff);
/* TLS v1.3 needs these */
WOLFSSL_LOCAL int HandleTlsResumption(WOLFSSL* ssl, int bogusID,
Suites* clSuites);