From 29c120356ecfdb9e7f6e0d72313ea3450084384c Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 21 Mar 2022 12:05:08 -0700 Subject: [PATCH] Sniffer asynchronous support. * Adds stateful handling of DH shared secret computation in `SetupKeys`. * Improved the decrypt handling to use internal functions and avoid generating alerts on failures. * Fix for sniffer resume due to missing `sessionIDSz` broken in #4807. * Fix sniffer test cases to split resume (session_ticket) tests. * Add `snifftest` list of build features so test script can gate running resume test. --- scripts/include.am | 3 + scripts/sniffer-testsuite.test | 78 +- scripts/sniffer-tls13-dh-resume.pcap | Bin 0 -> 35123 bytes scripts/sniffer-tls13-dh.pcap | Bin 64220 -> 24008 bytes scripts/sniffer-tls13-ecc-resume.pcap | Bin 0 -> 33707 bytes scripts/sniffer-tls13-ecc.pcap | Bin 62868 -> 23798 bytes scripts/sniffer-tls13-gen.sh | 94 +- scripts/sniffer-tls13-hrr.pcap | Bin 8789 -> 8447 bytes scripts/sniffer-tls13-x25519-resume.pcap | Bin 0 -> 24 bytes scripts/sniffer-tls13-x25519.pcap | Bin 42925 -> 24 bytes src/internal.c | 27 +- src/sniffer.c | 1860 ++++++++++++---------- src/tls13.c | 9 +- sslSniffer/sslSnifferTest/snifftest.c | 158 +- wolfcrypt/src/wolfevent.c | 2 +- wolfssl/internal.h | 7 +- wolfssl/sniffer.h | 28 +- wolfssl/wolfcrypt/dh.h | 5 + wolfssl/wolfcrypt/error-crypt.h | 2 +- wolfssl/wolfcrypt/types.h | 1 + 20 files changed, 1409 insertions(+), 865 deletions(-) create mode 100644 scripts/sniffer-tls13-dh-resume.pcap create mode 100644 scripts/sniffer-tls13-ecc-resume.pcap create mode 100644 scripts/sniffer-tls13-x25519-resume.pcap diff --git a/scripts/include.am b/scripts/include.am index a78c8f626..5e26f4a91 100644 --- a/scripts/include.am +++ b/scripts/include.am @@ -90,8 +90,11 @@ endif EXTRA_DIST += scripts/testsuite.pcap \ scripts/sniffer-ipv6.pcap \ scripts/sniffer-tls13-dh.pcap \ + scripts/sniffer-tls13-dh-resume.pcap \ scripts/sniffer-tls13-ecc.pcap \ + scripts/sniffer-tls13-ecc-resume.pcap \ scripts/sniffer-tls13-x25519.pcap \ + scripts/sniffer-tls13-x25519-resume.pcap \ scripts/sniffer-tls13-gen.sh \ scripts/sniffer-tls13-hrr.pcap \ scripts/ping.test \ diff --git a/scripts/sniffer-testsuite.test b/scripts/sniffer-testsuite.test index a3e596892..3388be5ac 100755 --- a/scripts/sniffer-testsuite.test +++ b/scripts/sniffer-testsuite.test @@ -14,53 +14,99 @@ fi # ./configure --enable-sniffer [--enable-session-ticket] # Resumption tests require "--enable-session-ticket" +session_ticket=no +./sslSniffer/sslSnifferTest/snifftest -? 2>&1 | grep -- 'session_ticket ' +if [ $? -eq 0 ]; then + session_ticket=yes +fi +has_rsa=no +./sslSniffer/sslSnifferTest/snifftest -? 2>&1 | grep -- 'rsa ' +if [ $? -eq 0 ]; then + has_rsa=yes +fi +RESULT=0 -echo -e "\nStaring snifftest on testsuite.pcap...\n" -./sslSniffer/sslSnifferTest/snifftest ./scripts/testsuite.pcap ./certs/server-key.pem 127.0.0.1 11111 +if test $session_ticket == yes +then + # TLS v1.2 Static RSA Test + echo -e "\nStaring snifftest on testsuite.pcap...\n" + ./sslSniffer/sslSnifferTest/snifftest ./scripts/testsuite.pcap ./certs/server-key.pem 127.0.0.1 11111 -RESULT=$? -[ $RESULT -ne 0 ] && echo -e "\nsnifftest failed\n" && exit 1 + RESULT=$? + [ $RESULT -ne 0 ] && echo -e "\nsnifftest failed\n" && exit 1 +fi -# TLS v1.3 sniffer test ECC (and resumption) -if test $# -ne 0 +# TLS v1.3 sniffer test ECC +if test $RESULT -eq 0 then ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-ecc.pcap ./certs/statickeys/ecc-secp256r1.pem 127.0.0.1 11111 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 ECC\n" && exit 1 + [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 ECC failed\n" && exit 1 fi -# TLS v1.3 sniffer test DH (and resumption) -if test $# -ne 0 +# TLS v1.3 sniffer test DH +if test $RESULT -eq 0 then ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-dh.pcap ./certs/statickeys/dh-ffdhe2048.pem 127.0.0.1 11111 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 DH\n" && exit 1 + [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 DH failed\n" && exit 1 fi -# TLS v1.3 sniffer test X25519 (and resumption) -if test $# -ne 0 +# TLS v1.3 sniffer test X25519 +if test $RESULT -eq 0 then ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-x25519.pcap ./certs/statickeys/x25519.pem 127.0.0.1 11111 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 X25519\n" && exit 1 + [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 X25519 failed\n" && exit 1 +fi + +# TLS v1.3 Resumption Tests +if test $session_ticket == yes +then + # TLS v1.3 sniffer test ECC resumption + if test $RESULT -eq 0 + then + ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-ecc-resume.pcap ./certs/statickeys/ecc-secp256r1.pem 127.0.0.1 11111 + + RESULT=$? + [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 ECC failed\n" && exit 1 + fi + + # TLS v1.3 sniffer test DH + if test $RESULT -eq 0 + then + ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-dh-resume.pcap ./certs/statickeys/dh-ffdhe2048.pem 127.0.0.1 11111 + + RESULT=$? + [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 DH failed\n" && exit 1 + fi + + # TLS v1.3 sniffer test X25519 + if test $RESULT -eq 0 + then + ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-x25519-resume.pcap ./certs/statickeys/x25519.pem 127.0.0.1 11111 + + RESULT=$? + [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 X25519 failed\n" && exit 1 + fi fi # TLS v1.3 sniffer test hello_retry_request (HRR) with ECDHE -if test $# -ne 0 +if test $RESULT -eq 0 then ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-hrr.pcap ./certs/statickeys/ecc-secp256r1.pem 127.0.0.1 11111 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 HRR\n" && exit 1 + [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 HRR failed\n" && exit 1 fi # IPv6 -if test $# -ne 0 && test "x$1" = "x-6"; +if test $RESULT -eq 0 && test "x$1" = "x-6"; then echo -e "\nStaring snifftest on sniffer-ipv6.pcap...\n" ./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-ipv6.pcap ./certs/server-key.pem ::1 11111 diff --git a/scripts/sniffer-tls13-dh-resume.pcap b/scripts/sniffer-tls13-dh-resume.pcap new file mode 100644 index 0000000000000000000000000000000000000000..0bdc4b4d1eef55a318e7224b612110bda95d0948 GIT binary patch literal 35123 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%0Ax%Ym~ZvsgtmU;Y-OzE2$ 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 literal 0 HcmV?d00001 diff --git a/scripts/sniffer-tls13-dh.pcap b/scripts/sniffer-tls13-dh.pcap index f1d5d306199b5a0e6cf41a39a3a66e10f1586d4d..7a334f54a24e4fa50a3715673c07a597bba973bb 100644 GIT binary patch literal 24008 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 Vp4rxfZ7sK|n0|2dVS=ayo literal 64220 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 diff --git a/scripts/sniffer-tls13-ecc-resume.pcap b/scripts/sniffer-tls13-ecc-resume.pcap new file mode 100644 index 0000000000000000000000000000000000000000..569d8839df2bb04a109e769c8b701c8798ae7e2f GIT binary patch literal 33707 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/dev/null || exit $? + make 1>/dev/null || exit $? + echo "starting capture" + tcpdump -i lo0 -nn port 11111 -w ./scripts/sniffer-tls13-$1.pcap & + tcpdump_pid=$! + run_sequence $1 + kill $tcpdump_pid +} + +run_capture "ecc" "" +run_capture "ecc-resume" "--enable-session-ticket" +run_capture "dh" "--disable-ecc" +run_capture "dh-resume" "--disable-ecc --enable-session-ticket" +run_capture "x25519" "--enable-curve25519 --disable-dh --disable-ecc" +run_capture "x25519-resume" "--enable-curve25519 --disable-dh --disable-ecc --enable-session-ticket" +run_capture "hrr" "--disable-dh CFLAGS=-DWOLFSSL_SNIFFER_WATCH" diff --git a/scripts/sniffer-tls13-hrr.pcap b/scripts/sniffer-tls13-hrr.pcap index c9b0789672b0663ebad9eff017cf62d1aa8d494d..b174b3c86a7562571132c15bf3bcb2f4374b9b45 100644 GIT binary patch literal 8447 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 literal 8789 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 a0|OXC<3$5Uyu1M|@(5sIVE8A)zyJWxNT107 diff --git a/scripts/sniffer-tls13-x25519-resume.pcap b/scripts/sniffer-tls13-x25519-resume.pcap new file mode 100644 index 0000000000000000000000000000000000000000..348ba487622c24dc5ef8a5804cddf48abb91f02f GIT binary patch literal 24 Scmca|c+)~A1{MYcfUp5Vh642f literal 0 HcmV?d00001 diff --git a/scripts/sniffer-tls13-x25519.pcap b/scripts/sniffer-tls13-x25519.pcap index 193271282fd0117e8559342bef1769fa919b1d62..348ba487622c24dc5ef8a5804cddf48abb91f02f 100644 GIT binary patch delta 6 NcmZ2`o=IYY1ON%A0zUu% literal 42925 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

Tbmmz{nWpItbS&v;vF>m%As3rWg4nm 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 eLRloptions.dtls) + if (!ssl->options.dtls && doAlert) { SendAlert(ssl, alert_fatal, bad_record_mac); - - #ifdef WOLFSSL_DTLS_DROP_STATS + } + #ifdef WOLFSSL_DTLS_DROP_STATS + if (ssl->options.dtls) ssl->macDropCount++; - #endif /* WOLFSSL_DTLS_DROP_STATS */ + #endif /* WOLFSSL_DTLS_DROP_STATS */ } return ret; @@ -17149,10 +17150,10 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr) #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) if (ssl->options.startedETMRead) { word32 digestSz = MacSize(ssl); - ret = Decrypt(ssl, + ret = DecryptTls(ssl, in->buffer + in->idx, in->buffer + in->idx, - ssl->curSize - (word16)digestSz); + ssl->curSize - (word16)digestSz, 1); if (ret == 0) { byte invalid = 0; byte padding = (byte)-1; @@ -17188,10 +17189,10 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr) else #endif { - ret = Decrypt(ssl, + ret = DecryptTls(ssl, in->buffer + in->idx, in->buffer + in->idx, - ssl->curSize); + ssl->curSize, 1); } #else ret = DECRYPT_ERROR; @@ -17204,7 +17205,7 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr) in->buffer + in->idx, in->buffer + in->idx, ssl->curSize, - (byte*)&ssl->curRL, RECORD_HEADER_SZ); + (byte*)&ssl->curRL, RECORD_HEADER_SZ, 1); #else ret = DECRYPT_ERROR; #endif /* WOLFSSL_TLS13 */ @@ -26804,11 +26805,15 @@ int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length) if (ssl->options.tls1_3) { XMEMCPY(ssl->session->sessionID, ssl->session->ticket + length - ID_LEN, ID_LEN); + ssl->session->sessionIDSz = ID_LEN; } else #endif + { XMEMCPY(ssl->arrays->sessionID, ssl->session->ticket + length - ID_LEN, ID_LEN); + ssl->arrays->sessionIDSz = ID_LEN; + } } return 0; diff --git a/src/sniffer.c b/src/sniffer.c index 8eae315c8..44c818573 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -28,6 +28,10 @@ #include #include +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + /* xctime */ #ifndef XCTIME #define XCTIME ctime @@ -122,6 +126,7 @@ #endif #endif +#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; } #ifndef WOLFSSL_SNIFFER_TIMEOUT #define WOLFSSL_SNIFFER_TIMEOUT 900 @@ -539,6 +544,9 @@ typedef struct SnifferSession { KeyShareInfo srvKs; KeyShareInfo cliKs; #endif +#ifdef WOLFSSL_ASYNC_CRYPT + void* userCtx; +#endif } SnifferSession; @@ -603,16 +611,16 @@ static void UpdateMissedDataSessions(void) NOLOCK_ADD_TO_STAT(x,y); UNLOCK_STAT(); } while (0) #define INC_STAT(x) do { LOCK_STAT(); \ NOLOCK_INC_STAT(x); UNLOCK_STAT(); } while (0) -#endif +#endif /* WOLFSSL_SNIFFER_STATS */ -#ifdef WOLF_CRYPTO_CB +#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_ASYNC_CRYPT) static WOLFSSL_GLOBAL int CryptoDeviceId = INVALID_DEVID; #endif /* Initialize overall Sniffer */ -void ssl_InitSniffer(void) +void ssl_InitSniffer_ex(int devId) { wolfSSL_Init(); wc_InitMutex(&ServerListMutex); @@ -622,20 +630,39 @@ void ssl_InitSniffer(void) XMEMSET(&SnifferStats, 0, sizeof(SSLStats)); wc_InitMutex(&StatsMutex); #endif +#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_ASYNC_CRYPT) + CryptoDeviceId = devId; +#endif + (void)devId; +} + +void ssl_InitSniffer(void) +{ + int devId = INVALID_DEVID; + #ifdef WOLF_CRYPTO_CB #ifdef HAVE_INTEL_QA_SYNC - CryptoDeviceId = wc_CryptoCb_InitIntelQa(); - if (INVALID_DEVID == CryptoDeviceId) { + devId = wc_CryptoCb_InitIntelQa(); + if (devId == INVALID_DEVID) { printf("Couldn't init the Intel QA\n"); } #endif #ifdef HAVE_CAVIUM_OCTEON_SYNC - CryptoDeviceId = wc_CryptoCb_InitOcteon(); - if (INVALID_DEVID == CryptoDeviceId) { - printf("Couldn't init the Intel QA\n"); + devId = wc_CryptoCb_InitOcteon(); + if (devId == INVALID_DEVID) { + printf("Couldn't init the Octeon\n"); } #endif #endif +#ifdef WOLFSSL_ASYNC_CRYPT + if (wolfAsync_DevOpen(&devId) < 0) { + printf("Async device open failed\nRunning without async\n"); + devId = INVALID_DEVID; + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + (void)devId; + + ssl_InitSniffer_ex(devId); } @@ -779,12 +806,15 @@ void ssl_FreeSniffer(void) wc_FreeMutex(&ServerListMutex); #ifdef WOLF_CRYPTO_CB -#ifdef HAVE_INTEL_QA_SYNC + #ifdef HAVE_INTEL_QA_SYNC wc_CryptoCb_CleanupIntelQa(&CryptoDeviceId); -#endif -#ifdef HAVE_CAVIUM_OCTEON_SYNC + #endif + #ifdef HAVE_CAVIUM_OCTEON_SYNC wc_CryptoCb_CleanupOcteon(&CryptoDeviceId); + #endif #endif +#ifdef WOLFSSL_ASYNC_CRYPT + wolfAsync_DevClose(&CryptoDeviceId); #endif if (TraceFile) { @@ -1605,7 +1635,7 @@ static int CreateWatchSnifferServer(char* error) FreeSnifferServer(sniffer); return -1; } -#ifdef WOLF_CRYPTO_CB +#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_ASYNC_CRYPT) if (CryptoDeviceId != INVALID_DEVID) wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDeviceId); #endif @@ -1710,6 +1740,10 @@ static int SetNamedPrivateKey(const char* name, const char* address, int port, FreeSnifferServer(sniffer); return -1; } + #if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_ASYNC_CRYPT) + if (CryptoDeviceId != INVALID_DEVID) + wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDeviceId); + #endif } if (name == NULL) { @@ -2155,701 +2189,891 @@ static void ShowTlsSecrets(SnifferSession* session) } #endif /* SHOW_SECRETS */ +typedef struct { + int type; + union { + #ifndef NO_RSA + RsaKey rsa; + #endif + #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) + struct { + word32 pLen; /* modulus length */ + word32 privKeySz; + byte privKey[WC_DH_PRIV_MAX_SZ]; /* max for TLS */ + DhKey key; + } dh; + #endif + #ifdef HAVE_ECC + ecc_key ecc; + #endif + #ifdef HAVE_CURVE25519 + curve25519_key x25519; + #endif + #ifdef HAVE_CURVE448 + curve448_key x448; + #endif + } priv; + +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + union { + /* RSA is for static RSA only */ + /* DH does not use public DhKey for Agree */ + #ifdef HAVE_ECC + ecc_key ecc; + #endif + #ifdef HAVE_CURVE25519 + curve25519_key x25519; + #endif + #ifdef HAVE_CURVE448 + curve448_key x448; + #endif + } pub; +#endif + int initPriv:1; + int initPub:1; +} SnifferKey; + +typedef struct SetupKeysArgs { +#ifdef WOLFSSL_ASYNC_CRYPT + SnifferKey* key; +#else + SnifferKey key[1]; +#endif + DerBuffer* keyBuf; + int length; + byte keyBufFree:1; + byte keyLocked:1; +} SetupKeysArgs; + +static void FreeSetupKeysArgs(WOLFSSL* ssl, void* pArgs) +{ + SetupKeysArgs* args = (SetupKeysArgs*)pArgs; + + if (args == NULL) { + return; + } + (void)ssl; +#ifdef WOLFSSL_ASYNC_CRYPT + if (args->key != NULL) +#endif + { + #ifndef NO_RSA + if (args->key->type == WC_PK_TYPE_RSA) { + if (args->key->initPriv) { + wc_FreeRsaKey(&args->key->priv.rsa); + } + } + #endif + #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) + if (args->key->type == WC_PK_TYPE_DH) { + if (args->key->initPriv) { + wc_FreeDhKey(&args->key->priv.dh.key); + } + } + #endif + #ifdef HAVE_ECC + if (args->key->type == WC_PK_TYPE_ECDH) { + if (args->key->initPriv) { + wc_ecc_free(&args->key->priv.ecc); + } + if (args->key->initPub) { + wc_ecc_free(&args->key->pub.ecc); + } + } + #endif + #ifdef HAVE_CURVE25519 + if (args->key->type == WC_PK_TYPE_CURVE25519) { + if (args->key->initPriv) { + wc_curve25519_free(&args->key->priv.x25519); + } + if (args->key->initPub) { + wc_curve25519_free(&args->key->pub.x25519); + } + } + #endif + #ifdef HAVE_CURVE448 + if (args->key->type == WC_PK_TYPE_CURVE448) { + if (args->key->initPriv) { + wc_curve448_free(&args->key->priv.x448); + } + if (args->key->initPub) { + wc_curve448_free(&args->key->pub.x448); + } + } + #endif + args->key->type = WC_PK_TYPE_NONE; + args->key->initPriv = 0; args->key->initPub = 0; + +#ifdef WOLFSSL_ASYNC_CRYPT + XFREE(args->key, NULL, DYNAMIC_TYPE_SNIFFER_KEY); + args->key = NULL; +#else + XMEMSET(args->key, 0, sizeof(args->key)); +#endif + } + + if (args->keyBuf != NULL && args->keyBufFree) { + FreeDer(&args->keyBuf); + args->keyBufFree = 0; + } +} /* Process Keys */ - static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, char* error, KeyShareInfo* ksInfo) { - word32 idx = 0; + word32 idx; int ret; - DerBuffer* keyBuf = NULL; - int keyBufFree = 0; -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) - int useCurveId = 0; -#endif int devId = INVALID_DEVID; WOLFSSL_CTX* ctx = session->context->ctx; WOLFSSL* ssl = session->sslServer; -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) - if (ksInfo && ksInfo->curve_id != 0) - useCurveId = ksInfo->curve_id; -#endif -#ifdef WOLF_CRYPTO_CB - devId = CryptoDeviceId; +#ifdef WOLFSSL_ASYNC_CRYPT + SetupKeysArgs* args = (SetupKeysArgs*)ssl->async.args; + typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1]; + (void)sizeof(args_test); +#else + SetupKeysArgs args[1]; #endif - if (session->sslServer->arrays == NULL || session->sslClient->arrays == NULL) { - /* secret's have already been established and released */ - /* this can happen with secure renegotiation */ + if (session->sslServer->arrays == NULL || + session->sslClient->arrays == NULL) { + /* Secret's have already been established and released. + * This can happen with secure renegotiation. */ return 0; } -#ifndef NO_RSA - /* Static RSA */ - if (ksInfo == NULL && ssl->buffers.key) { - RsaKey key; - int length; - int keyInit = 0; - - ret = wc_InitRsaKey_ex(&key, NULL, devId); - if (ret == 0) { - keyInit = 1; - keyBuf = ssl->buffers.key; - - ret = wc_RsaPrivateKeyDecode(keyBuf->buffer, &idx, &key, - keyBuf->length); - if (ret != 0) { - #ifndef HAVE_ECC - #ifdef WOLFSSL_SNIFFER_STATS - INC_STAT(SnifferStats.sslKeyFails); - #endif - SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE); - #else - /* If we can do ECC, this isn't fatal. Not loading a key later - * will be fatal, though. */ - SetError(RSA_DECODE_STR, error, session, 0); - keyBuf = NULL; - #endif - } - } - - if (ret == 0) { - length = wc_RsaEncryptSize(&key); - if (IsTLS(session->sslServer)) { - input += 2; /* tls pre length */ - } - - if (length > *sslBytes) { - SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); - ret = -1; - } - } - - #ifdef WC_RSA_BLINDING - if (ret == 0) { - ret = wc_RsaSetRNG(&key, session->sslServer->rng); - if (ret != 0) { - SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE); - } - } - #endif - - if (ret == 0) { - session->keySz = length * WOLFSSL_BIT_SIZE; - /* length is the key size in bytes */ - session->sslServer->arrays->preMasterSz = SECRET_LEN; - - do { - #ifdef WOLFSSL_ASYNC_CRYPT - ret = wc_AsyncWait(ret, &key.asyncDev, - WC_ASYNC_FLAG_CALL_AGAIN); - #endif - if (ret >= 0) { - ret = wc_RsaPrivateDecrypt(input, length, - session->sslServer->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSz, &key); - } - } while (ret == WC_PENDING_E); - - if (ret != SECRET_LEN) { - SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE); - } - } - - if (keyInit) { - wc_FreeRsaKey(&key); - } - } -#endif /* !NO_RSA */ - -#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) - /* Static DH Key */ - if (ksInfo && ksInfo->dh_key_bits != 0 && keyBuf == NULL) { - DhKey dhKey; - #ifdef HAVE_PUBLIC_FFDHE - const DhParams* params; - #endif - word32 privKeySz = 0, p_len = 0; - byte privKey[52]; /* max for TLS */ - int keyInit = 0; - - /* try and load static ephemeral */ - #ifdef WOLFSSL_STATIC_EPHEMERAL - #ifndef SINGLE_THREADED - int keyLocked = 0; - if (ctx->staticKELockInit && - wc_LockMutex(&ctx->staticKELock) == 0) - #endif - { - #ifndef SINGLE_THREADED - keyLocked = 1; - #endif - keyBuf = ssl->staticKE.dhKey; - if (keyBuf == NULL) - keyBuf = ctx->staticKE.dhKey; - } - #endif - - ret = 0; - #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK - if (KeyCb != NULL) { - if (keyBuf == NULL) { - ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL); - if (ret == 0) - keyBufFree = 1; - } - ret = KeyCb(session, ksInfo->named_group, - session->srvKs.key, session->srvKs.key_len, - session->cliKs.key, session->cliKs.key_len, - keyBuf, KeyCbCtx, error); - if (ret != 0) { - SetError(-1, error, session, FATAL_ERROR_STATE); - } - } - #endif - if (ret == 0 && keyBuf == NULL) { - ret = BUFFER_E; - } - - #ifdef HAVE_PUBLIC_FFDHE - if (ret == 0) { - /* get DH params */ - switch (ksInfo->named_group) { - #ifdef HAVE_FFDHE_2048 - case WOLFSSL_FFDHE_2048: - params = wc_Dh_ffdhe2048_Get(); - privKeySz = 29; - break; - #endif - #ifdef HAVE_FFDHE_3072 - case WOLFSSL_FFDHE_3072: - params = wc_Dh_ffdhe3072_Get(); - privKeySz = 34; - break; - #endif - #ifdef HAVE_FFDHE_4096 - case WOLFSSL_FFDHE_4096: - params = wc_Dh_ffdhe4096_Get(); - privKeySz = 39; - break; - #endif - #ifdef HAVE_FFDHE_6144 - case WOLFSSL_FFDHE_6144: - params = wc_Dh_ffdhe6144_Get(); - privKeySz = 46; - break; - #endif - #ifdef HAVE_FFDHE_8192 - case WOLFSSL_FFDHE_8192: - params = wc_Dh_ffdhe8192_Get(); - privKeySz = 52; - break; - #endif - default: - ret = BAD_FUNC_ARG; - } - } - #endif - - if (ret == 0) { - ret = wc_InitDhKey_ex(&dhKey, NULL, devId); - if (ret == 0) - keyInit = 1; - } - if (ret == 0) { - #ifdef HAVE_PUBLIC_FFDHE - ret = wc_DhSetKey(&dhKey, - (byte*)params->p, params->p_len, - (byte*)params->g, params->g_len); - p_len = params->p_len; - #else - ret = wc_DhSetNamedKey(&dhKey, ksInfo->named_group); - if (ret == 0) { - privKeySz = wc_DhGetNamedKeyMinSize(ksInfo->named_group); - ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group, - &p_len, NULL, NULL); - } - #endif - } - if (ret == 0) { - ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey, - keyBuf->length); - } - if (ret == 0) { - ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL, - NULL); - } - - #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) - if (keyLocked) { - wc_UnLockMutex(&ctx->staticKELock); - } - #endif - - if (ret == 0) { - /* Derive secret from private key and peer's public key */ - do { - #ifdef WOLFSSL_ASYNC_CRYPT - ret = wc_AsyncWait(ret, &dhKey.asyncDev, - WC_ASYNC_FLAG_CALL_AGAIN); - #endif - if (ret >= 0) { - PRIVATE_KEY_UNLOCK(); - ret = wc_DhAgree(&dhKey, - session->sslServer->arrays->preMasterSecret, - &session->sslServer->arrays->preMasterSz, - privKey, privKeySz, - input, *sslBytes); - PRIVATE_KEY_LOCK(); - } - } while (ret == WC_PENDING_E); - } - - if (keyInit) - wc_FreeDhKey(&dhKey); - - #ifdef WOLFSSL_SNIFFER_STATS - if (ret != 0) - INC_STAT(SnifferStats.sslKeyFails); - #endif - - /* left-padded with zeros up to the size of the prime */ - if (ret == 0 && p_len > session->sslServer->arrays->preMasterSz) { - word32 diff = p_len - session->sslServer->arrays->preMasterSz; - XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff, - session->sslServer->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSz); - XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff); - session->sslServer->arrays->preMasterSz = p_len; - } - } -#endif /* !NO_DH && WOLFSSL_DH_EXTRA */ - -#ifdef HAVE_ECC - /* Static ECC Key */ - if (useCurveId >= 0 && keyBuf == NULL - #ifdef HAVE_CURVE25519 - && useCurveId != ECC_X25519 - #endif - #ifdef HAVE_CURVE448 - && useCurveId != ECC_X448 - #endif - ) { - ecc_key key, pubKey; - int length, keyInit = 0, pubKeyInit = 0; - - /* try and load static ephemeral */ - #ifdef WOLFSSL_STATIC_EPHEMERAL - #ifndef SINGLE_THREADED - int keyLocked = 0; - if (ctx->staticKELockInit && - wc_LockMutex(&ctx->staticKELock) == 0) - #endif - { - #ifndef SINGLE_THREADED - keyLocked = 1; - #endif - keyBuf = ssl->staticKE.ecKey; - if (keyBuf == NULL) - keyBuf = ctx->staticKE.ecKey; - } - #endif - - /* try static ECC */ - if (keyBuf == NULL) { - keyBuf = session->sslServer->buffers.key; - } - - ret = 0; - #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK - if (KeyCb != NULL && ksInfo) { - if (keyBuf == NULL) { - ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL); - if (ret == 0) - keyBufFree = 1; - } - ret = KeyCb(session, ksInfo->named_group, - session->srvKs.key, session->srvKs.key_len, - session->cliKs.key, session->cliKs.key_len, - keyBuf, KeyCbCtx, error); - if (ret != 0) { - SetError(-1, error, session, FATAL_ERROR_STATE); - } - } - #endif - - if (ret == 0 && keyBuf == NULL) { - ret = BUFFER_E; - } - if (ret == 0) { - ret = wc_ecc_init_ex(&key, NULL, devId); - if (ret == 0) - keyInit = 1; - } - #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ - (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ - !defined(HAVE_SELFTEST) - if (ret == 0) { - ret = wc_ecc_set_rng(&key, session->sslServer->rng); - } - #endif - if (ret == 0) { - idx = 0; - ret = wc_EccPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length); - if (ret != 0) { - SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE); - } - } - - #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) - if (keyLocked) { - wc_UnLockMutex(&ctx->staticKELock); - } - #endif - - if (ret == 0) { - length = wc_ecc_size(&key) * 2 + 1; - /* The length should be 2 times the key size (x and y), plus 1 - * for the type byte. */ - if (!IsAtLeastTLSv1_3(session->sslServer->version)) { - input += 1; /* Don't include the TLS length for the key. */ - } - - if (length > *sslBytes) { - SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); - ret = -1; - } - - /* if curve not provided in key share data, then use private key curve */ - if (useCurveId == 0 && key.dp) { - useCurveId = key.dp->id; - } - } - if (ret == 0) { - ret = wc_ecc_init(&pubKey); - if (ret == 0) - pubKeyInit = 1; - } - if (ret == 0) { - ret = wc_ecc_import_x963_ex(input, length, &pubKey, useCurveId); - if (ret != 0) { - SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE); - } - } - if (ret == 0) { - session->keySz = ((length - 1) / 2) * WOLFSSL_BIT_SIZE; - /* Length is in bytes. Subtract 1 for the ECC key type. Divide - * by two as the key is in (x,y) coordinates, where x and y are - * the same size, the key size. Convert from bytes to bits. */ - session->sslServer->arrays->preMasterSz = ENCRYPT_LEN; - - do { - #ifdef WOLFSSL_ASYNC_CRYPT - ret = wc_AsyncWait(ret, &key.asyncDev, - WC_ASYNC_FLAG_CALL_AGAIN); - #endif - if (ret >= 0) { - PRIVATE_KEY_UNLOCK(); - ret = wc_ecc_shared_secret(&key, &pubKey, - session->sslServer->arrays->preMasterSecret, - &session->sslServer->arrays->preMasterSz); - PRIVATE_KEY_LOCK(); - } - } while (ret == WC_PENDING_E); - } - - #ifdef WOLFSSL_SNIFFER_STATS - if (ret != 0) - INC_STAT(SnifferStats.sslKeyFails); - #endif - - if (keyInit) - wc_ecc_free(&key); - if (pubKeyInit) - wc_ecc_free(&pubKey); - } -#endif /* HAVE_ECC */ - -#ifdef HAVE_CURVE25519 - /* Static Curve25519 Key */ - if (useCurveId == ECC_X25519) { - curve25519_key key, pubKey; - int length, keyInit = 0, pubKeyInit = 0; - - /* try and load static ephemeral */ -#ifdef WOLFSSL_STATIC_EPHEMERAL - #ifndef SINGLE_THREADED - int keyLocked = 0; - if (ctx->staticKELockInit && - wc_LockMutex(&ctx->staticKELock) == 0) - #endif - { - #ifndef SINGLE_THREADED - keyLocked = 1; - #endif - keyBuf = ssl->staticKE.x25519Key; - if (keyBuf == NULL) - keyBuf = ctx->staticKE.x25519Key; - } -#endif - - ret = 0; -#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK - if (KeyCb != NULL && ksInfo) { - if (keyBuf == NULL) { - ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL); - if (ret == 0) - keyBufFree = 1; - } - ret = KeyCb(session, ksInfo->named_group, - session->srvKs.key, session->srvKs.key_len, - session->cliKs.key, session->cliKs.key_len, - keyBuf, KeyCbCtx, error); - if (ret != 0) { - SetError(-1, error, session, FATAL_ERROR_STATE); - return ret; - } - } -#endif - - if (ret == 0 && keyBuf == NULL) { - ret = BUFFER_E; - } - if (ret == 0) { - ret = wc_curve25519_init_ex(&key, NULL, devId); - if (ret == 0) - keyInit = 1; - } - if (ret == 0) { - idx = 0; - ret = wc_Curve25519PrivateKeyDecode(keyBuf->buffer, &idx, &key, - keyBuf->length); - if (ret != 0) { - SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE); - } - } - -#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) - if (keyLocked) { - wc_UnLockMutex(&ctx->staticKELock); - } -#endif - - if (ret == 0) { - length = CURVE25519_KEYSIZE; - if (length > *sslBytes) { - SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); - ret = -1; - } - } - if (ret == 0) { - ret = wc_curve25519_init(&pubKey); - if (ret == 0) - pubKeyInit = 1; - } - if (ret == 0) { - ret = wc_curve25519_import_public_ex(input, length, &pubKey, - EC25519_LITTLE_ENDIAN); - if (ret != 0) { - SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE); - } - } - - if (ret == 0) { - /* For Curve25519 length is always 32 */ - session->keySz = CURVE25519_KEYSIZE; - session->sslServer->arrays->preMasterSz = ENCRYPT_LEN; - - ret = wc_curve25519_shared_secret_ex(&key, &pubKey, - session->sslServer->arrays->preMasterSecret, - &session->sslServer->arrays->preMasterSz, EC25519_LITTLE_ENDIAN); - } - -#ifdef WOLFSSL_SNIFFER_STATS - if (ret != 0) - INC_STAT(SnifferStats.sslKeyFails); -#endif - - if (keyInit) - wc_curve25519_free(&key); - if (pubKeyInit) - wc_curve25519_free(&pubKey); - } -#endif /* HAVE_CURVE25519 */ - -#ifdef HAVE_CURVE448 - /* Static Curve448 Key */ - if (useCurveId == ECC_X448) { - curve448_key key, pubKey; - int length, keyInit = 0, pubKeyInit = 0; - - /* try and load static ephemeral */ -#ifdef WOLFSSL_STATIC_EPHEMERAL - #ifndef SINGLE_THREADED - int keyLocked = 0; - if (ctx->staticKELockInit && - wc_LockMutex(&ctx->staticKELock) == 0) - #endif - { - #ifndef SINGLE_THREADED - keyLocked = 1; - #endif - keyBuf = ssl->staticKE.x448Key; - if (keyBuf == NULL) - keyBuf = ctx->staticKE.x448Key; - } -#endif - - ret = 0; -#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK - if (KeyCb != NULL && ksInfo) { - if (keyBuf == NULL) { - ret = AllocDer(&keyBuf, FILE_BUFFER_SIZE, PRIVATEKEY_TYPE, NULL); - if (ret == 0) - keyBufFree = 1; - } - ret = KeyCb(session, ksInfo->named_group, - session->srvKs.key, session->srvKs.key_len, - session->cliKs.key, session->cliKs.key_len, - keyBuf, KeyCbCtx, error); - if (ret != 0) { - SetError(-1, error, session, FATAL_ERROR_STATE); - return ret; - } - } -#endif - - if (ret == 0 && keyBuf == NULL) { - ret = BUFFER_E; - } - if (ret == 0) { - ret = wc_curve448_init(&key); - if (ret == 0) - keyInit = 1; - } - if (ret == 0) { - idx = 0; - ret = wc_Curve448PrivateKeyDecode(keyBuf->buffer, &idx, &key, - keyBuf->length); - if (ret != 0) { - SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE); - } - } - -#if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) - if (keyLocked) { - wc_UnLockMutex(&ctx->staticKELock); - } -#endif - - if (ret == 0) { - length = CURVE448_KEY_SIZE; - if (length > *sslBytes) { - SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); - ret = -1; - } - } - if (ret == 0) { - ret = wc_curve448_init(&pubKey); - if (ret == 0) - pubKeyInit = 1; - } - if (ret == 0) { - ret = wc_curve448_import_public_ex(input, length, &pubKey, - EC448_LITTLE_ENDIAN); - if (ret != 0) { - SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE); - } - } - - if (ret == 0) { - session->keySz = CURVE448_KEY_SIZE; - session->sslServer->arrays->preMasterSz = ENCRYPT_LEN; - - ret = wc_curve448_shared_secret_ex(&key, &pubKey, - session->sslServer->arrays->preMasterSecret, - &session->sslServer->arrays->preMasterSz, EC448_LITTLE_ENDIAN); - } - -#ifdef WOLFSSL_SNIFFER_STATS - if (ret != 0) - INC_STAT(SnifferStats.sslKeyFails); -#endif - - if (keyInit) - wc_curve448_free(&key); - if (pubKeyInit) - wc_curve448_free(&pubKey); - } -#endif /* HAVE_CURVE448 */ - - if (keyBufFree && keyBuf != NULL) { - FreeDer(&keyBuf); - } - - /* store for client side as well */ - XMEMCPY(session->sslClient->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSz); - session->sslClient->arrays->preMasterSz = - session->sslServer->arrays->preMasterSz; - -#ifdef SHOW_SECRETS - PrintSecret("pre master secret", - session->sslServer->arrays->preMasterSecret, - session->sslServer->arrays->preMasterSz); -#endif - - if (SetCipherSpecs(session->sslServer) != 0) { - SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); - return -1; - } - - if (SetCipherSpecs(session->sslClient) != 0) { - SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); - return -1; - } - -#ifdef WOLFSSL_TLS13 - /* TLS v1.3 derive handshake key */ - if (IsAtLeastTLSv1_3(session->sslServer->version)) { - ret = DeriveEarlySecret(session->sslServer); - ret += DeriveEarlySecret(session->sslClient); - ret += DeriveHandshakeSecret(session->sslServer); - ret += DeriveHandshakeSecret(session->sslClient); - ret += DeriveTls13Keys(session->sslServer, handshake_key, ENCRYPT_AND_DECRYPT_SIDE, 1); - ret += DeriveTls13Keys(session->sslClient, handshake_key, ENCRYPT_AND_DECRYPT_SIDE, 1); - #ifdef WOLFSSL_EARLY_DATA - ret += SetKeysSide(session->sslServer, DECRYPT_SIDE_ONLY); - ret += SetKeysSide(session->sslClient, DECRYPT_SIDE_ONLY); - #else - ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE); - ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE); - #endif +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState); + if (ret != WC_NOT_PENDING_E) { + /* Check for error */ + if (ret < 0) + goto exit_sk; } else #endif { - ret = MakeMasterSecret(session->sslServer); - ret += MakeMasterSecret(session->sslClient); - ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE); - ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE); - } - if (ret != 0) { - SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE); - return -1; + /* Reset state */ + ret = 0; + ssl->options.asyncState = TLS_ASYNC_BEGIN; + XMEMSET(args, 0, sizeof(SetupKeysArgs)); + #ifdef WOLFSSL_ASYNC_CRYPT + ssl->async.freeArgs = FreeSetupKeysArgs; + #endif + #ifdef WOLFSSL_ASYNC_CRYPT + args->key = (SnifferKey*)XMALLOC(sizeof(SnifferKey), NULL, + DYNAMIC_TYPE_SNIFFER_KEY); + #endif } -#ifdef SHOW_SECRETS - #ifdef WOLFSSL_TLS13 - if (!IsAtLeastTLSv1_3(session->sslServer->version)) - #endif - ShowTlsSecrets(session); +#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_ASYNC_CRYPT) + devId = CryptoDeviceId; #endif - CallConnectionCb(session); +#ifdef WOLFSSL_ASYNC_CRYPT + if (args->key == NULL) { + ERROR_OUT(MEMORY_E, exit_sk); + } +#endif + + switch (ssl->options.asyncState) { + case TLS_ASYNC_BEGIN: + { + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + int useCurveId = 0; + if (ksInfo && ksInfo->curve_id != 0) { + useCurveId = ksInfo->curve_id; + } + #endif + + #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) + if (ctx->staticKELockInit && + wc_LockMutex(&ctx->staticKELock) == 0) { + args->keyLocked = 1; + } + #endif + + #ifndef NO_RSA + /* Static RSA */ + if (ksInfo == NULL && ssl->buffers.key) { + ret = wc_InitRsaKey_ex(&args->key->priv.rsa, NULL, devId); + if (ret == 0) { + args->key->type = WC_PK_TYPE_RSA; + args->key->initPriv = 1; + args->keyBuf = ssl->buffers.key; + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfSSL_AsyncInit(ssl, &args->key->priv.rsa.asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + #endif + } + if (ret == 0) { + idx = 0; + ret = wc_RsaPrivateKeyDecode(args->keyBuf->buffer, &idx, + &args->key->priv.rsa, args->keyBuf->length); + if (ret != 0) { + #ifndef HAVE_ECC + SetError(RSA_DECODE_STR, error, session, + FATAL_ERROR_STATE); + break; + #else + /* If we can do ECC, this isn't fatal. Not loading a key + * later will be fatal, though. */ + SetError(RSA_DECODE_STR, error, session, 0); + args->keyBuf = NULL; + #endif + } + } + + if (ret == 0) { + args->length = wc_RsaEncryptSize(&args->key->priv.rsa); + if (IsTLS(session->sslServer)) { + input += 2; /* tls pre length */ + } + + if (args->length > *sslBytes) { + SetError(PARTIAL_INPUT_STR, error, session, + FATAL_ERROR_STATE); + ret = -1; + } + } + + #ifdef WC_RSA_BLINDING + if (ret == 0) { + ret = wc_RsaSetRNG(&args->key->priv.rsa, + session->sslServer->rng); + if (ret != 0) { + SetError(RSA_DECRYPT_STR, error, session, + FATAL_ERROR_STATE); + } + } + #endif + + if (ret == 0) { + session->keySz = args->length * WOLFSSL_BIT_SIZE; + /* length is the key size in bytes */ + session->sslServer->arrays->preMasterSz = SECRET_LEN; + } + } + #endif /* !NO_RSA */ + + #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) + /* Static DH Key */ + if (ksInfo && ksInfo->dh_key_bits != 0 && args->keyBuf == NULL) { + #ifdef HAVE_PUBLIC_FFDHE + const DhParams* params; + #endif + + /* try and load static ephemeral */ + #ifdef WOLFSSL_STATIC_EPHEMERAL + args->keyBuf = ssl->staticKE.dhKey; + if (args->keyBuf == NULL) + args->keyBuf = ctx->staticKE.dhKey; + #endif + + ret = 0; + #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK + if (KeyCb != NULL) { + if (args->keyBuf == NULL) { + ret = AllocDer(&args->keyBuf, FILE_BUFFER_SIZE, + PRIVATEKEY_TYPE, NULL); + if (ret == 0) + args->keyBufFree = 1; + } + ret = KeyCb(session, ksInfo->named_group, + session->srvKs.key, session->srvKs.key_len, + session->cliKs.key, session->cliKs.key_len, + args->keyBuf, KeyCbCtx, error); + if (ret != 0) { + SetError(-1, error, session, FATAL_ERROR_STATE); + } + } + #endif + if (ret == 0 && args->keyBuf == NULL) { + ret = BUFFER_E; + } + + #ifdef HAVE_PUBLIC_FFDHE + if (ret == 0) { + /* get DH params */ + switch (ksInfo->named_group) { + #ifdef HAVE_FFDHE_2048 + case WOLFSSL_FFDHE_2048: + params = wc_Dh_ffdhe2048_Get(); + args->key->priv.dh.privKeySz = 29; + break; + #endif + #ifdef HAVE_FFDHE_3072 + case WOLFSSL_FFDHE_3072: + params = wc_Dh_ffdhe3072_Get(); + args->key->priv.dh.privKeySz = 34; + break; + #endif + #ifdef HAVE_FFDHE_4096 + case WOLFSSL_FFDHE_4096: + params = wc_Dh_ffdhe4096_Get(); + args->key->priv.dh.privKeySz = 39; + break; + #endif + #ifdef HAVE_FFDHE_6144 + case WOLFSSL_FFDHE_6144: + params = wc_Dh_ffdhe6144_Get(); + args->key->priv.dh.privKeySz = 46; + break; + #endif + #ifdef HAVE_FFDHE_8192 + case WOLFSSL_FFDHE_8192: + params = wc_Dh_ffdhe8192_Get(); + args->key->priv.dh.privKeySz = 52; + break; + #endif + default: + ret = BAD_FUNC_ARG; + } + } + #endif + + if (ret == 0) { + ret = wc_InitDhKey_ex(&args->key->priv.dh.key, NULL, devId); + if (ret == 0) { + args->key->type = WC_PK_TYPE_DH; + args->key->initPriv = 1; + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfSSL_AsyncInit(ssl, + &args->key->priv.dh.key.asyncDev, WC_ASYNC_FLAG_NONE); + #endif + } + } + if (ret == 0) { + #ifdef HAVE_PUBLIC_FFDHE + ret = wc_DhSetKey(&args->key->priv.dh.key, + (byte*)params->p, params->p_len, + (byte*)params->g, params->g_len); + args->key->priv.dh.pLen = params->p_len; + #else + ret = wc_DhSetNamedKey(&args->key->priv.dh.key, + ksInfo->named_group); + if (ret == 0) { + args->key->priv.dh.privKeySz = + wc_DhGetNamedKeyMinSize(ksInfo->named_group); + ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group, + &args->key->priv.dh.pLen, NULL, NULL); + } + #endif + } + if (ret == 0) { + idx = 0; + ret = wc_DhKeyDecode(args->keyBuf->buffer, &idx, + &args->key->priv.dh.key, args->keyBuf->length); + } + if (ret == 0) { + ret = wc_DhExportKeyPair(&args->key->priv.dh.key, + args->key->priv.dh.privKey, &args->key->priv.dh.privKeySz, + NULL, NULL); + } + } + #endif /* !NO_DH && WOLFSSL_DH_EXTRA */ + + #ifdef HAVE_ECC + /* Static ECC Key */ + if (useCurveId >= 0 && args->keyBuf == NULL + #ifdef HAVE_CURVE25519 + && useCurveId != ECC_X25519 + #endif + #ifdef HAVE_CURVE448 + && useCurveId != ECC_X448 + #endif + ) { + /* try and load static ephemeral */ + #ifdef WOLFSSL_STATIC_EPHEMERAL + args->keyBuf = ssl->staticKE.ecKey; + if (args->keyBuf == NULL) + args->keyBuf = ctx->staticKE.ecKey; + #endif + + /* try static ECC */ + if (args->keyBuf == NULL) { + args->keyBuf = session->sslServer->buffers.key; + } + + ret = 0; + #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK + if (KeyCb != NULL && ksInfo) { + if (args->keyBuf == NULL) { + ret = AllocDer(&args->keyBuf, FILE_BUFFER_SIZE, + PRIVATEKEY_TYPE, NULL); + if (ret == 0) + args->keyBufFree = 1; + } + ret = KeyCb(session, ksInfo->named_group, + session->srvKs.key, session->srvKs.key_len, + session->cliKs.key, session->cliKs.key_len, + args->keyBuf, KeyCbCtx, error); + if (ret != 0) { + SetError(-1, error, session, FATAL_ERROR_STATE); + } + } + #endif + + if (ret == 0 && args->keyBuf == NULL) { + ret = BUFFER_E; + } + if (ret == 0) { + ret = wc_ecc_init_ex(&args->key->priv.ecc, NULL, devId); + if (ret == 0) { + args->key->type = WC_PK_TYPE_ECDH; + args->key->initPriv = 1; + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfSSL_AsyncInit(ssl, &args->key->priv.ecc.asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + #endif + } + } + #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ + !defined(HAVE_SELFTEST) + if (ret == 0) { + ret = wc_ecc_set_rng(&args->key->priv.ecc, + session->sslServer->rng); + } + #endif + if (ret == 0) { + idx = 0; + ret = wc_EccPrivateKeyDecode(args->keyBuf->buffer, &idx, + &args->key->priv.ecc, args->keyBuf->length); + if (ret != 0) { + SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE); + } + } + + if (ret == 0) { + args->length = wc_ecc_size(&args->key->priv.ecc) * 2 + 1; + /* The length should be 2 times the key size (x and y), plus 1 + * for the type byte. */ + if (!IsAtLeastTLSv1_3(session->sslServer->version)) { + input += 1; /* Don't include the TLS length for the key. */ + } + + if (args->length > *sslBytes) { + SetError(PARTIAL_INPUT_STR, error, session, + FATAL_ERROR_STATE); + ret = -1; + } + + /* if curve not provided in key share data, then use private + * key curve */ + if (useCurveId == 0 && args->key->priv.ecc.dp) { + /* this is for the static ECC case */ + useCurveId = args->key->priv.ecc.dp->id; + } + } + if (ret == 0) { + ret = wc_ecc_init(&args->key->pub.ecc); + if (ret == 0) + args->key->initPub = 1; + } + if (ret == 0) { + ret = wc_ecc_import_x963_ex(input, args->length, + &args->key->pub.ecc, useCurveId); + if (ret != 0) { + SetError(ECC_PUB_DECODE_STR, error, session, + FATAL_ERROR_STATE); + } + } + if (ret == 0) { + session->keySz = ((args->length - 1) / 2) * WOLFSSL_BIT_SIZE; + /* Length is in bytes. Subtract 1 for the ECC key type. Divide + * by two as the key is in (x,y) coordinates, where x and y are + * the same size, the key size. Convert from bytes to bits. */ + session->sslServer->arrays->preMasterSz = ENCRYPT_LEN; + } + } + #endif /* HAVE_ECC */ + + #ifdef HAVE_CURVE25519 + /* Static Curve25519 Key */ + if (useCurveId == ECC_X25519) { + /* try and load static ephemeral */ + #ifdef WOLFSSL_STATIC_EPHEMERAL + args->keyBuf = ssl->staticKE.x25519Key; + if (args->keyBuf == NULL) + args->keyBuf = ctx->staticKE.x25519Key; + #endif + + ret = 0; + #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK + if (KeyCb != NULL && ksInfo) { + if (args->keyBuf == NULL) { + ret = AllocDer(&args->keyBuf, FILE_BUFFER_SIZE, + PRIVATEKEY_TYPE, NULL); + if (ret == 0) + args->keyBufFree = 1; + } + ret = KeyCb(session, ksInfo->named_group, + session->srvKs.key, session->srvKs.key_len, + session->cliKs.key, session->cliKs.key_len, + args->keyBuf, KeyCbCtx, error); + if (ret != 0) { + SetError(-1, error, session, FATAL_ERROR_STATE); + break; + } + } + #endif + + if (ret == 0 && args->keyBuf == NULL) { + ret = BUFFER_E; + } + if (ret == 0) { + ret = wc_curve25519_init_ex(&args->key->priv.x25519, NULL, + devId); + if (ret == 0) { + args->key->type = WC_PK_TYPE_CURVE25519; + args->key->initPriv = 1; + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfSSL_AsyncInit(ssl, + &args->key->priv.x25519.asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + #endif + } + } + if (ret == 0) { + idx = 0; + ret = wc_Curve25519PrivateKeyDecode(args->keyBuf->buffer, &idx, + &args->key->priv.x25519, args->keyBuf->length); + if (ret != 0) { + SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE); + } + } + + if (ret == 0) { + args->length = CURVE25519_KEYSIZE; + if (args->length > *sslBytes) { + SetError(PARTIAL_INPUT_STR, error, session, + FATAL_ERROR_STATE); + ret = -1; + } + } + if (ret == 0) { + ret = wc_curve25519_init(&args->key->pub.x25519); + if (ret == 0) + args->key->initPub = 1; + } + if (ret == 0) { + ret = wc_curve25519_import_public_ex(input, args->length, + &args->key->pub.x25519, EC25519_LITTLE_ENDIAN); + if (ret != 0) { + SetError(ECC_PUB_DECODE_STR, error, session, + FATAL_ERROR_STATE); + } + } + + if (ret == 0) { + /* For Curve25519 length is always 32 */ + session->keySz = CURVE25519_KEYSIZE; + session->sslServer->arrays->preMasterSz = ENCRYPT_LEN; + } + } + #endif /* HAVE_CURVE25519 */ + + #ifdef HAVE_CURVE448 + /* Static Curve448 Key */ + if (useCurveId == ECC_X448) { + /* try and load static ephemeral */ + #ifdef WOLFSSL_STATIC_EPHEMERAL + args->keyBuf = ssl->staticKE.x448Key; + if (args->keyBuf == NULL) + args->keyBuf = ctx->staticKE.x448Key; + #endif + + ret = 0; + #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK + if (KeyCb != NULL && ksInfo) { + if (args->keyBuf == NULL) { + ret = AllocDer(&args->keyBuf, FILE_BUFFER_SIZE, + PRIVATEKEY_TYPE, NULL); + if (ret == 0) + args->keyBufFree = 1; + } + ret = KeyCb(session, ksInfo->named_group, + session->srvKs.key, session->srvKs.key_len, + session->cliKs.key, session->cliKs.key_len, + args->keyBuf, KeyCbCtx, error); + if (ret != 0) { + SetError(-1, error, session, FATAL_ERROR_STATE); + break; + } + } + #endif + + if (ret == 0 && args->keyBuf == NULL) { + ret = BUFFER_E; + } + if (ret == 0) { + ret = wc_curve448_init(&args->key->priv.x448); + if (ret == 0) { + args->key->type = WC_PK_TYPE_CURVE448; + args->key->initPriv = 1; + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfSSL_AsyncInit(ssl, &args->key->priv.x448.asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + #endif + } + } + if (ret == 0) { + idx = 0; + ret = wc_Curve448PrivateKeyDecode(args->keyBuf->buffer, &idx, + &args->key->priv.x448, args->keyBuf->length); + if (ret != 0) { + SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE); + } + } + + if (ret == 0) { + args->length = CURVE448_KEY_SIZE; + if (args->length > *sslBytes) { + SetError(PARTIAL_INPUT_STR, error, session, + FATAL_ERROR_STATE); + ret = -1; + } + } + if (ret == 0) { + ret = wc_curve448_init(&args->key->pub.x448); + if (ret == 0) + args->key->initPub = 1; + } + if (ret == 0) { + ret = wc_curve448_import_public_ex(input, args->length, + &args->key->pub.x448, EC448_LITTLE_ENDIAN); + if (ret != 0) { + SetError(ECC_PUB_DECODE_STR, error, session, + FATAL_ERROR_STATE); + } + } + + if (ret == 0) { + session->keySz = CURVE448_KEY_SIZE; + session->sslServer->arrays->preMasterSz = ENCRYPT_LEN; + } + } + #endif /* HAVE_CURVE448 */ + + #if defined(WOLFSSL_STATIC_EPHEMERAL) && !defined(SINGLE_THREADED) + if (args->keyLocked) { + wc_UnLockMutex(&ctx->staticKELock); + } + #endif + + if (ret != 0) { + goto exit_sk; + } + + /* make sure a key type was found */ + if (args->key->type == WC_PK_TYPE_NONE) { + ERROR_OUT(NOT_COMPILED_IN, exit_sk); + } + + /* Advance state and proceed */ + ssl->options.asyncState = TLS_ASYNC_DO; + } /* case TLS_ASYNC_BEGIN */ + FALL_THROUGH; + + case TLS_ASYNC_DO: + { + #ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV* asyncDev = NULL; + #endif + #ifndef NO_RSA + if (args->key->type == WC_PK_TYPE_RSA) { + ret = wc_RsaPrivateDecrypt(input, args->length, + session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSz, + &args->key->priv.rsa); + #ifdef WOLFSSL_ASYNC_CRYPT + asyncDev = &args->key->priv.rsa.asyncDev; + #endif + } + #endif /* !NO_RSA */ + #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) + if (args->key->type == WC_PK_TYPE_DH) { + /* Derive secret from private key and peer's public key */ + ret = wc_DhAgree(&args->key->priv.dh.key, + session->sslServer->arrays->preMasterSecret, + &session->sslServer->arrays->preMasterSz, + args->key->priv.dh.privKey, args->key->priv.dh.privKeySz, + input, *sslBytes); + #ifdef WOLFSSL_ASYNC_CRYPT + asyncDev = &args->key->priv.dh.key.asyncDev; + #endif + } + #endif /* !NO_DH && WOLFSSL_DH_EXTRA */ + #ifdef HAVE_ECC + if (args->key->type == WC_PK_TYPE_ECDH) { + ret = wc_ecc_shared_secret(&args->key->priv.ecc, + &args->key->pub.ecc, + session->sslServer->arrays->preMasterSecret, + &session->sslServer->arrays->preMasterSz); + #ifdef WOLFSSL_ASYNC_CRYPT + asyncDev = &args->key->priv.ecc.asyncDev; + #endif + } + #endif /* HAVE_ECC */ + #ifdef HAVE_CURVE25519 + if (args->key->type == WC_PK_TYPE_CURVE25519) { + ret = wc_curve25519_shared_secret_ex(&args->key->priv.x25519, + &args->key->pub.x25519, + session->sslServer->arrays->preMasterSecret, + &session->sslServer->arrays->preMasterSz, + EC25519_LITTLE_ENDIAN); + #ifdef WOLFSSL_ASYNC_CRYPT + asyncDev = &args->key->priv.x25519.asyncDev; + #endif + } + #endif /* HAVE_CURVE25519 */ + #ifdef HAVE_CURVE448 + if (args->key->type == WC_PK_TYPE_CURVE448) { + ret = wc_curve448_shared_secret_ex(&args->key->priv.x448, + &args->key->pub.x448, + session->sslServer->arrays->preMasterSecret, + &session->sslServer->arrays->preMasterSz, EC448_LITTLE_ENDIAN); + #ifdef WOLFSSL_ASYNC_CRYPT + asyncDev = &args->key->priv.x448.asyncDev; + #endif + } + #endif /* HAVE_CURVE448 */ + + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + /* Handle async pending response */ + ret = wolfSSL_AsyncPush(ssl, asyncDev); + break; + } + #endif /* WOLFSSL_ASYNC_CRYPT */ + + /* Advance state and proceed */ + ssl->options.asyncState = TLS_ASYNC_VERIFY; + } /* case TLS_ASYNC_DO */ + FALL_THROUGH; + + case TLS_ASYNC_VERIFY: + { + #ifndef NO_RSA + if (args->key->type == WC_PK_TYPE_RSA) { + if (ret != SECRET_LEN) { + SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE); + } + } + #endif /* !NO_RSA */ + #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) + if (args->key->type == WC_PK_TYPE_DH) { + /* left-padded with zeros up to the size of the prime */ + if (args->key->priv.dh.pLen > + session->sslServer->arrays->preMasterSz) { + word32 diff = args->key->priv.dh.pLen - + session->sslServer->arrays->preMasterSz; + XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff, + session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSz); + XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff); + session->sslServer->arrays->preMasterSz=args->key->priv.dh.pLen; + } + } + #endif /* !NO_DH && WOLFSSL_DH_EXTRA */ + + /* Advance state and proceed */ + ssl->options.asyncState = TLS_ASYNC_FINALIZE; + } /* case TLS_ASYNC_VERIFY */ + FALL_THROUGH; + + case TLS_ASYNC_FINALIZE: + { + /* store for client side as well */ + XMEMCPY(session->sslClient->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSz); + session->sslClient->arrays->preMasterSz = + session->sslServer->arrays->preMasterSz; + + #ifdef SHOW_SECRETS + PrintSecret("pre master secret", + session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSz); + #endif + + if (SetCipherSpecs(session->sslServer) != 0) { + SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); + ret = -1; goto exit_sk; + } + + if (SetCipherSpecs(session->sslClient) != 0) { + SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE); + ret = -1; goto exit_sk; + } + + #ifdef WOLFSSL_TLS13 + /* TLS v1.3 derive handshake key */ + if (IsAtLeastTLSv1_3(session->sslServer->version)) { + ret = DeriveEarlySecret(session->sslServer); + ret += DeriveEarlySecret(session->sslClient); + ret += DeriveHandshakeSecret(session->sslServer); + ret += DeriveHandshakeSecret(session->sslClient); + ret += DeriveTls13Keys(session->sslServer, handshake_key, + ENCRYPT_AND_DECRYPT_SIDE, 1); + ret += DeriveTls13Keys(session->sslClient, handshake_key, + ENCRYPT_AND_DECRYPT_SIDE, 1); + #ifdef WOLFSSL_EARLY_DATA + ret += SetKeysSide(session->sslServer, DECRYPT_SIDE_ONLY); + ret += SetKeysSide(session->sslClient, DECRYPT_SIDE_ONLY); + #else + ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE); + ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE); + #endif + } + else + #endif /* WOLFSSL_TLS13 */ + { + ret = MakeMasterSecret(session->sslServer); + ret += MakeMasterSecret(session->sslClient); + ret += SetKeysSide(session->sslServer, ENCRYPT_AND_DECRYPT_SIDE); + ret += SetKeysSide(session->sslClient, ENCRYPT_AND_DECRYPT_SIDE); + } + if (ret != 0) { + SetError(BAD_DERIVE_STR, error, session, FATAL_ERROR_STATE); + ret = -1; goto exit_sk; + } + + #ifdef SHOW_SECRETS + #ifdef WOLFSSL_TLS13 + if (!IsAtLeastTLSv1_3(session->sslServer->version)) + #endif + { + ShowTlsSecrets(session); + } + #endif + + CallConnectionCb(session); + + break; + } /* case TLS_ASYNC_FINALIZE */ + + default: + ret = INPUT_CASE_ERROR; + } /* switch(ssl->options.asyncState) */ + +exit_sk: + + /* Handle async pending response */ +#ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + return ret; + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + +#ifdef WOLFSSL_SNIFFER_STATS + if (ret != 0) + INC_STAT(SnifferStats.sslKeyFails); +#endif + + /* Final cleanup */ + FreeSetupKeysArgs(ssl, args); return ret; } @@ -3267,8 +3491,10 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, if (b) { #ifdef WOLFSSL_TLS13 XMEMCPY(session->sslServer->session->sessionID, input, ID_LEN); + session->sslServer->session->sessionIDSz = ID_LEN; #endif XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN); + session->sslServer->arrays->sessionIDSz = ID_LEN; session->sslServer->options.haveSessionId = 1; } input += b; @@ -3467,11 +3693,16 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, } #endif - /* hash server_hello */ - HashRaw(session->sslServer, inputHello - HANDSHAKE_HEADER_SZ, - initialBytes + HANDSHAKE_HEADER_SZ); - HashRaw(session->sslClient, inputHello - HANDSHAKE_HEADER_SZ, - initialBytes + HANDSHAKE_HEADER_SZ); +#ifdef WOLFSSL_ASYNC_CRYPT + if (session->sslServer->error != WC_PENDING_E) +#endif + { + /* hash server_hello */ + HashRaw(session->sslServer, inputHello - HANDSHAKE_HEADER_SZ, + initialBytes + HANDSHAKE_HEADER_SZ); + HashRaw(session->sslClient, inputHello - HANDSHAKE_HEADER_SZ, + initialBytes + HANDSHAKE_HEADER_SZ); + } if (doResume) { ret = DoResume(session, error); @@ -3496,6 +3727,11 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, ret = SetupKeys(session->cliKs.key, &session->cliKs.key_len, session, error, &session->cliKs); if (ret != 0) { + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + return ret; + } + #endif SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); return ret; } @@ -3596,9 +3832,12 @@ static int ProcessClientHello(const byte* input, int* sslBytes, Trace(CLIENT_RESUME_TRY_STR); #ifdef WOLFSSL_TLS13 XMEMCPY(session->sslClient->session->sessionID, input, ID_LEN); + session->sslClient->session->sessionIDSz = ID_LEN; #endif - if (session->sslClient->arrays) + if (session->sslClient->arrays) { XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN); + session->sslClient->arrays->sessionIDSz = ID_LEN; + } session->sslClient->options.haveSessionId = 1; } @@ -4230,7 +4469,12 @@ static int DoHandShake(const byte* input, int* sslBytes, } #endif if (ret == 0) { + /* TODO: Add async reentry support here */ ret = ProcessClientKeyExchange(input, sslBytes, session, error); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) + return ret; + #endif if (ret != 0) SetError(GOT_CLIENT_KEY_EX_STR, error, session, FATAL_ERROR_STATE); } @@ -4262,96 +4506,6 @@ exit: return ret; } - -/* Decrypt input into plain output, 0 on success */ -static int Decrypt(WOLFSSL* ssl, byte* output, const byte* input, word32 sz) -{ - int ret = 0; - - (void)output; - (void)input; - (void)sz; - - switch (ssl->specs.bulk_cipher_algorithm) { - #ifdef BUILD_ARC4 - case wolfssl_rc4: - wc_Arc4Process(ssl->decrypt.arc4, output, input, sz); - break; - #endif - - #ifdef BUILD_DES3 - case wolfssl_triple_des: - ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, output, input, sz); - break; - #endif - - #ifdef BUILD_AES - case wolfssl_aes: - ret = wc_AesCbcDecrypt(ssl->decrypt.aes, output, input, sz); - break; - #endif - - #ifdef HAVE_CAMELLIA - case wolfssl_camellia: - wc_CamelliaCbcDecrypt(ssl->decrypt.cam, output, input, sz); - break; - #endif - - #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) - case wolfssl_aes_gcm: - case wolfssl_aes_ccm: /* GCM AEAD macros use same size as CCM */ - if (sz >= (word32)(AESGCM_EXP_IV_SZ + ssl->specs.aead_mac_size)) { - /* scratch buffer, sniffer ignores auth tag */ - wc_AesAuthEncryptFunc aes_auth_fn; - byte authTag[WOLFSSL_MIN_AUTH_TAG_SZ]; - byte nonce[AESGCM_NONCE_SZ]; - XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ); - XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ); - - /* use encrypt because we don't care about authtag */ - #if defined(BUILD_AESGCM) && defined(HAVE_AESCCM) - aes_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) - ? wc_AesGcmEncrypt : wc_AesCcmEncrypt; - #elif defined(BUILD_AESGCM) - aes_auth_fn = wc_AesGcmEncrypt; - #else - aes_auth_fn = wc_AesCcmEncrypt; - #endif - if (aes_auth_fn(ssl->decrypt.aes, - output, - input + AESGCM_EXP_IV_SZ, - sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, - nonce, AESGCM_NONCE_SZ, - authTag, sizeof(authTag), - NULL, 0) < 0) { - Trace(BAD_DECRYPT); - ret = -1; - } - ForceZero(nonce, AESGCM_NONCE_SZ); - } - else { - Trace(BAD_DECRYPT_SIZE); - ret = -1; - } - break; - #endif - - #ifdef HAVE_NULL_CIPHER - case wolfssl_cipher_null: - XMEMCPY(output, input, sz); - break; - #endif - - default: - Trace(BAD_DECRYPT_TYPE); - ret = -1; - break; - } - - return ret; -} - - /* Decrypt input message into output, adjust output steam if needed */ static const byte* DecryptMessage(WOLFSSL* ssl, const byte* input, word32 sz, byte* output, int* error, int* advance, RecordLayerHeader* rh) @@ -4361,13 +4515,25 @@ static const byte* DecryptMessage(WOLFSSL* ssl, const byte* input, word32 sz, #ifdef WOLFSSL_TLS13 if (IsAtLeastTLSv1_3(ssl->version)) { - ret = DecryptTls13(ssl, output, input, sz, (byte*)rh, RECORD_HEADER_SZ); + ret = DecryptTls13(ssl, output, input, sz, (byte*)rh, RECORD_HEADER_SZ, 0); } else #endif { - ret = Decrypt(ssl, output, input, sz); + ret = DecryptTls(ssl, output, input, sz, 0); } +#ifdef WOLFSSL_ASYNC_CRYPT + /* for async the symmetric operations are blocking */ + if (ret == WC_PENDING_E) { + do { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + } while (ret == 0); + if (ret >= 0) { + /* remove from event queue list */ + ret = wolfSSL_AsyncPop(ssl, NULL); + } + } +#endif if (ret != 0) { *error = ret; return NULL; @@ -4992,7 +5158,9 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session, if (real < *expected) { if (real + *sslBytes > *expected) { - Trace(OVERLAP_DUPLICATE_STR); + if (session->sslServer->error != WC_PENDING_E) { + Trace(OVERLAP_DUPLICATE_STR); + } /* The following conditional block is duplicated below. It is the * same action but for a different setup case. If changing this @@ -5041,7 +5209,8 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session, if (*sslBytes > 0) { /* If packet has data attempt to process packet, if hasn't * already been ack'd during handshake */ - if (FindPrevAck(session, real)) { + if (session->sslServer->error != WC_PENDING_E && + FindPrevAck(session, real)) { Trace(DUPLICATE_STR); ret = 1; } @@ -5638,6 +5807,10 @@ doPart: Trace(GOT_HANDSHAKE_STR); ret = DoHandShake(sslFrame, &sslBytes, session, error, rhSize); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) + return ret; + #endif if (ret != 0 || sslBytes > startIdx) { if (session->flags.fatalError == 0) SetError(BAD_HANDSHAKE_STR, error, session, @@ -5846,10 +6019,9 @@ static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo, * WOLFSSL_SNIFFER_ERROR on error and WOLFSSL_SNIFFER_FATAL_ERROR on fatal state * error */ -static int ssl_DecodePacketInternal(const byte* packet, int length, - void* vChain, word32 chainSz, +static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain, byte** data, SSLInfo* sslInfo, - void* ctx, char* error) + void* ctx, char* error, int asyncOkay) { TcpInfo tcpInfo; IpInfo ipInfo; @@ -5857,19 +6029,28 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, const byte* end; int sslBytes; /* ssl bytes unconsumed */ int ret; - SnifferSession* session = 0; + SnifferSession* session = NULL; + void* vChain = NULL; + word32 chainSz = 0; + if (isChain) { #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT - if (packet == NULL && vChain != NULL) { - struct iovec* chain = (struct iovec*)vChain; + struct iovec* chain; word32 i; + vChain = (void*)packet; + chainSz = (word32)length; + + chain = (struct iovec*)vChain; length = 0; for (i = 0; i < chainSz; i++) length += chain[i].iov_len; packet = (const byte*)chain[0].iov_base; - } +#else + SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE); + return WOLFSSL_SNIFFER_ERROR; #endif + } if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes, error) != 0) @@ -5895,6 +6076,10 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, return 0; /* done for now */ } +#ifdef WOLFSSL_ASYNC_CRYPT + session->userCtx = ctx; +#endif + ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error); if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return WOLFSSL_SNIFFER_FATAL_ERROR; @@ -5929,7 +6114,27 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, INC_STAT(SnifferStats.sslDecryptedPackets); #endif - ret = ProcessMessage(sslFrame, session, sslBytes, data, end, ctx, error); +#ifdef WOLFSSL_ASYNC_CRYPT + do { +#endif + ret = ProcessMessage(sslFrame, session, sslBytes, data, end, ctx, error); + session->sslServer->error = ret; +#ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + if (!asyncOkay || CryptoDeviceId == INVALID_DEVID) { + /* If devId has not been set then we need to block here by + * polling and looping */ + wolfSSL_AsyncPoll(session->sslServer, WOLF_POLL_FLAG_CHECK_HW); + } + else { + return ret; /* return to caller */ + } + } + } while (ret == WC_PENDING_E); +#else + (void)asyncOkay; +#endif + if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return WOLFSSL_SNIFFER_FATAL_ERROR; if (CheckFinCapture(&ipInfo, &tcpInfo, session) == 0) { @@ -5947,8 +6152,8 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int ssl_DecodePacketWithSessionInfo(const unsigned char* packet, int length, unsigned char** data, SSLInfo* sslInfo, char* error) { - return ssl_DecodePacketInternal(packet, length, NULL, 0, data, sslInfo, - NULL, error); + return ssl_DecodePacketInternal(packet, length, 0, data, sslInfo, + NULL, error, 0); } @@ -5957,8 +6162,8 @@ int ssl_DecodePacketWithSessionInfo(const unsigned char* packet, int length, * on error and WOLFSSL_SNIFFER_FATAL_ERROR on fatal state error */ int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error) { - return ssl_DecodePacketInternal(packet, length, NULL, 0, data, NULL, NULL, - error); + return ssl_DecodePacketInternal(packet, length, 0, data, NULL, NULL, + error, 0); } @@ -5969,8 +6174,8 @@ int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error) int ssl_DecodePacketWithSessionInfoStoreData(const unsigned char* packet, int length, void* ctx, SSLInfo* sslInfo, char* error) { - return ssl_DecodePacketInternal(packet, length, NULL, 0, NULL, sslInfo, - ctx, error); + return ssl_DecodePacketInternal(packet, length, 0, NULL, sslInfo, + ctx, error, 0); } #endif @@ -5983,8 +6188,8 @@ int ssl_DecodePacketWithSessionInfoStoreData(const unsigned char* packet, int ssl_DecodePacketWithChain(void* vChain, word32 chainSz, byte** data, char* error) { - return ssl_DecodePacketInternal(NULL, 0, vChain, chainSz, data, NULL, NULL, - error); + return ssl_DecodePacketInternal(vChain, chainSz, 1, data, NULL, NULL, + error, 0); } #endif @@ -6000,8 +6205,8 @@ int ssl_DecodePacketWithChain(void* vChain, word32 chainSz, byte** data, int ssl_DecodePacketWithChainSessionInfoStoreData(void* vChain, word32 chainSz, void* ctx, SSLInfo* sslInfo, char* error) { - return ssl_DecodePacketInternal(NULL, 0, vChain, chainSz, NULL, sslInfo, - ctx, error); + return ssl_DecodePacketInternal(vChain, chainSz, 1, NULL, sslInfo, + ctx, error, 0); } #endif @@ -6306,5 +6511,54 @@ int ssl_SetKeyCallback(SSLKeyCb cb, void* cbCtx) } #endif +#ifdef WOLFSSL_ASYNC_CRYPT + +int ssl_DecodePacketAsync(void* packet, unsigned int packetSz, + int isChain, unsigned char** data, char* error, SSLInfo* sslInfo, + void* userCtx) +{ + return ssl_DecodePacketInternal(packet, packetSz, isChain, data, sslInfo, + userCtx, error, 1); +} + +int ssl_PollSniffer(WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, + int* pEventCount) +{ + int ret = 0; + int eventCount = 0; + SnifferServer* srv; + + wc_LockMutex(&ServerListMutex); + + /* Iterate the open sniffer sessions calling wolfSSL_CTX_AsyncPoll */ + srv = ServerList; + while (srv) { + int nMax = maxEvents - eventCount, nReady = 0; + if (nMax <= 0) { + break; /* out of room in events list */ + } + ret = wolfSSL_CTX_AsyncPoll(srv->ctx, events + nReady, nMax, flags, + &nReady); + if (ret == 0) { + eventCount += nReady; + } + else { + #ifdef DEBUG_SNIFFER + printf("Sniffer Server %p: Poll error: %d\n", srv, ret); + #endif + break; + } + srv = srv->next; + } + wc_UnLockMutex(&ServerListMutex); + + *pEventCount = eventCount; + + return ret; +} +#endif + +#undef ERROR_OUT + #endif /* WOLFSSL_SNIFFER */ -#endif /* WOLFCRYPT_ONLY */ +#endif /* !WOLFCRYPT_ONLY && !NO_FILESYSTEM */ diff --git a/src/tls13.c b/src/tls13.c index b92a0c882..35cc7774c 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2106,10 +2106,11 @@ static int Tls13IntegrityOnly_Decrypt(WOLFSSL* ssl, byte* output, * sz The length of the encrypted data plus authentication tag. * aad The additional authentication data. * aadSz The size of the addition authentication data. + * doAlert Generate alert on error (not for sniffer use cases) * returns 0 on success, otherwise failure. */ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz, - const byte* aad, word16 aadSz) + const byte* aad, word16 aadSz, int doAlert) { int ret = 0; word16 dataSz = sz - ssl->specs.aead_mac_size; @@ -2275,9 +2276,13 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz, #ifndef WOLFSSL_EARLY_DATA if (ret < 0) { - SendAlert(ssl, alert_fatal, bad_record_mac); + if (doAlert) { + SendAlert(ssl, alert_fatal, bad_record_mac); + } ret = VERIFY_MAC_ERROR; } +#else + (void)doAlert; #endif return ret; diff --git a/sslSniffer/sslSnifferTest/snifftest.c b/sslSniffer/sslSnifferTest/snifftest.c index 10f47f30d..1bc66da58 100644 --- a/sslSniffer/sslSnifferTest/snifftest.c +++ b/sslSniffer/sslSnifferTest/snifftest.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB #include @@ -382,6 +384,80 @@ static void TrimNewLine(char* str) str[strSz-1] = '\0'; } +static void show_appinfo(void) +{ + printf("snifftest %s\n", LIBWOLFSSL_VERSION_STRING); + + /* list enabled sniffer features */ + printf("sniffer features: " + #ifdef WOLFSSL_SNIFFER_STATS + "stats, " + #endif + #ifdef WOLFSSL_SNIFFER_WATCH + "watch, " + #endif + #ifdef WOLFSSL_SNIFFER_STORE_DATA_CB + "store_data_cb " + #endif + #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT + "chain_input " + #endif + #ifdef WOLFSSL_SNIFFER_KEY_CALLBACK + "key_callback " + #endif + #ifdef DEBUG_SNIFFER + "debug " + #endif + #ifdef WOLFSSL_TLS13 + "tls_v13 " + #endif + #ifdef HAVE_SESSION_TICKET + "session_ticket " + #endif + #ifdef WOLFSSL_STATIC_EPHEMERAL + "static_ephemeral " + #endif + #ifdef WOLFSSL_ENCRYPTED_KEYS + "encrypted_keys " + #endif + #ifdef HAVE_SNI + "sni " + #endif + #ifdef HAVE_EXTENDED_MASTER + "extended_master " + #endif + #ifdef HAVE_MAX_FRAGMENT + "max fragment " + #endif + #ifdef WOLFSSL_ASYNC_CRYPT + "async_crypt " + #endif + #ifndef NO_RSA + "rsa " + #endif + #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) + "dh " + #endif + #ifdef HAVE_ECC + "ecc " + #endif + #ifdef HAVE_CURVE448 + "x448 " + #endif + #ifdef HAVE_CURVE22519 + "x22519 " + #endif + "\n\n" + ); +} +static void show_usage(void) +{ + printf("usage:\n"); + printf("\t./snifftest\n"); + printf("\t\tprompts for options\n"); + printf("\t./snifftest dump pemKey [server] [port] [password]\n"); +} + int main(int argc, char** argv) { int ret = 0; @@ -401,11 +477,15 @@ int main(int argc, char** argv) struct bpf_program fp; pcap_if_t *d; pcap_addr_t *a; + int isChain = 0; + int j; #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT - struct iovec chain[CHAIN_INPUT_COUNT]; - int chainSz; + struct iovec chains[CHAIN_INPUT_COUNT]; + unsigned int remainder; #endif + show_appinfo(); + signal(SIGINT, sig_handler); #ifndef _WIN32 @@ -601,9 +681,7 @@ int main(int argc, char** argv) } } else { - /* usage error */ - printf( "usage: ./snifftest or ./snifftest dump pemKey" - " [server] [port] [password]\n"); + show_usage(); exit(EXIT_FAILURE); } @@ -618,9 +696,11 @@ int main(int argc, char** argv) struct pcap_pkthdr header; const unsigned char* packet = pcap_next(pcap, &header); SSLInfo sslInfo; + void* chain = NULL; + int chainSz = 0; + packetNumber++; if (packet) { - byte* data = NULL; if (header.caplen > 40) { /* min ip(20) + min tcp(20) */ @@ -629,45 +709,69 @@ int main(int argc, char** argv) } else continue; + #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT - { - unsigned int j = 0; - unsigned int remainder = header.caplen; - - chainSz = 0; - do { - unsigned int chunkSz; - - chunkSz = min(remainder, CHAIN_INPUT_CHUNK_SIZE); - chain[chainSz].iov_base = (void*)(packet + j); - chain[chainSz].iov_len = chunkSz; - j += chunkSz; - remainder -= chunkSz; - chainSz++; - } while (j < header.caplen); - } + isChain = 1; + j = 0; + remainder = header.caplen; + chainSz = 0; + do { + unsigned int chunkSz = min(remainder, CHAIN_INPUT_CHUNK_SIZE); + chains[chainSz].iov_base = (void*)(packet + j); + chains[chainSz].iov_len = chunkSz; + j += chunkSz; + remainder -= chunkSz; + chainSz++; + } while (j < (int)header.caplen); + chain = (void*)chains; +#else + chain = (void*)packet; + chainSz = header.caplen; + (void)isChain; #endif -#if defined(WOLFSSL_SNIFFER_CHAIN_INPUT) && \ - defined(WOLFSSL_SNIFFER_STORE_DATA_CB) +#ifdef WOLFSSL_ASYNC_CRYPT + do { + WOLF_EVENT* events[1]; /* poll for single event */ + int eventCount = 0; + + /* For async call the original API again with same data, + * or call with different sessions for multiple concurrent + * stream processing */ + ret = ssl_DecodePacketAsync(chain, chainSz, isChain, &data, err, + &sslInfo, NULL); + + if (ret == WC_PENDING_E) { + if (ssl_PollSniffer(events, 1, WOLF_POLL_FLAG_CHECK_HW, + &eventCount) != 0) { + break; + } + } + } while (ret == WC_PENDING_E); +#elif defined(WOLFSSL_SNIFFER_CHAIN_INPUT) && \ + defined(WOLFSSL_SNIFFER_STORE_DATA_CB) ret = ssl_DecodePacketWithChainSessionInfoStoreData(chain, chainSz, &data, &sslInfo, err); #elif defined(WOLFSSL_SNIFFER_CHAIN_INPUT) (void)sslInfo; ret = ssl_DecodePacketWithChain(chain, chainSz, &data, err); -#elif defined(WOLFSSL_SNIFFER_STORE_DATA_CB) +#else + #if defined(WOLFSSL_SNIFFER_STORE_DATA_CB) ret = ssl_DecodePacketWithSessionInfoStoreData(packet, header.caplen, &data, &sslInfo, err); -#else + #else ret = ssl_DecodePacketWithSessionInfo(packet, header.caplen, &data, &sslInfo, err); + #endif + (void)chain; + (void)chainSz; #endif + if (ret < 0) { printf("ssl_Decode ret = %d, %s\n", ret, err); hadBadPacket = 1; } if (ret > 0) { - int j; /* Convert non-printable data to periods. */ for (j = 0; j < ret; j++) { if (isprint(data[j]) || isspace(data[j])) continue; diff --git a/wolfcrypt/src/wolfevent.c b/wolfcrypt/src/wolfevent.c index 8ae2717d7..2356ae406 100644 --- a/wolfcrypt/src/wolfevent.c +++ b/wolfcrypt/src/wolfevent.c @@ -205,7 +205,7 @@ int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter, } #endif - /* itterate event queue */ + /* iterrate event queue */ for (event = queue->head; event != NULL; event = event->next) { /* optional filter based on context */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 652d5dfea..85893b1e2 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1760,9 +1760,14 @@ WOLFSSL_LOCAL int HashInput(WOLFSSL* ssl, const byte* input, int sz); WOLFSSL_LOCAL int SNI_Callback(WOLFSSL* ssl); #endif #endif + +WOLFSSL_LOCAL int DecryptTls(WOLFSSL* ssl, byte* plain, const byte* input, + word16 sz, int doAlert); + #ifdef WOLFSSL_TLS13 WOLFSSL_LOCAL int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, - word16 sz, const byte* aad, word16 aadSz); + word16 sz, const byte* aad, word16 aadSz, + int doAlert); WOLFSSL_LOCAL int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, byte type, word32 size, word32 totalSz); diff --git a/wolfssl/sniffer.h b/wolfssl/sniffer.h index 95503a6bf..2a49f9bda 100644 --- a/wolfssl/sniffer.h +++ b/wolfssl/sniffer.h @@ -27,6 +27,11 @@ #include #include +#ifdef HAVE_WOLF_EVENT + #include +#endif + + #ifdef _WIN32 #ifdef SSL_SNIFFER_EXPORTS #define SSL_SNIFFER_API __declspec(dllexport) @@ -119,9 +124,13 @@ SSL_SNIFFER_API int ssl_GetSessionStats(unsigned int* active, unsigned int* reassemblyMemory, char* error); -WOLFSSL_API void ssl_InitSniffer(void); +WOLFSSL_API +SSL_SNIFFER_API void ssl_InitSniffer(void); +WOLFSSL_API +SSL_SNIFFER_API void ssl_InitSniffer_ex(int devId); -WOLFSSL_API void ssl_FreeSniffer(void); +WOLFSSL_API +SSL_SNIFFER_API void ssl_FreeSniffer(void); /* ssl_SetPrivateKey typeKs */ @@ -270,6 +279,21 @@ SSL_SNIFFER_API int ssl_DecodePacketWithChainSessionInfoStoreData( #endif +#ifdef WOLFSSL_ASYNC_CRYPT + +WOLFSSL_API +SSL_SNIFFER_API int ssl_DecodePacketAsync(void* packet, unsigned int packetSz, + int isChain, unsigned char** data, char* error, SSLInfo* sslInfo, + void* userCtx); + +WOLFSSL_API +SSL_SNIFFER_API int ssl_PollSniffer(WOLF_EVENT** events, int maxEvents, + WOLF_EVENT_FLAG flags, int* eventCount); + +#endif /* WOLFSSL_ASYNC_CRYPT */ + + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 3cc826957..fee7d7455 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -91,6 +91,11 @@ enum { WC_FFDHE_8192 = 260, }; +/* DH Private Key size up to 8192 bit */ +#ifndef WC_DH_PRIV_MAX_SZ +#define WC_DH_PRIV_MAX_SZ 52 +#endif + #ifdef HAVE_PUBLIC_FFDHE #ifdef HAVE_FFDHE_2048 WOLFSSL_API const DhParams* wc_Dh_ffdhe2048_Get(void); diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index b876a516f..4d5e502d4 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -24,7 +24,7 @@ */ /* DESCRIPTION -This library defines error codes and contians routines for setting and examining +This library defines error codes and contains routines for setting and examining the error status. */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 9b5386f9f..44519a595 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -904,6 +904,7 @@ decouple library dependencies with standard string, memory and so on. DYNAMIC_TYPE_SNIFFER_PB_BUFFER = 1003, DYNAMIC_TYPE_SNIFFER_TICKET_ID = 1004, DYNAMIC_TYPE_SNIFFER_NAMED_KEY = 1005, + DYNAMIC_TYPE_SNIFFER_KEY = 1006, }; /* max error buffer string size */