diff --git a/.gitignore b/.gitignore index 47c38e3f1f..dd4247fcca 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,8 @@ fips_test.c fips src/async.c wolfssl/async.h +wolfcrypt/src/async.c +wolfssl/wolfcrypt/async.h ctaocrypt/benchmark/benchmark ctaocrypt/test/testctaocrypt wolfcrypt/benchmark/benchmark @@ -49,6 +51,10 @@ examples/client/client examples/echoclient/echoclient examples/echoserver/echoserver examples/server/server +examples/sctp/sctp-server +examples/sctp/sctp-server-dtls +examples/sctp/sctp-client +examples/sctp/sctp-client-dtls server_ready snifftest output diff --git a/IDE/ARDUINO/README.md b/IDE/ARDUINO/README.md index 9742289a48..b16d492e5f 100644 --- a/IDE/ARDUINO/README.md +++ b/IDE/ARDUINO/README.md @@ -7,10 +7,16 @@ files to be in the library's root directory with a header file in the name of the library. This script moves all src/ files to the root wolfssl directory and creates a stub header file called wolfssl.h. -To configure wolfSSL with Arduino, enter the following from within the +Step 1: To configure wolfSSL with Arduino, enter the following from within the wolfssl/IDE/ARDUINO directory: - ./wolfssl-arduino.sh + ./wolfssl-arduino.sh + + +Step 2: Edit /wolfssl/wolfcrypt/settings.h uncomment the define for +WOLFSSL_ARDUINO + +also uncomment the define for INTEL_GALILEO if building for that platform #####Including wolfSSL in Arduino Libraries (for Arduino version 1.6.6) 1. Copy the wolfSSL directory into Arduino/libraries (or wherever Arduino searches for libraries). diff --git a/IDE/ARDUINO/sketches/wolfssl_client.ino b/IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino similarity index 100% rename from IDE/ARDUINO/sketches/wolfssl_client.ino rename to IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino diff --git a/IDE/ARDUINO/wolfssl-arduino.sh b/IDE/ARDUINO/wolfssl-arduino.sh index 7d6b270880..d076ea7a12 100755 --- a/IDE/ARDUINO/wolfssl-arduino.sh +++ b/IDE/ARDUINO/wolfssl-arduino.sh @@ -6,7 +6,7 @@ DIR=${PWD##*/} -if [ "$DIR" == "ARDUINO" ]; then +if [ "$DIR" = "ARDUINO" ]; then cp ../../src/*.c ../../ cp ../../wolfcrypt/src/*.c ../../ echo "/* stub header file for Arduino compatibility */" >> ../../wolfssl.h diff --git a/IDE/WIN/user_settings.h b/IDE/WIN/user_settings.h index 30ec8f0007..a3146861fa 100755 --- a/IDE/WIN/user_settings.h +++ b/IDE/WIN/user_settings.h @@ -28,6 +28,7 @@ #define WOLFSSL_RIPEMD #define WOLFSSL_SHA512 #define NO_PSK + #define HAVE_EXTENDED_MASTER #define WOLFSSL_SNIFFER #else /* The servers and clients */ diff --git a/IDE/WIN/wolfssl-fips.vcxproj b/IDE/WIN/wolfssl-fips.vcxproj index 74c1041ab4..8575aeb9ac 100644 --- a/IDE/WIN/wolfssl-fips.vcxproj +++ b/IDE/WIN/wolfssl-fips.vcxproj @@ -300,6 +300,7 @@ + diff --git a/autogen.sh b/autogen.sh index 971878e33b..7d5ffd856b 100755 --- a/autogen.sh +++ b/autogen.sh @@ -20,8 +20,8 @@ if test -d .git; then touch ./ctaocrypt/src/fips_test.c # touch async crypt files - touch ./src/async.c - touch ./wolfssl/async.h + touch ./wolfcrypt/src/async.c + touch ./wolfssl/wolfcrypt/async.h else WARNINGS="all" fi diff --git a/configure.ac b/configure.ac index ed283b5efb..e74edd3272 100644 --- a/configure.ac +++ b/configure.ac @@ -125,6 +125,71 @@ AS_IF([test "$ax_enable_debug" = "yes"], [AM_CFLAGS="$AM_CFLAGS -DNDEBUG"]) +# Distro build feature subset (Debian, Ubuntu, etc.) +AC_ARG_ENABLE([distro], + [ --enable-distro Enable wolfSSL distro build (default: disabled)], + [ ENABLED_DISTRO=$enableval ], + [ ENABLED_DISTRO=no ] + ) +if test "$ENABLED_DISTRO" = "yes" +then + enable_shared=yes + enable_static=yes + enable_dtls=yes + enable_openssh=yes + enable_opensslextra=yes + enable_savesession=yes + enable_savecert=yes + enable_atomicuser=yes + enable_pkcallbacks=yes + enable_aesgcm=yes + enable_aesccm=yes + enable_camellia=yes + enable_ripemd=yes + enable_sha512=yes + enable_sessioncerts=yes + enable_keygen=yes + enable_certgen=yes + enable_certreq=yes + enable_certext=yes + enable_sep=yes + enable_hkdf=yes + enable_dsa=yes + enable_ecccustcurves=yes + enable_compkey=yes + enable_curve25519=yes + enable_ed25519=yes + enable_fpecc=yes + enable_eccencrypt=yes + enable_psk=yes + enable_idea=yes + enable_cmac=yes + enable_webserver=yes + enable_hc128=yes + enable_rabbit=yes + enable_ocsp=yes + enable_ocspstapling=yes + enable_ocspstapling2=yes + enable_crl=yes + enable_crl_monitor=yes + enable_sni=yes + enable_maxfragment=yes + enable_alpn=yes + enable_truncatedhmac=yes + enable_supportedcurves=yes + enable_session_ticket=yes + enable_tlsx=yes + enable_pkcs7=yes + enable_scep=yes + enable_srp=yes + enable_certservice=yes + enable_jni=yes + enable_lighty=yes + enable_stunnel=yes + enable_pwdbased=yes +fi + + # SINGLE THREADED AC_ARG_ENABLE([singlethreaded], [ --enable-singlethreaded Enable wolfSSL single threaded (default: disabled)], @@ -156,6 +221,29 @@ then fi +# DTLS-SCTP +AC_ARG_ENABLE([sctp], + [AS_HELP_STRING([--enable-sctp],[Enable wolfSSL DTLS-SCTP support (default: disabled)])], + [ENABLED_SCTP=$enableval], + [ENABLED_SCTP=no]) + +AM_CONDITIONAL([BUILD_SCTP], [test "x$ENABLED_SCTP" = "xyes"]) + +AS_IF([test "x$ENABLED_SCTP" = "xyes"], + [AC_MSG_CHECKING([for SCTP]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( +[[ +#include +#include +]], +[[int s = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); if (s == -1) return 1;]])], +[AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no) + AC_MSG_ERROR([SCTP not available, remove enable-sctp from configure])]) +]) + + # OpenSSH compatibility Build AC_ARG_ENABLE([openssh], [AS_HELP_STRING([--enable-openssh],[Enable OpenSSH compatibility build (default: disabled)])], @@ -454,6 +542,24 @@ fi AM_CONDITIONAL([BUILD_AESCCM], [test "x$ENABLED_AESCCM" = "xyes"]) +# AES-ARM +AC_ARG_ENABLE([armasm], + [AS_HELP_STRING([--enable-armasm],[Enable wolfSSL ARM ASM support (default: disabled)])], + [ ENABLED_ARMASM=$enableval ], + [ ENABLED_ARMASM=no ] + ) +if test "$ENABLED_ARMASM" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ARMASM" + if test "$GCC" = "yes" + then + # GCC needs this flag + AM_CFLAGS="$AM_CFLAGS -mcpu=generic+crypto" + fi +fi + +AM_CONDITIONAL([BUILD_ARMASM], [test "x$ENABLED_ARMASM" = "xyes"]) + # AES-NI AC_ARG_ENABLE([aesni], [AS_HELP_STRING([--enable-aesni],[Enable wolfSSL AES-NI support (default: disabled)])], @@ -1869,6 +1975,18 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SESSION_TICKET" fi +# Extended Master Secret Extension +AC_ARG_ENABLE([extended-master], + [AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: enabled)])], + [ ENABLED_EXTENDED_MASTER=$enableval ], + [ ENABLED_EXTENDED_MASTER=yes ] + ) + +if test "x$ENABLED_EXTENDED_MASTER" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DHAVE_EXTENDED_MASTER" +fi + # TLS Extensions AC_ARG_ENABLE([tlsx], [ --enable-tlsx Enable all TLS Extensions (default: disabled)], @@ -2439,28 +2557,69 @@ AC_ARG_WITH([cavium], AC_MSG_CHECKING([for cavium]) CPPFLAGS="$CPPFLAGS -DHAVE_CAVIUM" - if test "x$withval" == "xyes" ; then - AC_MSG_ERROR([need a PATH for --with-cavium]) - fi - if test "x$withval" != "xno" ; then - trycaviumdir=$withval - fi + if test "x$withval" == "xyes" ; then + AC_MSG_ERROR([need a PATH for --with-cavium]) + fi + if test "x$withval" != "xno" ; then + trycaviumdir=$withval + fi - LDFLAGS="$AM_LDFLAGS $trycaviumdir/api/cavium_common.o" - CPPFLAGS="$CPPFLAGS -I$trycaviumdir/include" + LDFLAGS="$AM_LDFLAGS $trycaviumdir/api/cavium_common.o" + CPPFLAGS="$CPPFLAGS -I$trycaviumdir/include" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "cavium_common.h"]], [[ CspShutdown(CAVIUM_DEV_ID); ]])],[ cavium_linked=yes ],[ cavium_linked=no ]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "cavium_common.h"]], [[ CspShutdown(CAVIUM_DEV_ID); ]])],[ cavium_linked=yes ],[ cavium_linked=no ]) - if test "x$cavium_linked" == "xno" ; then - AC_MSG_ERROR([cavium isn't found. - If it's already installed, specify its path using --with-cavium=/dir/]) - fi - AC_MSG_RESULT([yes]) - enable_shared=no - enable_static=yes + if test "x$cavium_linked" == "xno" ; then + AC_MSG_ERROR([cavium isn't found. + If it's already installed, specify its path using --with-cavium=/dir/]) + fi + AC_MSG_RESULT([yes]) + enable_shared=no + enable_static=yes + ENABLED_CAVIUM=yes + ], + [ ENABLED_CAVIUM=no ] +) + +# cavium V +trycaviumdir="" +AC_ARG_WITH([cavium-v], + [ --with-cavium-v=PATH PATH to Cavium V/software dir ], + [ + AC_MSG_CHECKING([for cavium]) + CPPFLAGS="$CPPFLAGS -DHAVE_CAVIUM -DHAVE_CAVIUM_V" + + if test "x$withval" == "xyes" ; then + AC_MSG_ERROR([need a PATH for --with-cavium]) + fi + if test "x$withval" != "xno" ; then + trycaviumdir=$withval + fi + + LDFLAGS="$AM_LDFLAGS $trycaviumdir/utils/sample_tests/cavium_common.o $trycaviumdir/utils/sample_tests/cavium_sym_crypto.o $trycaviumdir/utils/sample_tests/cavium_asym_crypto.o" + CPPFLAGS="$CPPFLAGS -I$trycaviumdir/include" + + #AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "cavium_common.h"]], [[ CspShutdown(0); ]])],[ cavium_linked=yes ],[ cavium_linked=no ]) + + if test "x$cavium_linked" == "xno" ; then + AC_MSG_ERROR([cavium isn't found. + If it's already installed, specify its path using --with-cavium-v=/dir/]) + fi + AC_MSG_RESULT([yes]) + + enable_shared=no + enable_static=yes + ENABLED_CAVIUM=yes + ENABLED_CAVIUM_V=yes + ], + [ + ENABLED_CAVIUM_=no + ENABLED_CAVIUM_V=no ] ) +AM_CONDITIONAL([BUILD_CAVIUM], [test "x$ENABLED_CAVIUM" = "xyes"]) + # Fast RSA using Intel IPP ippdir="${srcdir}/IPP" @@ -2668,7 +2827,7 @@ AC_ARG_ENABLE([asynccrypt], if test "$ENABLED_ASYNCCRYPT" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ASYNC_CRYPT" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ASYNC_CRYPT -DHAVE_WOLF_EVENT" # if Cavium not enabled the use async simulator for testing if test "x$ENABLED_CAVIUM" = "xno" @@ -2679,6 +2838,9 @@ fi AM_CONDITIONAL([BUILD_ASYNCCRYPT], [test "x$ENABLED_ASYNCCRYPT" = "xyes"]) +AM_CONDITIONAL([BUILD_WOLFEVENT], [test "x$ENABLED_ASYNCCRYPT" = "xyes"]) + + # Session Export AC_ARG_ENABLE([sessionexport], @@ -2777,6 +2939,15 @@ AS_IF([test "x$ENABLED_MAXSTRENGTH" = "xyes" && \ test "x$ENABLED_SSLV3" = "xyes"], [AC_MSG_ERROR([Cannot use Max Strength and SSLv3 at the same time.])]) +AS_IF([test "x$ENABLED_SCTP" = "xyes"], + [AM_CFLAGS="-DWOLFSSL_SCTP $AM_CFLAGS"]) + +# SCTP requires DTLS +AS_IF([test "x$ENABLED_DTLS" = "xno" && \ + test "x$ENABLED_SCTP" = "xyes"], + [AM_CFLAGS="-DWOLFSSL_DTLS $AM_CFLAGS" + ENABLED_DTLS=yes]) + ################################################################################ # OPTIMIZE FLAGS @@ -2986,6 +3157,7 @@ echo " * Filesystem: $ENABLED_FILESYSTEM" echo " * OpenSSH Build: $ENABLED_OPENSSH" echo " * OpenSSL Extra API: $ENABLED_OPENSSLEXTRA" echo " * Max Strength Build: $ENABLED_MAXSTRENGTH" +echo " * Distro Build: $ENABLED_DISTRO" echo " * fastmath: $ENABLED_FASTMATH" echo " * sniffer: $ENABLED_SNIFFER" echo " * snifftest: $ENABLED_SNIFFTEST" @@ -3037,6 +3209,7 @@ echo " * LIGHTY: $ENABLED_LIGHTY" echo " * STUNNEL: $ENABLED_STUNNEL" echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS" echo " * DTLS: $ENABLED_DTLS" +echo " * SCTP: $ENABLED_SCTP" echo " * Old TLS Versions: $ENABLED_OLD_TLS" echo " * SSL version 3.0: $ENABLED_SSLV3" echo " * OCSP: $ENABLED_OCSP" @@ -3056,6 +3229,7 @@ echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT" echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC" echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES" echo " * Session Ticket: $ENABLED_SESSION_TICKET" +echo " * Extended Master Secret: $ENABLED_EXTENDED_MASTER" echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION" echo " * Secure Renegotiation: $ENABLED_SECURE_RENEGOTIATION" echo " * All TLS Extensions: $ENABLED_TLSX" @@ -3069,6 +3243,8 @@ echo " * Examples: $ENABLED_EXAMPLES" echo " * User Crypto: $ENABLED_USER_CRYPTO" echo " * Fast RSA: $ENABLED_FAST_RSA" echo " * Async Crypto: $ENABLED_ASYNCCRYPT" +echo " * Cavium: $ENABLED_CAVIUM" +echo " * ARM ASM: $ENABLED_ARMASM" echo "" echo "---" diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index 8ad064f06c..78ab33dcb2 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -56,11 +56,6 @@ #define AesCcmDecrypt wc_AesCcmDecrypt #endif /* HAVE_AESCCM */ -#ifdef HAVE_CAVIUM - #define AesInitCavium wc_AesInitCavium - #define AesFreeCavium wc_AesFreeCavium -#endif - #endif /* CTAO_CRYPT_AES_H */ #endif /* NO_AES */ diff --git a/cyassl/ctaocrypt/arc4.h b/cyassl/ctaocrypt/arc4.h index 093d8465b7..c99eb3cbda 100644 --- a/cyassl/ctaocrypt/arc4.h +++ b/cyassl/ctaocrypt/arc4.h @@ -26,11 +26,10 @@ /* for arc4 reverse compatibility */ #ifndef NO_RC4 #include - #define CYASSL_ARC4_CAVIUM_MAGIC WOLFSSL_ARC4_CAVIUM_MAGIC #define Arc4Process wc_Arc4Process #define Arc4SetKey wc_Arc4SetKey - #define Arc4InitCavium wc_Arc4InitCavium - #define Arc4FreeCavium wc_Arc4FreeCavium + #define Arc4AsyncInit wc_Arc4AsyncInit + #define Arc4AsyncFree wc_Arc4AsyncFree #endif #endif /* CTAO_CRYPT_ARC4_H */ diff --git a/cyassl/ctaocrypt/des3.h b/cyassl/ctaocrypt/des3.h index 674d96840b..40719554e1 100644 --- a/cyassl/ctaocrypt/des3.h +++ b/cyassl/ctaocrypt/des3.h @@ -39,9 +39,9 @@ #define Des3_CbcEncrypt wc_Des3_CbcEncrypt #define Des3_CbcDecrypt wc_Des3_CbcDecrypt #define Des3_CbcDecryptWithKey wc_Des3_CbcDecryptWithKey -#ifdef HAVE_CAVIUM - #define Des3_InitCavium wc_Des3_InitCavium - #define Des3_FreeCavium wc_Des3_FreeCavium +#ifdef WOLFSSL_ASYNC_CRYPT + #define Des3AsyncInit wc_Des3AsyncInit + #define Des3AsyncFree wc_Des3AsyncFree #endif #endif /* NO_DES3 */ diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index b582395e31..505e44a7ca 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -30,9 +30,9 @@ #define HmacSetKey wc_HmacSetKey #define HmacUpdate wc_HmacUpdate #define HmacFinal wc_HmacFinal -#ifdef HAVE_CAVIUM - #define HmacInitCavium wc_HmacInitCavium - #define HmacFreeCavium wc_HmacFreeCavium +#ifdef WOLFSSL_ASYNC_CRYPT + #define HmacAsyncInit wc_HmacAsyncInit + #define HmacAsyncFree wc_HmacAsyncFree #endif #define CyaSSL_GetHmacMaxSize wolfSSL_GetHmacMaxSize #ifdef HAVE_HKDF diff --git a/cyassl/ctaocrypt/rsa.h b/cyassl/ctaocrypt/rsa.h index 3c8a9f23bf..ecb7de485b 100644 --- a/cyassl/ctaocrypt/rsa.h +++ b/cyassl/ctaocrypt/rsa.h @@ -47,9 +47,9 @@ #define RsaKeyToDer wc_RsaKeyToDer #endif -#ifdef HAVE_CAVIUM - #define RsaInitCavium wc_RsaInitCavium - #define RsaFreeCavium wc_RsaFreeCavium +#ifdef WOLFSSL_ASYNC_CRYPT + #define RsaAsyncInit wc_RsaAsyncInit + #define RsaAsyncFree wc_RsaAsyncFree #endif #endif /* CTAO_CRYPT_RSA_H */ diff --git a/examples/client/client.c b/examples/client/client.c index 0469be812a..14ef262455 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -53,6 +53,10 @@ #include "examples/client/client.h" +#ifdef WOLFSSL_ASYNC_CRYPT + static int devId = INVALID_DEVID; +#endif + /* Note on using port 0: the client standalone example doesn't utilize the * port 0 port sharing; that is used by (1) the server in external control * test mode and (2) the testsuite which uses this code and sets up the correct @@ -78,7 +82,7 @@ static void NonBlockingSSL_Connect(WOLFSSL* ssl) #endif int error = wolfSSL_get_error(ssl, 0); SOCKET_T sockfd = (SOCKET_T)wolfSSL_get_fd(ssl); - int select_ret; + int select_ret = 0; while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE || @@ -91,15 +95,17 @@ static void NonBlockingSSL_Connect(WOLFSSL* ssl) printf("... client would write block\n"); #ifdef WOLFSSL_ASYNC_CRYPT else if (error == WC_PENDING_E) { - ret = AsyncCryptPoll(ssl); + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); if (ret < 0) { break; } else if (ret == 0) { continue; } } #endif -#ifdef WOLFSSL_DTLS - currTimeout = wolfSSL_dtls_get_current_timeout(ssl); -#endif - select_ret = tcp_select(sockfd, currTimeout); + if (error != WC_PENDING_E) { + #ifdef WOLFSSL_DTLS + currTimeout = wolfSSL_dtls_get_current_timeout(ssl); + #endif + select_ret = tcp_select(sockfd, currTimeout); + } if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_ERROR_READY)) { @@ -150,8 +156,10 @@ static void ShowVersions(void) printf("3\n"); } -int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int benchmark, int resumeSession) +/* Measures average time to create, connect and disconnect a connection (TPS). +Benchmark = number of connections. */ +static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, + int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession) { /* time passed in number of connects give average */ int times = benchmark; @@ -174,7 +182,7 @@ int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, if (ssl == NULL) err_sys("unable to get SSL object"); - tcp_connect(&sockfd, host, port, doDTLS, ssl); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl); #ifndef NO_SESSION_CACHE if (benchResume) @@ -209,8 +217,9 @@ int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, return EXIT_SUCCESS; } -int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int throughput) +/* Measures throughput in kbps. Throughput = number of bytes */ +static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, + int dtlsUDP, int dtlsSCTP, int throughput) { double start, conn_time = 0, tx_time = 0, rx_time = 0; SOCKET_T sockfd; @@ -221,7 +230,7 @@ int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, ssl = wolfSSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL object"); - tcp_connect(&sockfd, host, port, doDTLS, ssl); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl); if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } @@ -337,7 +346,8 @@ const char* starttlsCmd[6] = { "QUIT\r\n", }; -int StartTLS_Init(SOCKET_T* sockfd) +/* Initiates the STARTTLS command sequence over TCP */ +static int StartTLS_Init(SOCKET_T* sockfd) { char tmpBuf[256]; @@ -393,7 +403,8 @@ int StartTLS_Init(SOCKET_T* sockfd) return SSL_SUCCESS; } -int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown) +/* Closes down the SMTP connection */ +static int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown) { int ret; char tmpBuf[256]; @@ -455,6 +466,10 @@ static void Usage(void) printf("-g Send server HTTP GET\n"); printf("-u Use UDP DTLS," " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#ifdef WOLFSSL_SCTP + printf("-G Use SCTP DTLS," + " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#endif printf("-m Match domain name in cert\n"); printf("-N Use Non-blocking sockets\n"); printf("-r Resume session\n"); @@ -479,6 +494,9 @@ static void Usage(void) #ifdef HAVE_TRUNCATED_HMAC printf("-T Use Truncated HMAC\n"); #endif +#ifdef HAVE_EXTENDED_MASTER + printf("-n Disable Extended Master Secret\n"); +#endif #ifdef HAVE_OCSP printf("-o Perform OCSP lookup on peer certificate\n"); printf("-O Perform OCSP lookup using as responder\n"); @@ -545,6 +563,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int benchmark = 0; int throughput = 0; int doDTLS = 0; + int dtlsUDP = 0; + int dtlsSCTP = 0; int matchName = 0; int doPeerCheck = 1; int nonBlocking = 0; @@ -592,6 +612,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) byte statusRequest = 0; #endif +#ifdef HAVE_EXTENDED_MASTER + byte disableExtMasterSecret = 0; +#endif #ifdef HAVE_OCSP @@ -634,7 +657,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef WOLFSSL_VXWORKS while ((ch = mygetopt(argc, argv, - "?gdeDusmNrwRitfxXUPCVh:p:v:l:A:c:k:Z:b:zS:F:L:ToO:aB:W:E:M:q:")) + "?gdeDuGsmNrwRitfxXUPCVh:p:v:l:A:c:k:Z:b:zS:F:L:TnoO:aB:W:E:M:q:")) != -1) { switch (ch) { case '?' : @@ -664,7 +687,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) break; case 'u' : - doDTLS = 1; + doDTLS = 1; + dtlsUDP = 1; + break; + + case 'G' : + #ifdef WOLFSSL_SCTP + doDTLS = 1; + dtlsSCTP = 1; + #endif break; case 's' : @@ -832,6 +863,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; + case 'n' : + #ifdef HAVE_EXTENDED_MASTER + disableExtMasterSecret = 1; + #endif + break; + case 'W' : #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) @@ -1106,6 +1143,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } } +#ifdef WOLFSSL_SCTP + if (dtlsSCTP) + wolfSSL_CTX_dtls_set_sctp(ctx); +#endif + #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif @@ -1175,9 +1217,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb); #endif -#ifdef HAVE_CAVIUM - wolfSSL_CTX_UseCavium(ctx, CAVIUM_DEV_ID); -#endif +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_DevOpen(&devId); + if (ret != 0) { + err_sys("Async device open failed"); + } + wolfSSL_CTX_UseAsync(ctx, devId); +#endif /* WOLFSSL_ASYNC_CRYPT */ #ifdef HAVE_SNI if (sniHostName) @@ -1199,17 +1245,24 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS) err_sys("UseSessionTicket failed"); #endif +#ifdef HAVE_EXTENDED_MASTER + if (disableExtMasterSecret) + if (wolfSSL_CTX_DisableExtendedMasterSecret(ctx) != SSL_SUCCESS) + err_sys("DisableExtendedMasterSecret failed"); +#endif if (benchmark) { ((func_args*)args)->return_code = - ClientBenchmarkConnections(ctx, host, port, doDTLS, benchmark, resumeSession); + ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP, + benchmark, resumeSession); wolfSSL_CTX_free(ctx); exit(EXIT_SUCCESS); } if(throughput) { ((func_args*)args)->return_code = - ClientBenchmarkThroughput(ctx, host, port, doDTLS, throughput); + ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP, + throughput); wolfSSL_CTX_free(ctx); exit(EXIT_SUCCESS); } @@ -1295,7 +1348,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - tcp_connect(&sockfd, host, port, doDTLS, ssl); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl); if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } @@ -1343,7 +1396,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) do { #ifdef WOLFSSL_ASYNC_CRYPT if (err == WC_PENDING_E) { - ret = AsyncCryptPoll(ssl); + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); if (ret < 0) { break; } else if (ret == 0) { continue; } } #endif @@ -1474,7 +1527,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - if (doDTLS == 0) { /* don't send alert after "break" command */ + if (dtlsUDP == 0) { /* don't send alert after "break" command */ ret = wolfSSL_shutdown(ssl); if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) wolfSSL_shutdown(ssl); /* bidirectional shutdown */ @@ -1488,7 +1541,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef NO_SESSION_CACHE if (resumeSession) { - if (doDTLS) { + if (dtlsUDP) { #ifdef USE_WINDOWS_API Sleep(500); #elif defined(WOLFSSL_TIRTOS) @@ -1497,7 +1550,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) sleep(1); #endif } - tcp_connect(&sockfd, host, port, doDTLS, sslResume); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, sslResume); if (wolfSSL_set_fd(sslResume, sockfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } @@ -1519,6 +1572,32 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB, (void*)"resumed session"); #endif + #ifdef HAVE_SUPPORTED_CURVES /* add curves to supported curves extension */ + if (wolfSSL_UseSupportedCurve(sslResume, WOLFSSL_ECC_SECP256R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp256r1"); + } + if (wolfSSL_UseSupportedCurve(sslResume, WOLFSSL_ECC_SECP384R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp384r1"); + } + if (wolfSSL_UseSupportedCurve(sslResume, WOLFSSL_ECC_SECP521R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp521r1"); + } + if (wolfSSL_UseSupportedCurve(sslResume, WOLFSSL_ECC_SECP224R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp224r1"); + } + if (wolfSSL_UseSupportedCurve(sslResume, WOLFSSL_ECC_SECP192R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp192r1"); + } + if (wolfSSL_UseSupportedCurve(sslResume, WOLFSSL_ECC_SECP160R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp160r1"); + } + #endif #ifndef WOLFSSL_CALLBACKS if (nonBlocking) { @@ -1622,6 +1701,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ((func_args*)args)->return_code = 0; +#ifdef WOLFSSL_ASYNC_CRYPT + wolfAsync_DevClose(&devId); +#endif + #if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) if (trackMemory) ShowMemoryTracker(); @@ -1650,11 +1733,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { func_args args; -#ifdef HAVE_CAVIUM - int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) - err_sys("Cavium OpenNitroxDevice failed"); -#endif /* HAVE_CAVIUM */ StartTCP(); @@ -1674,10 +1752,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif wolfSSL_Cleanup(); -#ifdef HAVE_CAVIUM - CspShutdown(CAVIUM_DEV_ID); -#endif - #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) err_sys("Failed to free netRandom context"); diff --git a/examples/client/client.h b/examples/client/client.h index 913339ac01..39456a4f5e 100644 --- a/examples/client/client.h +++ b/examples/client/client.h @@ -26,21 +26,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args); -/* Measures average time to create, connect and disconnect a connection (TPS). -Benchmark = number of connections. */ -int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int benchmark, int resumeSession); - -/* Measures throughput in kbps. Throughput = number of bytes */ -int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int throughput); - -/* Initiates the STARTTLS command sequence over TCP */ -int StartTLS_Init(SOCKET_T* sockfd); - -/* Closes down the SMTP connection */ -int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown); - #endif /* WOLFSSL_CLIENT_H */ diff --git a/examples/echoclient/echoclient.c b/examples/echoclient/echoclient.c index 2c5f10b2b7..1c06efa83b 100644 --- a/examples/echoclient/echoclient.c +++ b/examples/echoclient/echoclient.c @@ -52,6 +52,11 @@ #include "examples/echoclient/echoclient.h" +#ifdef WOLFSSL_ASYNC_CRYPT + static int devId = INVALID_DEVID; +#endif + + void echoclient_test(void* args) { SOCKET_T sockfd = 0; @@ -162,12 +167,20 @@ void echoclient_test(void* args) SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif - #if defined(WOLFSSL_MDK_ARM) +#if defined(WOLFSSL_MDK_ARM) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); - #endif +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_DevOpen(&devId); + if (ret != 0) { + err_sys("Async device open failed"); + } + wolfSSL_CTX_UseAsync(ctx, devId); +#endif /* WOLFSSL_ASYNC_CRYPT */ ssl = SSL_new(ctx); - tcp_connect(&sockfd, yasslIP, port, doDTLS, ssl); + tcp_connect(&sockfd, yasslIP, port, doDTLS, 0, ssl); SSL_set_fd(ssl, sockfd); #if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER) @@ -178,7 +191,7 @@ void echoclient_test(void* args) do { #ifdef WOLFSSL_ASYNC_CRYPT if (err == WC_PENDING_E) { - ret = AsyncCryptPoll(ssl); + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); if (ret < 0) { break; } else if (ret == 0) { continue; } } #endif @@ -250,6 +263,10 @@ void echoclient_test(void* args) SSL_free(ssl); SSL_CTX_free(ctx); +#ifdef WOLFSSL_ASYNC_CRYPT + wolfAsync_DevClose(&devId); +#endif + fflush(fout); if (inCreated) fclose(fin); if (outCreated) fclose(fout); @@ -266,12 +283,6 @@ void echoclient_test(void* args) { func_args args; -#ifdef HAVE_CAVIUM - int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) - err_sys("Cavium OpenNitroxDevice failed"); -#endif /* HAVE_CAVIUM */ - #ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0) err_sys("Whitewood netRandom global config failed"); @@ -293,10 +304,6 @@ void echoclient_test(void* args) CyaSSL_Cleanup(); -#ifdef HAVE_CAVIUM - CspShutdown(CAVIUM_DEV_ID); -#endif - #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) err_sys("Failed to free netRandom context"); diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 65ca4c46c2..432525806c 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -53,6 +53,10 @@ #include "examples/echoserver/echoserver.h" +#ifdef WOLFSSL_ASYNC_CRYPT + static int devId = INVALID_DEVID; +#endif + #define SVR_COMMAND_SIZE 256 static void SignalReady(void* args, word16 port) @@ -132,7 +136,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) fdOpenSession(Task_self()); #endif - tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); + tcp_listen(&sockfd, &port, useAnyAddr, doDTLS, 0); #if defined(CYASSL_DTLS) method = CyaDTLSv1_2_server_method(); @@ -226,6 +230,14 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) #endif } +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_DevOpen(&devId); + if (ret != 0) { + err_sys("Async device open failed"); + } + wolfSSL_CTX_UseAsync(ctx, devId); +#endif /* WOLFSSL_ASYNC_CRYPT */ + SignalReady(args, port); while (!shutDown) { @@ -272,7 +284,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) do { #ifdef WOLFSSL_ASYNC_CRYPT if (err == WC_PENDING_E) { - ret = AsyncCryptPoll(ssl); + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); if (ret < 0) { break; } else if (ret == 0) { continue; } } #endif @@ -361,7 +373,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) CyaSSL_free(ssl); CloseSocket(clientfd); #ifdef CYASSL_DTLS - tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); + tcp_listen(&sockfd, &port, useAnyAddr, doDTLS, 0); SignalReady(args, port); #endif } @@ -390,6 +402,10 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) TicketCleanup(); #endif +#ifdef WOLFSSL_ASYNC_CRYPT + wolfAsync_DevClose(&devId); +#endif + #ifndef CYASSL_TIRTOS return 0; #endif @@ -403,12 +419,6 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) { func_args args; -#ifdef HAVE_CAVIUM - int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) - err_sys("Cavium OpenNitroxDevice failed"); -#endif /* HAVE_CAVIUM */ - #ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0) err_sys("Whitewood netRandom global config failed"); @@ -427,10 +437,6 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) echoserver_test(&args); CyaSSL_Cleanup(); -#ifdef HAVE_CAVIUM - CspShutdown(CAVIUM_DEV_ID); -#endif - #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) err_sys("Failed to free netRandom context"); diff --git a/examples/include.am b/examples/include.am index e06bc86a17..66b82b1cdd 100644 --- a/examples/include.am +++ b/examples/include.am @@ -5,3 +5,4 @@ include examples/client/include.am include examples/echoclient/include.am include examples/echoserver/include.am include examples/server/include.am +include examples/sctp/include.am diff --git a/examples/sctp/include.am b/examples/sctp/include.am new file mode 100644 index 0000000000..ae970b40b3 --- /dev/null +++ b/examples/sctp/include.am @@ -0,0 +1,38 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + + +if BUILD_SCTP +if BUILD_EXAMPLE_SERVERS +noinst_PROGRAMS += \ + examples/sctp/sctp-server \ + examples/sctp/sctp-server-dtls +examples_sctp_sctp_server_SOURCES = examples/sctp/sctp-server.c +examples_sctp_sctp_server_LDADD = $(LIB_STATIC_ADD) +examples_sctp_sctp_server_dtls_SOURCES = examples/sctp/sctp-server-dtls.c +examples_sctp_sctp_server_dtls_LDADD = src/libwolfssl.la $(LIB_STATIC_ADD) +examples_sctp_sctp_server_dtls_DEPENDENCIES = src/libwolfssl.la +endif +if BUILD_EXAMPLE_CLIENTS +noinst_PROGRAMS += \ + examples/sctp/sctp-client \ + examples/sctp/sctp-client-dtls +examples_sctp_sctp_client_SOURCES = examples/sctp/sctp-client.c +examples_sctp_sctp_client_LDADD = $(LIB_STATIC_ADD) +examples_sctp_sctp_client_dtls_SOURCES = examples/sctp/sctp-client-dtls.c +examples_sctp_sctp_client_dtls_LDADD = src/libwolfssl.la $(LIB_STATIC_ADD) +examples_sctp_sctp_client_dtls_DEPENDENCIES = src/libwolfssl.la +endif +endif + +dist_example_DATA += \ + examples/sctp/sctp-server.c \ + examples/sctp/sctp-server-dtls.c \ + examples/sctp/sctp-client.c \ + examples/sctp/sctp-client-dtls.c +DISTCLEANFILES += \ + examples/sctp/.libs/sctp-server \ + examples/sctp/.libs/sctp-server-dtls \ + examples/sctp/.libs/sctp-client \ + examples/sctp/.libs/sctp-client-dtls diff --git a/examples/sctp/sctp-client-dtls.c b/examples/sctp/sctp-client-dtls.c new file mode 100644 index 0000000000..f07051795f --- /dev/null +++ b/examples/sctp/sctp-client-dtls.c @@ -0,0 +1,125 @@ +/* sctp-client-dtls.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* sctp */ +#include +#include +#include +#include + +/* std */ +#include +#include +#include +#include + +/* wolfssl */ +#include +#include + + + +#define cacert "./certs/ca-cert.pem" + +static int err_sys(const char* msg) +{ + perror(msg); + exit(EXIT_FAILURE); +} + +int main() +{ + int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); + + if (sd < 0) + err_sys("sctp socket error"); + + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr("127.0.0.1"); + sa.sin_port = htons(12345); + + int ret = connect(sd, (struct sockaddr*)&sa, sizeof(sa)); + if (ret < 0) + err_sys("sctp connect error"); + + const char* response = "hello there"; + char buffer[80]; + + WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()); + if (ctx == NULL) + err_sys("ctx new dtls client failed"); + + ret = wolfSSL_CTX_dtls_set_sctp(ctx); + if (ret != SSL_SUCCESS) + err_sys("set sctp mode failed"); + + ret = wolfSSL_CTX_load_verify_locations(ctx, cacert, NULL); + if (ret != SSL_SUCCESS) + err_sys("ca cert error"); + + WOLFSSL* ssl = wolfSSL_new(ctx); + if (ssl == NULL) + err_sys("ssl new dtls client failed"); + + wolfSSL_set_fd(ssl, sd); + + ret = wolfSSL_connect(ssl); + if (ret != SSL_SUCCESS) + err_sys("ssl connect failed"); + + printf("TLS version is %s\n", wolfSSL_get_version(ssl)); + printf("Cipher Suite is %s\n", + wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl))); + + wolfSSL_write(ssl, response, (int)strlen(response)); + int got = wolfSSL_read(ssl, buffer, sizeof(buffer)); + if (got > 0) { + buffer[got] = 0; + printf("server said: %s\n", buffer); + } + + unsigned char bigBuf[4096]; + unsigned int i; + + for (i = 0; i < (int)sizeof(bigBuf); i++) + bigBuf[i] = (unsigned char)(i & 0xFF); + wolfSSL_write(ssl, bigBuf, sizeof(bigBuf)); + memset(bigBuf, 0, sizeof(bigBuf)); + + wolfSSL_read(ssl, bigBuf, sizeof(bigBuf)); + for (i = 0; i < sizeof(bigBuf); i++) { + if (bigBuf[i] != (unsigned char)(i & 0xFF)) { + printf("big message check fail\n"); + break; + } + } + + wolfSSL_shutdown(ssl); + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + + close(sd); + + return 0; +} diff --git a/examples/sctp/sctp-client.c b/examples/sctp/sctp-client.c new file mode 100644 index 0000000000..b601fa4031 --- /dev/null +++ b/examples/sctp/sctp-client.c @@ -0,0 +1,64 @@ +/* sctp-client.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* sctp */ +#include +#include +#include +#include + +/* std */ +#include +#include +#include + +int main() +{ + int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); + + if (sd < 0) + perror("sctp socket error"); + + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr("127.0.0.1"); + sa.sin_port = htons(12345); + + int ret = connect(sd, (struct sockaddr*)&sa, sizeof(sa)); + if (ret < 0) + perror("sctp connect error"); + + const char* msg = "hello sctp"; + char buffer[80]; + + send(sd, msg, strlen(msg), 0); + int got = (int)recv(sd, buffer, sizeof(buffer), 0); + if (got > 0) { + buffer[got] = 0; + printf("server said: %s\n", buffer); + } + + close(sd); + + return 0; +} diff --git a/examples/sctp/sctp-server-dtls.c b/examples/sctp/sctp-server-dtls.c new file mode 100644 index 0000000000..e64c888db5 --- /dev/null +++ b/examples/sctp/sctp-server-dtls.c @@ -0,0 +1,124 @@ +/* sctp-server-dtls.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* sctp */ +#include +#include +#include + +/* std */ +#include +#include +#include +#include + +/* wolfssl */ +#include +#include + + + +#define key "./certs/server-key.pem" +#define cert "./certs/server-cert.pem" + +static int err_sys(const char* msg) +{ + perror(msg); + exit(EXIT_FAILURE); +} + +int main() +{ + int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); + + if (sd < 0) + err_sys("sctp socket error"); + + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_ANY); + sa.sin_port = htons(12345); + + int ret = bind(sd, (struct sockaddr*)&sa, sizeof(sa)); + if (ret < 0) + err_sys("sctp bind error"); + + listen(sd, 3); + + int client_sd = accept(sd, NULL, NULL); + if (client_sd < 0) + err_sys("sctp accept error"); + + const char* response = "well hello to you"; + char buffer[80]; + + WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()); + if (ctx == NULL) + err_sys("ctx new dtls server failed"); + + ret = wolfSSL_CTX_dtls_set_sctp(ctx); + if (ret != SSL_SUCCESS) + err_sys("set sctp mode failed"); + + ret = wolfSSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM); + if (ret != SSL_SUCCESS) + err_sys("use private key error"); + + ret = wolfSSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM); + if (ret != SSL_SUCCESS) + err_sys("use cert error"); + + WOLFSSL* ssl = wolfSSL_new(ctx); + if (ssl == NULL) + err_sys("ssl new dtls server failed"); + + wolfSSL_set_fd(ssl, client_sd); + + ret = wolfSSL_accept(ssl); + if (ret != SSL_SUCCESS) + err_sys("ssl accept failed"); + + printf("TLS version is %s\n", wolfSSL_get_version(ssl)); + printf("Cipher Suite is %s\n", + wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl))); + + int got = wolfSSL_read(ssl, buffer, sizeof(buffer)); + if (got > 0) { + buffer[got] = 0; + printf("client said: %s\n", buffer); + } + wolfSSL_write(ssl, response, (int)strlen(response)); + + unsigned char bigBuf[4096]; + + wolfSSL_read(ssl, bigBuf, sizeof(bigBuf)); + wolfSSL_write(ssl, bigBuf, sizeof(bigBuf)); + + wolfSSL_shutdown(ssl); + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + + close(sd); + + return 0; +} diff --git a/examples/sctp/sctp-server.c b/examples/sctp/sctp-server.c new file mode 100644 index 0000000000..fc0439d364 --- /dev/null +++ b/examples/sctp/sctp-server.c @@ -0,0 +1,70 @@ +/* sctp-server.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* sctp */ +#include +#include +#include + +/* std */ +#include +#include +#include + +int main() +{ + int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); + + if (sd < 0) + perror("sctp socket error"); + + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_ANY); + sa.sin_port = htons(12345); + + int ret = bind(sd, (struct sockaddr*)&sa, sizeof(sa)); + if (ret < 0) + perror("sctp bind error"); + + listen(sd, 3); + + int client_sd = accept(sd, NULL, NULL); + if (client_sd < 0) + perror("sctp accept error"); + + const char* response = "hi there"; + char buffer[80]; + + int got = (int)recv(client_sd, buffer, sizeof(buffer), 0); + if (got > 0) { + buffer[got] = 0; + printf("client said: %s\n", buffer); + } + send(client_sd, response, strlen(response), 0); + + + close(sd); + + return 0; +} diff --git a/examples/server/server.c b/examples/server/server.c index b5dc3de2d2..de3b09960f 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -55,6 +55,10 @@ #include "examples/server/server.h" +#ifdef WOLFSSL_ASYNC_CRYPT + static int devId = INVALID_DEVID; +#endif + /* Note on using port 0: if the server uses port 0 to bind an ephemeral port * number and is using the ready file for scripted testing, the code in * test.h will write the actual port number into the ready file for use @@ -215,6 +219,10 @@ static void Usage(void) printf("-t Track wolfSSL memory use\n"); printf("-u Use UDP DTLS," " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#ifdef WOLFSSL_SCTP + printf("-G Use SCTP DTLS," + " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#endif printf("-f Fewer packets/group messages\n"); printf("-r Allow one client Resumption\n"); printf("-N Use Non-blocking sockets\n"); @@ -271,6 +279,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int usePskPlus = 0; int useAnon = 0; int doDTLS = 0; + int dtlsUDP = 0; + int dtlsSCTP = 0; int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; @@ -366,7 +376,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) useAnyAddr = 1; #else while ((ch = mygetopt(argc, argv, - "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) { + "?jdbstnNuGfrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) { switch (ch) { case '?' : Usage(); @@ -400,6 +410,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) case 'u' : doDTLS = 1; + dtlsUDP = 1; + break; + + case 'G' : + #ifdef WOLFSSL_SCTP + doDTLS = 1; + dtlsSCTP = 1; + #endif break; case 'f' : @@ -559,6 +577,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) myoptind = 0; /* reset for test cases */ #endif /* !WOLFSSL_VXWORKS */ + /* Can only use DTLS over UDP or SCTP, can't do both. */ + if (dtlsUDP && dtlsSCTP) { + err_sys("Cannot use DTLS with both UDP and SCTP."); + } + /* sort out DTLS versus TLS versions */ if (version == CLIENT_INVALID_VERSION) { if (doDTLS) @@ -655,7 +678,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) err_sys("unable to load static memory and create ctx"); #else ctx = SSL_CTX_new(method(NULL)); -#endif +#endif /* WOLFSSL_STATIC_MEMORY */ if (ctx == NULL) err_sys("unable to get ctx"); @@ -685,6 +708,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) if (fewerPackets) CyaSSL_CTX_set_group_messages(ctx); +#ifdef WOLFSSL_SCTP + if (dtlsSCTP) + wolfSSL_CTX_dtls_set_sctp(ctx); +#endif + #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif @@ -806,16 +834,24 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } #endif /* USE_WINDOWS_API */ +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_DevOpen(&devId); + if (ret != 0) { + err_sys("Async device open failed"); + } + wolfSSL_CTX_UseAsync(ctx, devId); +#endif /* WOLFSSL_ASYNC_CRYPT */ + while (1) { /* allow resume option */ if(resumeCount > 1) { - if (doDTLS == 0) { + if (dtlsUDP == 0) { SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); clientfd = accept(sockfd, (struct sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); } else { - tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); + tcp_listen(&sockfd, &port, useAnyAddr, dtlsUDP, dtlsSCTP); clientfd = sockfd; } if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) { @@ -896,7 +932,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) readySignal->srfName = serverReadyFile; } tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, - doDTLS, serverReadyFile ? 1 : 0, doListen); + dtlsUDP, dtlsSCTP, serverReadyFile ? 1 : 0, doListen); doListen = 0; /* Don't listen next time */ if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) { @@ -911,7 +947,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif #ifdef WOLFSSL_DTLS - if (doDTLS) { + if (doDTLS && dtlsUDP) { SOCKADDR_IN_T cliaddr; byte b[1500]; int n; @@ -947,7 +983,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) do { #ifdef WOLFSSL_ASYNC_CRYPT if (err == WC_PENDING_E) { - ret = AsyncCryptPoll(ssl); + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); if (ret < 0) { break; } else if (ret == 0) { continue; } } #endif @@ -1027,7 +1063,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) Task_yield(); #endif - if (doDTLS == 0) { + if (dtlsUDP == 0) { ret = SSL_shutdown(ssl); if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) SSL_shutdown(ssl); /* bidirectional shutdown */ @@ -1088,6 +1124,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) TicketCleanup(); #endif +#ifdef WOLFSSL_ASYNC_CRYPT + wolfAsync_DevClose(&devId); +#endif + /* There are use cases when these assignments are not read. To avoid * potential confusion those warnings have been handled here. */ @@ -1112,11 +1152,6 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) func_args args; tcp_ready ready; -#ifdef HAVE_CAVIUM - int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) - err_sys("Cavium OpenNitroxDevice failed"); -#endif /* HAVE_CAVIUM */ StartTCP(); @@ -1139,10 +1174,6 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) CyaSSL_Cleanup(); FreeTcpReady(&ready); -#ifdef HAVE_CAVIUM - CspShutdown(CAVIUM_DEV_ID); -#endif - #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) err_sys("Failed to free netRandom context"); diff --git a/mcapi/crypto.c b/mcapi/crypto.c index c8a99f5795..d0216035d2 100644 --- a/mcapi/crypto.c +++ b/mcapi/crypto.c @@ -223,6 +223,7 @@ int CRYPT_SHA512_Finalize(CRYPT_SHA512_CTX* sha512, unsigned char* digest) int CRYPT_HMAC_SetKey(CRYPT_HMAC_CTX* hmac, int type, const unsigned char* key, unsigned int sz) { + /* compile-time check to verify CRYPT_HMAC_CTX is large enough to hold Hmac */ typedef char hmac_test[sizeof(CRYPT_HMAC_CTX) >= sizeof(Hmac) ? 1 : -1]; (void)sizeof(hmac_test); diff --git a/mcapi/crypto.h b/mcapi/crypto.h index 8fe3236310..3a6a87a6f3 100644 --- a/mcapi/crypto.h +++ b/mcapi/crypto.h @@ -104,7 +104,7 @@ enum { /* HMAC */ typedef struct CRYPT_HMAC_CTX { - long long holder[67]; /* big enough to hold internal, but check on init */ + long long holder[68]; /* big enough to hold internal, but check on init */ } CRYPT_HMAC_CTX; int CRYPT_HMAC_SetKey(CRYPT_HMAC_CTX*, int, const unsigned char*, unsigned int); diff --git a/scripts/ocsp-stapling.test b/scripts/ocsp-stapling.test index 82869ca281..e8984b0aa1 100755 --- a/scripts/ocsp-stapling.test +++ b/scripts/ocsp-stapling.test @@ -25,14 +25,14 @@ sleep 1 # client test against our own server - GOOD CERT ./examples/server/server -c certs/ocsp/server1-cert.pem -k certs/ocsp/server1-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 1 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "\n\nClient connection failed" && exit 1 # client test against our own server - REVOKED CERT ./examples/server/server -c certs/ocsp/server2-cert.pem -k certs/ocsp/server2-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 1 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 RESULT=$? [ $RESULT -ne 1 ] && echo -e "\n\nClient connection suceeded $RESULT" && exit 1 diff --git a/scripts/ocsp-stapling2.test b/scripts/ocsp-stapling2.test index 9bdc2f5d93..16bd818233 100755 --- a/scripts/ocsp-stapling2.test +++ b/scripts/ocsp-stapling2.test @@ -16,39 +16,39 @@ sleep 1 # client test against our own server - GOOD CERTS ./examples/server/server -c certs/ocsp/server3-cert.pem -k certs/ocsp/server3-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 1 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "\n\nClient connection failed" && exit 1 ./examples/server/server -c certs/ocsp/server3-cert.pem -k certs/ocsp/server3-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 2 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 2 RESULT=$? [ $RESULT -ne 0 ] && echo -e "\n\nClient connection failed" && exit 1 # client test against our own server - REVOKED SERVER CERT ./examples/server/server -c certs/ocsp/server4-cert.pem -k certs/ocsp/server4-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 1 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 RESULT=$? [ $RESULT -ne 1 ] && echo -e "\n\nClient connection suceeded $RESULT" && exit 1 ./examples/server/server -c certs/ocsp/server4-cert.pem -k certs/ocsp/server4-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 2 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 2 RESULT=$? [ $RESULT -ne 1 ] && echo -e "\n\nClient connection suceeded $RESULT" && exit 1 # client test against our own server - REVOKED INTERMEDIATE CERT ./examples/server/server -c certs/ocsp/server5-cert.pem -k certs/ocsp/server5-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 1 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "\n\nClient connection failed $RESULT" && exit 1 ./examples/server/server -c certs/ocsp/server5-cert.pem -k certs/ocsp/server5-key.pem & sleep 1 -./examples/client/client -X -C -A certs/ocsp/root-ca-cert.pem -W 2 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 2 RESULT=$? [ $RESULT -ne 1 ] && echo -e "\n\nClient connection suceeded $RESULT" && exit 1 diff --git a/scripts/resume.test b/scripts/resume.test index 337c30a76c..6b6ad488ec 100755 --- a/scripts/resume.test +++ b/scripts/resume.test @@ -5,6 +5,7 @@ # need a unique resume port since may run the same time as testsuite # use server port zero hack to get one resume_string="reused" +ems_string="Extended\ Master\ Secret" resume_port=0 no_pid=-1 server_pid=$no_pid @@ -41,57 +42,72 @@ do_trap() { exit -1 } +do_test() { + echo -e "\nStarting example server for resume test...\n" + + remove_ready_file + ./examples/server/server -r -R $ready_file -p $resume_port & + server_pid=$! + + while [ ! -s $ready_file -a "$counter" -lt 20 ]; do + echo -e "waiting for ready file..." + sleep 0.1 + counter=$((counter+ 1)) + done + + if test -e $ready_file; then + echo -e "found ready file, starting client..." + else + echo -e "NO ready file ending test..." + do_cleanup + exit 1 + fi + + # get created port 0 ephemeral port + resume_port=`cat $ready_file` + + capture_out=$(./examples/client/client $1 -r -p $resume_port 2>&1) + client_result=$? + + if [ $client_result != 0 ] + then + echo -e "client failed!" + do_cleanup + exit 1 + fi + + wait $server_pid + server_result=$? + remove_ready_file + + if [ $server_result != 0 ] + then + echo -e "client failed!" + exit 1 + fi + + case "$capture_out" in + *$resume_string*) + echo "resumed session" ;; + *) + echo "did NOT resume session as expected" + exit 1 + ;; + esac +} + trap do_trap INT TERM -echo -e "\nStarting example server for resume test...\n" +do_test -remove_ready_file -./examples/server/server -r -R $ready_file -p $resume_port & -server_pid=$! - -while [ ! -s $ready_file -a "$counter" -lt 20 ]; do - echo -e "waiting for ready file..." - sleep 0.1 - counter=$((counter+ 1)) -done - -if test -e $ready_file; then - echo -e "found ready file, starting client..." -else - echo -e "NO ready file ending test..." - do_cleanup - exit 1 -fi - -# get created port 0 ephemeral port -resume_port=`cat $ready_file` - -capture_out=$(./examples/client/client -r -p $resume_port 2>&1) -client_result=$? - -if [ $client_result != 0 ] -then - echo -e "client failed!" - do_cleanup - exit 1 -fi - -wait $server_pid -server_result=$? -remove_ready_file - -if [ $server_result != 0 ] -then - echo -e "client failed!" - exit 1 -fi - -case "$capture_out" in -*$resume_string*) - echo "resumed session" ;; +# Check the client for the extended master secret disable option. If +# present we need to run the test twice. +options_check=`./examples/client/client -?` +case "$options_check" in +*$ems_string*) + echo -e "\nRepeating resume test without extended master secret..." + do_test -n ;; *) - echo "did NOT resume session as expected" - exit 1 ;; esac diff --git a/src/include.am b/src/include.am index 5044bd9a47..9e874eaf75 100644 --- a/src/include.am +++ b/src/include.am @@ -62,9 +62,22 @@ endif src_libwolfssl_la_SOURCES += \ wolfcrypt/src/hmac.c \ wolfcrypt/src/random.c \ - wolfcrypt/src/sha256.c \ wolfcrypt/src/hash.c +if BUILD_ARMASM +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-sha256.c +else +src_libwolfssl_la_SOURCES += wolfcrypt/src/sha256.c +endif + +if BUILD_WOLFEVENT +src_libwolfssl_la_SOURCES += wolfcrypt/src/wolfevent.c +endif + +if BUILD_ASYNCCRYPT +src_libwolfssl_la_SOURCES += wolfcrypt/src/async.c +endif + if !BUILD_USER_RSA if BUILD_RSA if BUILD_FAST_RSA @@ -254,8 +267,4 @@ if BUILD_SNIFFER src_libwolfssl_la_SOURCES += src/sniffer.c endif -if BUILD_ASYNCCRYPT -src_libwolfssl_la_SOURCES += src/async.c -endif - endif # !BUILD_CRYPTONLY diff --git a/src/internal.c b/src/internal.c index 0fba76ab67..de6a8e6f99 100755 --- a/src/internal.c +++ b/src/internal.c @@ -195,6 +195,22 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) } +/* If SCTP is not enabled returns the state of the dtls option. + * If SCTP is enabled returns dtls && !sctp. */ +static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) +{ + int result = ssl->options.dtls; + + if (result) { +#ifdef WOLFSSL_SCTP + result = !ssl->options.dtlsSctp; +#endif + } + + return result; +} + + #ifdef HAVE_QSH /* free all structs that where used with QSH */ static int QSH_FreeAll(WOLFSSL* ssl) @@ -588,15 +604,15 @@ static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) exp[idx++] = keys->encryptionOn; exp[idx++] = keys->decryptedCur; - #ifdef WORD64_AVAILABLE +#ifdef WORD64_AVAILABLE c64toa(keys->dtls_state.window, exp + idx); idx += OPAQUE64_LEN; c64toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE64_LEN; - #else +#else c32toa(keys->dtls_state.window, exp + idx); idx += OPAQUE32_LEN; c32toa(0, exp + idx); idx += OPAQUE32_LEN; c32toa(keys->dtls_state.prevWindow, exp + idx); idx += OPAQUE32_LEN; c32toa(0, exp + idx); idx += OPAQUE32_LEN; - #endif +#endif #ifdef HAVE_TRUNCATED_HMAC sz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ: ssl->specs.hash_size; @@ -713,15 +729,15 @@ static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver) keys->encryptionOn = exp[idx++]; keys->decryptedCur = exp[idx++]; - #ifdef WORD64_AVAILABLE +#ifdef WORD64_AVAILABLE ato64(exp + idx, &keys->dtls_state.window); idx += OPAQUE64_LEN; ato64(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE64_LEN; - #else +#else ato32(exp + idx, &keys->dtls_state.window); idx += OPAQUE32_LEN; ato32(exp + idx, 0); idx += OPAQUE32_LEN; ato32(exp + idx, &keys->dtls_state.prevWindow); idx += OPAQUE32_LEN; ato32(exp + idx, 0); idx += OPAQUE32_LEN; - #endif +#endif #ifdef HAVE_TRUNCATED_HMAC ssl->truncated_hmac = exp[idx++]; @@ -1300,61 +1316,6 @@ int wolfSSL_dtls_import_internal(WOLFSSL* ssl, byte* buf, word32 sz) #endif /* WOLFSSL_SESSION_EXPORT */ -#ifdef HAVE_WOLF_EVENT -int wolfSSL_EventInit(WOLFSSL* ssl, WOLF_EVENT_TYPE type) -{ - if (!ssl) { - return BAD_FUNC_ARG; - } - - if (ssl->event.pending) { - WOLFSSL_MSG("ssl.event already pending!"); - return BAD_COND_E; - } - - XMEMSET(&ssl->event, 0, sizeof(WOLF_EVENT)); - ssl->event.ssl = ssl; - ssl->event.type = type; - - return 0; -} - -int wolfSSL_CTX_EventPush(WOLFSSL_CTX* ctx, WOLF_EVENT* event) -{ - int ret; - - if (ctx == NULL || event == NULL) { - return BAD_FUNC_ARG; - } - -#ifndef SINGLE_THREADED - if (LockMutex(&ctx->event_queue.lock) != 0) { - return BAD_MUTEX_E; - } -#endif - - /* Setup event */ - event->next = NULL; - event->pending = 1; - - if (ctx->event_queue.tail == NULL) { - ctx->event_queue.head = event; - } - else { - ctx->event_queue.tail->next = event; - } - ctx->event_queue.tail = event; /* add to the end either way */ - ret = 0; - -#ifndef SINGLE_THREADED - UnLockMutex(&ctx->event_queue.lock); -#endif - - return ret; -} -#endif /* HAVE_WOLF_EVENT */ - - void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv) { method->version = pv; @@ -1366,6 +1327,8 @@ void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv) /* Initialize SSL context, return 0 on success */ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) { + int ret = 0; + XMEMSET(ctx, 0, sizeof(WOLFSSL_CTX)); ctx->method = method; @@ -1424,8 +1387,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) } #endif -#ifdef HAVE_CAVIUM - ctx->devId = NO_CAVIUM_DEVICE; + ctx->devId = INVALID_DEVID; + +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + ctx->dtlsMtuSz = MAX_RECORD_SIZE; #endif #ifndef NO_CERTS @@ -1436,23 +1401,31 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) } #endif +#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT) + if (method->side == WOLFSSL_CLIENT_END) { + if ((method->version.major == SSLv3_MAJOR) && + (method->version.minor >= TLSv1_MINOR)) { + + ctx->haveEMS = 1; + } +#ifdef WOLFSSL_DTLS + if (method->version.major == DTLS_MAJOR) + ctx->haveEMS = 1; +#endif /* WOLFSSL_DTLS */ + } +#endif /* HAVE_EXTENDED_MASTER && !NO_WOLFSSL_CLIENT */ + #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT; #endif #ifdef HAVE_WOLF_EVENT - XMEMSET(&ctx->event_queue, 0, sizeof(WOLF_EVENT_QUEUE)); - #ifndef SINGLE_THREADED - if (InitMutex(&ctx->event_queue.lock) < 0) { - WOLFSSL_MSG("Mutex error on CTX event queue init"); - return BAD_MUTEX_E; - } - #endif + ret = wolfEventQueue_Init(&ctx->event_queue); #endif /* HAVE_WOLF_EVENT */ ctx->heap = heap; /* wolfSSL_CTX_load_static_memory sets */ - return 0; + return ret; } @@ -1464,9 +1437,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) (void)i; #ifdef HAVE_WOLF_EVENT - #ifndef SINGLE_THREADED - FreeMutex(&ctx->event_queue.lock); - #endif + wolfEventQueue_Free(&ctx->event_queue); #endif /* HAVE_WOLF_EVENT */ XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD); @@ -1528,7 +1499,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) } #endif } -#endif +#endif /* WOLFSSL_STATIC_MEMORY */ } @@ -1616,30 +1587,30 @@ void FreeCiphers(WOLFSSL* ssl) { (void)ssl; #ifdef BUILD_ARC4 - #ifdef HAVE_CAVIUM - if (ssl->devId != NO_CAVIUM_DEVICE) { - wc_Arc4FreeCavium(ssl->encrypt.arc4); - wc_Arc4FreeCavium(ssl->decrypt.arc4); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ssl->devId != INVALID_DEVID) { + wc_Arc4AsyncFree(ssl->encrypt.arc4); + wc_Arc4AsyncFree(ssl->decrypt.arc4); } #endif XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif #ifdef BUILD_DES3 - #ifdef HAVE_CAVIUM - if (ssl->devId != NO_CAVIUM_DEVICE) { - wc_Des3_FreeCavium(ssl->encrypt.des3); - wc_Des3_FreeCavium(ssl->decrypt.des3); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ssl->devId != INVALID_DEVID) { + wc_Des3AsyncFree(ssl->encrypt.des3); + wc_Des3AsyncFree(ssl->decrypt.des3); } #endif XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER); XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif #ifdef BUILD_AES - #ifdef HAVE_CAVIUM - if (ssl->devId != NO_CAVIUM_DEVICE) { - wc_AesFreeCavium(ssl->encrypt.aes); - wc_AesFreeCavium(ssl->decrypt.aes); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ssl->devId != INVALID_DEVID) { + wc_AesAsyncFree(ssl->encrypt.aes); + wc_AesAsyncFree(ssl->decrypt.aes); } #endif XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER); @@ -2681,24 +2652,7 @@ int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, (void)keySz; (void)ctx; -#if defined(WOLFSSL_ASYNC_CRYPT_TEST) - if (ssl->options.side == WOLFSSL_SERVER_END && - ssl->asyncCryptTest.type == ASYNC_TEST_NONE) - { - ssl->asyncCryptTest.type = ASYNC_TEST_RSA_SIGN; - ssl->asyncCryptTest.rsaSign.in = in; - ssl->asyncCryptTest.rsaSign.inSz = inSz; - ssl->asyncCryptTest.rsaSign.out = out; - ssl->asyncCryptTest.rsaSign.outSz = outSz; - ssl->asyncCryptTest.rsaSign.keyBuf = keyBuf; - ssl->asyncCryptTest.rsaSign.keySz = keySz; - ssl->asyncCryptTest.rsaSign.key = key; - #if defined(HAVE_PK_CALLBACKS) - ssl->asyncCryptTest.ctx = ctx; - #endif - return WC_PENDING_E; - } -#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ + WOLFSSL_ENTER("RsaSign"); #if defined(HAVE_PK_CALLBACKS) if (ssl->ctx->RsaSignCb) { @@ -2710,11 +2664,26 @@ int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, { ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, key, ssl->rng); } + + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + /* For positive response return in outSz */ if (ret > 0) { *outSz = ret; ret = 0; } + WOLFSSL_LEAVE("RsaSign", ret); + return ret; } @@ -2728,6 +2697,8 @@ int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz, (void)keySz; (void)ctx; + WOLFSSL_ENTER("RsaVerify"); + #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->RsaVerifyCb) { ret = ssl->ctx->RsaVerifyCb(ssl, in, inSz, out, keyBuf, keySz, ctx); @@ -2737,18 +2708,27 @@ int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz, { ret = wc_RsaSSL_VerifyInline(in, inSz, out, key); } + + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("RsaVerify", ret); + return ret; } /* Verify RSA signature, 0 on success */ -int VerifyRsaSign(WOLFSSL* ssl, const byte* sig, word32 sigSz, +int VerifyRsaSign(WOLFSSL* ssl, byte* verifySig, word32 sigSz, const byte* plain, word32 plainSz, RsaKey* key) { - #ifdef WOLFSSL_SMALL_STACK - byte* verifySig = NULL; - #else - byte verifySig[ENCRYPT_LEN]; - #endif byte* out = NULL; /* inline result */ int ret; @@ -2756,8 +2736,7 @@ int VerifyRsaSign(WOLFSSL* ssl, const byte* sig, word32 sigSz, WOLFSSL_ENTER("VerifyRsaSign"); - if (sig == NULL || plain == NULL || key == NULL) { - WOLFSSL_MSG("Null pointer input"); + if (verifySig == NULL || plain == NULL || key == NULL) { return BAD_FUNC_ARG; } @@ -2766,26 +2745,30 @@ int VerifyRsaSign(WOLFSSL* ssl, const byte* sig, word32 sigSz, return BUFFER_E; } - #ifdef WOLFSSL_SMALL_STACK - verifySig = (byte*)XMALLOC(ENCRYPT_LEN, NULL, - DYNAMIC_TYPE_SIGNATURE); - if (verifySig == NULL) - return MEMORY_ERROR; - #endif - - XMEMCPY(verifySig, sig, sigSz); ret = wc_RsaSSL_VerifyInline(verifySig, sigSz, &out, key); - if (ret != (int)plainSz || !out || XMEMCMP(plain, out, plainSz) != 0) { - WOLFSSL_MSG("RSA Signature verification failed"); - ret = RSA_SIGN_FAULT; - } else { - ret = 0; /* RSA reset */ + if (ret > 0) { + if (ret != (int)plainSz || !out || + XMEMCMP(plain, out, plainSz) != 0) { + WOLFSSL_MSG("RSA Signature verification failed"); + ret = RSA_SIGN_FAULT; + } else { + ret = 0; /* RSA reset */ + } } - #ifdef WOLFSSL_SMALL_STACK - XFREE(verifySig, NULL, DYNAMIC_TYPE_SIGNATURE); - #endif + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("VerifyRsaSign", ret); return ret; } @@ -2800,24 +2783,7 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, (void)keySz; (void)ctx; -#if defined(WOLFSSL_ASYNC_CRYPT_TEST) - if (ssl->options.side == WOLFSSL_SERVER_END && - ssl->asyncCryptTest.type == ASYNC_TEST_NONE) - { - ssl->asyncCryptTest.type = ASYNC_TEST_RSA_DEC; - ssl->asyncCryptTest.rsaDec.in = in; - ssl->asyncCryptTest.rsaDec.inSz = inSz; - ssl->asyncCryptTest.rsaDec.out = out; - ssl->asyncCryptTest.rsaDec.outSz = outSz; - ssl->asyncCryptTest.rsaDec.keyBuf = keyBuf; - ssl->asyncCryptTest.rsaDec.keySz = keySz; - ssl->asyncCryptTest.rsaDec.key = key; - #if defined(HAVE_PK_CALLBACKS) - ssl->asyncCryptTest.ctx = ctx; - #endif - return WC_PENDING_E; - } -#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ + WOLFSSL_ENTER("RsaDec"); #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->RsaDecCb) { @@ -2835,10 +2801,70 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, ret = wc_RsaPrivateDecryptInline(in, inSz, out, key); } + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + /* For positive response return in outSz */ if (ret > 0) { *outSz = ret; ret = 0; } + + WOLFSSL_LEAVE("RsaDec", ret); + + return ret; +} + +int RsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, word32* outSz, + RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx) +{ + int ret; + + (void)ssl; + (void)keyBuf; + (void)keySz; + (void)ctx; + + WOLFSSL_ENTER("RsaEnc"); + +#ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->RsaEncCb) { + ret = ssl->ctx->RsaEncCb(ssl, in, inSz, out, outSz, keyBuf, keySz, + ctx); + } + else +#endif /* HAVE_PK_CALLBACKS */ + { + ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, key, ssl->rng); + } + + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + /* For positive response return in outSz */ + if (ret > 0) { + *outSz = ret; + ret = 0; + } + + WOLFSSL_LEAVE("RsaEnc", ret); + return ret; } @@ -2856,24 +2882,7 @@ int EccSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, (void)keySz; (void)ctx; -#if defined(WOLFSSL_ASYNC_CRYPT_TEST) - if (ssl->options.side == WOLFSSL_SERVER_END && - ssl->asyncCryptTest.type == ASYNC_TEST_NONE) - { - ssl->asyncCryptTest.type = ASYNC_TEST_ECC_SIGN; - ssl->asyncCryptTest.eccSign.in = in; - ssl->asyncCryptTest.eccSign.inSz = inSz; - ssl->asyncCryptTest.eccSign.out = out; - ssl->asyncCryptTest.eccSign.outSz = outSz; - ssl->asyncCryptTest.eccSign.keyBuf = keyBuf; - ssl->asyncCryptTest.eccSign.keySz = keySz; - ssl->asyncCryptTest.eccSign.key = key; - #if defined(HAVE_PK_CALLBACKS) - ssl->asyncCryptTest.ctx = ctx; - #endif - return WC_PENDING_E; - } -#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ + WOLFSSL_ENTER("EccSign"); #if defined(HAVE_PK_CALLBACKS) if (ssl->ctx->EccSignCb) { @@ -2885,10 +2894,24 @@ int EccSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, { ret = wc_ecc_sign_hash(in, inSz, out, outSz, ssl->rng, key); } + + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("EccSign", ret); + return ret; } -int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, +int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out, word32 outSz, ecc_key* key, byte* keyBuf, word32 keySz, void* ctx) { @@ -2899,18 +2922,35 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, (void)keySz; (void)ctx; + WOLFSSL_ENTER("EccVerify"); + #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->EccVerifyCb) { ret = ssl->ctx->EccVerifyCb(ssl, in, inSz, out, outSz, keyBuf, keySz, &verify, ctx); } else -#endif +#endif /* HAVE_PK_CALLBACKS */ { ret = wc_ecc_verify_hash(in, inSz, out, outSz, &verify, key); } - ret = (ret != 0 || verify == 0) ? VERIFY_SIGN_ERROR : 0; + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } + else +#endif /* WOLFSSL_ASYNC_CRYPT */ + { + ret = (ret != 0 || verify == 0) ? VERIFY_SIGN_ERROR : 0; + } + + WOLFSSL_LEAVE("EccVerify", ret); return ret; } @@ -2922,44 +2962,56 @@ int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, (void)ssl; -#if defined(WOLFSSL_ASYNC_CRYPT_TEST) - if (ssl->options.side == WOLFSSL_SERVER_END && - ssl->asyncCryptTest.type == ASYNC_TEST_NONE) - { - ssl->asyncCryptTest.type = ASYNC_TEST_ECC_SHARED_SEC; - ssl->asyncCryptTest.eccSharedSec.private_key = priv_key; - ssl->asyncCryptTest.eccSharedSec.public_key = pub_key; - ssl->asyncCryptTest.eccSharedSec.out = out; - ssl->asyncCryptTest.eccSharedSec.outLen = outSz; - return WC_PENDING_E; - } -#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ + WOLFSSL_ENTER("EccSharedSecret"); ret = wc_ecc_shared_secret(priv_key, pub_key, out, outSz); + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &priv_key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; + } + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("EccSharedSecret", ret); + return ret; } -int EccMakeTempKey(WOLFSSL* ssl) +int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer) { int ret = 0; - if (ssl->eccTempKeyPresent == 0) { - #if defined(WOLFSSL_ASYNC_CRYPT_TEST) - if (ssl->options.side == WOLFSSL_SERVER_END && - ssl->asyncCryptTest.type == ASYNC_TEST_NONE) - { - ssl->asyncCryptTest.type = ASYNC_TEST_ECC_TMPKEY_GEN; - return WC_PENDING_E; - } - #endif /* WOLFSSL_ASYNC_CRYPT_TEST */ + int keySz = 0; - ret = wc_ecc_make_key(ssl->rng, ssl->eccTempKeySz, - ssl->eccTempKey); - if (ret == MP_OKAY) { - ssl->eccTempKeyPresent = 1; - ret = 0; + WOLFSSL_ENTER("EccMakeKey"); + + if (peer == NULL) { + keySz = ssl->eccTempKeySz; + } + else { + keySz = peer->dp->size; + } + + /* TODO: Implement _ex version here */ + ret = wc_ecc_make_key(ssl->rng, keySz, key); + + /* Handle async pending response */ +#if defined(WOLFSSL_ASYNC_CRYPT) + if (ret == WC_PENDING_E) { + ret = wolfAsync_EventInit(&ssl->event, + WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &key->asyncDev); + if (ret == 0) { + ret = WC_PENDING_E; } } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("EccMakeKey", ret); + return ret; } @@ -2979,29 +3031,13 @@ int DhGenKeyPair(WOLFSSL* ssl, int ret; DhKey dhKey; -#if defined(WOLFSSL_ASYNC_CRYPT_TEST) - if (ssl->options.side == WOLFSSL_SERVER_END && - ssl->asyncCryptTest.type == ASYNC_TEST_NONE) - { - ssl->asyncCryptTest.type = ASYNC_TEST_DH_GEN; - ssl->asyncCryptTest.dhGen.p = p; - ssl->asyncCryptTest.dhGen.pSz = pSz; - ssl->asyncCryptTest.dhGen.g = g; - ssl->asyncCryptTest.dhGen.gSz = gSz; - ssl->asyncCryptTest.dhGen.priv = priv; - ssl->asyncCryptTest.dhGen.privSz = privSz; - ssl->asyncCryptTest.dhGen.pub = pub; - ssl->asyncCryptTest.dhGen.pubSz = pubSz; - return WC_PENDING_E; - } -#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ - wc_InitDhKey(&dhKey); ret = wc_DhSetKey(&dhKey, p, pSz, g, gSz); if (ret == 0) { ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng, priv, privSz, pub, pubSz); } wc_FreeDhKey(&dhKey); + return ret; } @@ -3016,27 +3052,6 @@ int DhAgree(WOLFSSL* ssl, int ret; DhKey dhKey; -#if defined(WOLFSSL_ASYNC_CRYPT_TEST) - if (ssl->options.side == WOLFSSL_SERVER_END && - ssl->asyncCryptTest.type == ASYNC_TEST_NONE) - { - ssl->asyncCryptTest.type = ASYNC_TEST_DH_AGREE; - ssl->asyncCryptTest.dhAgree.p = p; - ssl->asyncCryptTest.dhAgree.pSz = pSz; - ssl->asyncCryptTest.dhAgree.g = g; - ssl->asyncCryptTest.dhAgree.gSz = gSz; - ssl->asyncCryptTest.dhAgree.priv = priv; - ssl->asyncCryptTest.dhAgree.privSz = privSz; - ssl->asyncCryptTest.dhAgree.pub = pub; - ssl->asyncCryptTest.dhAgree.pubSz = pubSz; - ssl->asyncCryptTest.dhAgree.otherPub = otherPub; - ssl->asyncCryptTest.dhAgree.otherPubSz = otherPubSz; - ssl->asyncCryptTest.dhAgree.agree = agree; - ssl->asyncCryptTest.dhAgree.agreeSz = agreeSz; - return WC_PENDING_E; - } -#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ - wc_InitDhKey(&dhKey); ret = wc_DhSetKey(&dhKey, p, pSz, g, gSz); if (ret == 0 && pub) { @@ -3172,7 +3187,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) ssl->buffers.key = ctx->privateKey; #endif -#ifdef HAVE_CAVIUM +#ifdef WOLFSSL_ASYNC_CRYPT ssl->devId = ctx->devId; #endif @@ -3321,7 +3336,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) } #else ssl->heap = ctx->heap; /* carry over user heap without static memory */ -#endif +#endif /* WOLFSSL_STATIC_MEMORY */ ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer; ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN; @@ -3343,9 +3358,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */ ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */ #endif -#ifdef WOLFSSL_DTLS - ssl->dtls_expected_rx = MAX_MTU; -#endif ssl->options.serverState = NULL_STATE; ssl->options.clientState = NULL_STATE; @@ -3355,9 +3367,17 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) ssl->options.processReply = doProcessInit; #ifdef WOLFSSL_DTLS + #ifdef WOLFSSL_SCTP + ssl->options.dtlsSctp = ctx->dtlsSctp; + ssl->dtlsMtuSz = ctx->dtlsMtuSz; + ssl->dtls_expected_rx = ssl->dtlsMtuSz; + #else + ssl->dtls_expected_rx = MAX_MTU; + #endif ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT; ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX; ssl->dtls_timeout = ssl->dtls_timeout_init; + ssl->buffers.dtlsCtx.fd = -1; #endif #ifndef NO_OLD_TLS @@ -3367,12 +3387,12 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #endif -#ifdef WOLFSSL_DTLS - ssl->buffers.dtlsCtx.fd = -1; -#endif - ssl->cipher.ssl = ssl; +#ifdef HAVE_EXTENDED_MASTER + ssl->options.haveEMS = ctx->haveEMS; +#endif + #ifdef HAVE_TLS_EXTENSIONS #ifdef HAVE_MAX_FRAGMENT ssl->max_fragment = MAX_RECORD_SIZE; @@ -3380,7 +3400,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #ifdef HAVE_ALPN ssl->alpn_client_list = NULL; #endif -#endif +#endif /* HAVE_TLS_EXTENSIONS */ /* default alert state (none) */ ssl->alert_history.last_rx.code = -1; @@ -3523,6 +3543,13 @@ static void FreeKeyExchange(WOLFSSL* ssl) ssl->buffers.sig.length = 0; } + /* Cleanup digest buffer */ + if (ssl->buffers.digest.buffer) { + XFREE(ssl->buffers.digest.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + ssl->buffers.digest.buffer = NULL; + ssl->buffers.digest.length = 0; + } + /* Free sigKey */ if (ssl->sigKey) { switch (ssl->sigType) @@ -3585,7 +3612,7 @@ void SSL_ResourceFree(WOLFSSL* ssl) XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH); XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH); } -#endif +#endif /* !NO_DH */ #ifndef NO_CERTS ssl->keepCert = 0; /* make sure certificate is free'd */ wolfSSL_UnloadCertsKeys(ssl); @@ -3637,7 +3664,7 @@ void SSL_ResourceFree(WOLFSSL* ssl) wc_ecc_free(ssl->eccTempKey); XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC); } -#endif +#endif /* HAVE_ECC */ #ifdef HAVE_PK_CALLBACKS #ifdef HAVE_ECC XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC); @@ -3728,7 +3755,7 @@ static void HashFinal(WOLFSSL * ssl) { #define HashFinal(ssl) -#endif +#endif /* WOLFSSL_TI_HASH */ /* Free any handshake resources no longer needed */ void FreeHandshakeResources(WOLFSSL* ssl) @@ -3811,7 +3838,7 @@ void FreeHandshakeResources(WOLFSSL* ssl) XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC); ssl->eccTempKey = NULL; } -#endif +#endif /* HAVE_ECC */ #ifndef NO_DH if (ssl->buffers.serverDH_Priv.buffer) { ForceZero(ssl->buffers.serverDH_Priv.buffer, @@ -3828,7 +3855,7 @@ void FreeHandshakeResources(WOLFSSL* ssl) XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH); ssl->buffers.serverDH_P.buffer = NULL; } -#endif +#endif /* !NO_DH */ #ifndef NO_CERTS wolfSSL_UnloadCertsKeys(ssl); #endif @@ -4791,16 +4818,15 @@ retry: return -1; case WOLFSSL_CBIO_ERR_TIMEOUT: - if (ssl->options.dtls) { -#ifdef WOLFSSL_DTLS - if (!ssl->options.handShakeDone && - DtlsPoolTimeout(ssl) == 0 && - DtlsPoolSend(ssl) == 0) { + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl) && + !ssl->options.handShakeDone && + DtlsPoolTimeout(ssl) == 0 && + DtlsPoolSend(ssl) == 0) { - goto retry; - } -#endif + goto retry; } + #endif return -1; default: @@ -5067,7 +5093,7 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls && + if (IsDtlsNotSctpMode(ssl) && (!DtlsCheckWindow(&ssl->keys.dtls_state) || (ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) { return SEQUENCE_ERROR; @@ -6573,14 +6599,14 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("PeerRsaKey Memory error"); keyRet = MEMORY_E; } else { - keyRet = wc_InitRsaKey(ssl->peerRsaKey, - ssl->heap); + keyRet = wc_InitRsaKey_ex(ssl->peerRsaKey, + ssl->heap, ssl->devId); } } else if (ssl->peerRsaKeyPresent) { /* don't leak on reuse */ wc_FreeRsaKey(ssl->peerRsaKey); ssl->peerRsaKeyPresent = 0; - keyRet = wc_InitRsaKey(ssl->peerRsaKey, ssl->heap); + keyRet = wc_InitRsaKey_ex(ssl->peerRsaKey, ssl->heap, ssl->devId); } if (keyRet != 0 || wc_RsaPublicKeyDecode(dCert->publicKey, @@ -6645,12 +6671,14 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("PeerEccDsaKey Memory error"); return MEMORY_E; } - wc_ecc_init_h(ssl->peerEccDsaKey, ssl->heap); + wc_ecc_init_ex(ssl->peerEccDsaKey, ssl->heap, + ssl->devId); } else if (ssl->peerEccDsaKeyPresent) { /* don't leak on reuse */ wc_ecc_free(ssl->peerEccDsaKey); ssl->peerEccDsaKeyPresent = 0; - wc_ecc_init_h(ssl->peerEccDsaKey, ssl->heap); + wc_ecc_init_ex(ssl->peerEccDsaKey, ssl->heap, + ssl->devId); } curveId = wc_ecc_get_oid(dCert->keyOID, NULL, NULL); @@ -7437,7 +7465,8 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* hello_request not hashed */ /* Also, skip hashing the client_hello message here for DTLS. It will be * hashed later if the DTLS cookie is correct. */ - if (type != hello_request && !(ssl->options.dtls && type == client_hello) && + if (type != hello_request && + !(IsDtlsNotSctpMode(ssl) && type == client_hello) && ssl->error != WC_PENDING_E) { ret = HashInput(ssl, input + *inOutIdx, size); if (ret != 0) return ret; @@ -7542,6 +7571,16 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; } + /* if async, offset index so this msg will be processed again */ + if (ret == WC_PENDING_E) { + *inOutIdx -= HANDSHAKE_HEADER_SZ; + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + *inOutIdx -= DTLS_HANDSHAKE_EXTRA; + } + #endif + } + WOLFSSL_LEAVE("DoHandShakeMsgType()", ret); return ret; } @@ -7790,7 +7829,8 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, } *inOutIdx += ssl->keys.padSz; } - ret = DtlsPoolSend(ssl); + if (IsDtlsNotSctpMode(ssl)) + ret = DtlsPoolSend(ssl); } else if (fragSz < size) { /* Since this branch is in order, but fragmented, dtls_msg_list will be @@ -7807,10 +7847,13 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, } else { /* This branch is in order next, and a complete message. */ - ssl->keys.dtls_expected_peer_handshake_number++; ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz); - if (ret == 0 && ssl->dtls_msg_list != NULL) - ret = DtlsMsgDrain(ssl); + if (ret == 0) { + ssl->keys.dtls_expected_peer_handshake_number++; + if (ssl->dtls_msg_list != NULL) { + ret = DtlsMsgDrain(ssl); + } + } } WOLFSSL_LEAVE("DoDtlsHandShakeMsg()", ret); @@ -9177,7 +9220,7 @@ int ProcessReply(WOLFSSL* ssl) ssl->buffers.inputBuffer.length = 0; ssl->buffers.inputBuffer.idx = 0; - if (ssl->options.dtlsHsRetain) { + if (IsDtlsNotSctpMode(ssl) && ssl->options.dtlsHsRetain) { ret = DtlsPoolSend(ssl); if (ret != 0) return ret; @@ -9279,11 +9322,11 @@ int ProcessReply(WOLFSSL* ssl) ssl->keys.decryptedCur = 1; } - if (ssl->options.dtls) { #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl)) { DtlsUpdateWindow(&ssl->keys.dtls_state); - #endif /* WOLFSSL_DTLS */ } + #endif /* WOLFSSL_DTLS */ WOLFSSL_MSG("received record layer msg"); @@ -9336,9 +9379,11 @@ int ProcessReply(WOLFSSL* ssl) if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E) return ret; - ret = DtlsPoolSend(ssl); - if (ret != 0) - return ret; + if (IsDtlsNotSctpMode(ssl)) { + ret = DtlsPoolSend(ssl); + if (ret != 0) + return ret; + } if (ssl->curSize != 1) { WOLFSSL_MSG("Malicious or corrupted" @@ -9529,7 +9574,7 @@ int SendChangeCipher(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -9968,7 +10013,7 @@ int SendFinished(WOLFSSL* ssl) #endif #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, input, headerSz + finishedSz)) != 0) return ret; } @@ -10214,7 +10259,7 @@ int SendCertificate(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -10309,7 +10354,7 @@ int SendCertificateRequest(WOLFSSL* ssl) i += REQ_HEADER_SZ; */ #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -10408,7 +10453,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, ret = HashOutput(ssl, output, sendSz, 0); #ifdef WOLFSSL_DTLS - if (ret == 0 && ssl->options.dtls) + if (ret == 0 && IsDtlsNotSctpMode(ssl)) ret = DtlsPoolSave(ssl, output, sendSz); #endif @@ -10770,8 +10815,13 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) if (ssl->options.handShakeState != HANDSHAKE_DONE) { int err; WOLFSSL_MSG("handshake not complete, trying to finish"); - if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS) + if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS) { + /* if async would block return WANT_WRITE */ + if (ssl->error == WC_PENDING_E) { + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } return err; + } } /* last time system socket output buffer was full, try again to send */ @@ -10802,14 +10852,10 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) #endif for (;;) { -#ifdef HAVE_MAX_FRAGMENT - int len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)); -#else - int len = min(sz - sent, OUTPUT_RECORD_SIZE); -#endif + int len; byte* out; byte* sendBuffer = (byte*)data + sent; /* may switch on comp */ - int buffSz = len; /* may switch on comp */ + int buffSz; /* may switch on comp */ int outputSz; #ifdef HAVE_LIBZ byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA]; @@ -10817,12 +10863,17 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) if (sent == sz) break; + len = min(sz - sent, OUTPUT_RECORD_SIZE); +#ifdef HAVE_MAX_FRAGMENT + len = min(len, ssl->max_fragment); +#endif + #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - len = min(len, MAX_UDP_SIZE); - buffSz = len; + if (IsDtlsNotSctpMode(ssl)) { + len = min(len, MAX_UDP_SIZE); } #endif + buffSz = len; /* check for available size */ outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA; @@ -10899,8 +10950,13 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek) if (ssl->options.handShakeState != HANDSHAKE_DONE) { int err; WOLFSSL_MSG("Handshake not complete, trying to finish"); - if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS) + if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS) { + /* if async would block return WANT_WRITE */ + if (ssl->error == WC_PENDING_E) { + return WOLFSSL_CBIO_ERR_WANT_READ; + } return err; + } } #ifdef HAVE_SECURE_RENEGOTIATION @@ -11124,6 +11180,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case MATCH_SUITE_ERROR : return "can't match cipher suite"; + case COMPRESSION_ERROR : + return "compression mismatch error"; + case BUILD_MSG_ERROR : return "build message failure"; @@ -11379,9 +11438,6 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case OCSP_INVALID_STATUS: return "Invalid OCSP Status Error"; - case ASYNC_NOT_PENDING: - return "Async operation not pending"; - case RSA_KEY_SIZE_E: return "RSA key too small"; @@ -11397,6 +11453,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case CTX_INIT_MUTEX_E: return "Initialize ctx mutex error"; + case EXT_MASTER_SECRET_NEEDED_E: + return "Extended Master Secret must be enabled to resume EMS session"; + default : return "unknown error number"; } @@ -12643,6 +12702,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, ? ssl->session.sessionIDSz : 0; int ret; + word16 extSz = 0; if (ssl->suites == NULL) { WOLFSSL_MSG("Bad suites pointer in SendClientHello"); @@ -12676,11 +12736,19 @@ static void PickHashSigAlgo(WOLFSSL* ssl, if (QSH_Init(ssl) != 0) return MEMORY_E; #endif - length += TLSX_GetRequestSize(ssl); + extSz = TLSX_GetRequestSize(ssl); + if (extSz != 0) + length += extSz; #else - if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) { - length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ; - } + if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) + extSz += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ + + ssl->suites->hashSigAlgoSz; +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) + extSz += HELLO_EXT_SZ; +#endif + if (extSz != 0) + length += extSz + HELLO_EXT_SZ_SZ; #endif sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; @@ -12765,24 +12833,36 @@ static void PickHashSigAlgo(WOLFSSL* ssl, (void)idx; /* suppress analyzer warning, keep idx current */ #else - if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) - { - int i; - /* add in the extensions length */ - c16toa((word16)(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz), - output + idx); - idx += 2; + if (extSz != 0) { + c16toa(extSz, output + idx); + idx += HELLO_EXT_SZ_SZ; - c16toa(HELLO_EXT_SIG_ALGO, output + idx); - idx += 2; - c16toa((word16)(HELLO_EXT_SIGALGO_SZ + ssl->suites->hashSigAlgoSz), - output+idx); - idx += 2; - c16toa(ssl->suites->hashSigAlgoSz, output + idx); - idx += 2; - for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) { - output[idx] = ssl->suites->hashSigAlgo[i]; + if (IsAtLeastTLSv1_2(ssl)) { + if (ssl->suites->hashSigAlgoSz) { + int i; + /* extension type */ + c16toa(HELLO_EXT_SIG_ALGO, output + idx); + idx += HELLO_EXT_TYPE_SZ; + /* extension data length */ + c16toa(HELLO_EXT_SIGALGO_SZ + ssl->suites->hashSigAlgoSz, + output + idx); + idx += HELLO_EXT_SZ_SZ; + /* sig algos length */ + c16toa(ssl->suites->hashSigAlgoSz, output + idx); + idx += HELLO_EXT_SIGALGO_SZ; + for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) { + output[idx] = ssl->suites->hashSigAlgo[i]; + } + } } +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_EXTMS, output + idx); + idx += HELLO_EXT_TYPE_SZ; + c16toa(0, output + idx); + idx += HELLO_EXT_SZ_SZ; + } +#endif } #endif @@ -12808,7 +12888,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -13013,6 +13093,11 @@ static void PickHashSigAlgo(WOLFSSL* ssl, ssl->options.cipherSuite = cs1; compression = input[i++]; + if (compression != NO_COMPRESSION && !ssl->options.usingCompression) { + WOLFSSL_MSG("Server forcing compression w/o support"); + return COMPRESSION_ERROR; + } + if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) { WOLFSSL_MSG("Server refused compression, turning off"); ssl->options.usingCompression = 0; /* turn off if server refused */ @@ -13020,9 +13105,8 @@ static void PickHashSigAlgo(WOLFSSL* ssl, *inOutIdx = i; - - if ( (i - begin) < helloSz) { #ifdef HAVE_TLS_EXTENSIONS + if ( (i - begin) < helloSz) { if (TLSX_SupportExtensions(ssl)) { int ret = 0; word16 totalExtSz; @@ -13044,9 +13128,70 @@ static void PickHashSigAlgo(WOLFSSL* ssl, *inOutIdx = i; } else -#endif *inOutIdx = begin + helloSz; /* skip extensions */ } + else + ssl->options.haveEMS = 0; /* If no extensions, no EMS */ +#else + { + int allowExt = 0; + byte pendingEMS = 0; + + if ( (i - begin) < helloSz) { + if (ssl->version.major == SSLv3_MAJOR && + ssl->version.minor >= TLSv1_MINOR) { + + allowExt = 1; + } +#ifdef WOLFSSL_DTLS + if (ssl->version.major == DTLS_MAJOR) + allowExt = 1; +#endif + + if (allowExt) { + word16 totalExtSz; + + if ((i - begin) + OPAQUE16_LEN > helloSz) + return BUFFER_ERROR; + + ato16(&input[i], &totalExtSz); + i += OPAQUE16_LEN; + + if ((i - begin) + totalExtSz > helloSz) + return BUFFER_ERROR; + + while (totalExtSz) { + word16 extId, extSz; + + if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz) + return BUFFER_ERROR; + + ato16(&input[i], &extId); + i += OPAQUE16_LEN; + ato16(&input[i], &extSz); + i += OPAQUE16_LEN; + + if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz) + return BUFFER_ERROR; + + if (extId == HELLO_EXT_EXTMS) + pendingEMS = 1; + else + i += extSz; + + totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz; + } + + *inOutIdx = i; + } + else + *inOutIdx = begin + helloSz; /* skip extensions */ + } + + if (!pendingEMS && ssl->options.haveEMS) + ssl->options.haveEMS = 0; + } +#endif ssl->options.serverState = SERVER_HELLO_COMPLETE; @@ -13283,926 +13428,902 @@ static void PickHashSigAlgo(WOLFSSL* ssl, #endif /* HAVE_ECC */ - static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, - word32* inOutIdx, word32 size) + +static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, + word32* inOutIdx, word32 size) +{ + int ret = 0; + word16 length = 0; + word32 idx = *inOutIdx, begin = *inOutIdx; +#ifndef NO_RSA + int typeH = 0; +#endif + byte* output = NULL; + byte sigAlgo = ssl->specs.sig_algo; + word16 sigSz = 0; +#if !defined(NO_DH) || defined(HAVE_ECC) + byte* verifySig = NULL; +#endif + + (void)output; + (void)sigSz; + + WOLFSSL_ENTER("DoServerKeyExchange"); + +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_EventPop(&ssl->event, WOLF_EVENT_TYPE_ASYNC_ANY); + if (ret != WC_NOT_PENDING_E) { + WOLF_EVENT_TYPE eType = ssl->event.type; + + /* Clear event */ + XMEMSET(&ssl->event, 0, sizeof(ssl->event)); + + /* Check for error */ + if (ret < 0) { + goto exit_dske; + } + else { + /* Restore variables needed for async */ + idx = ssl->async.idx; + length = ssl->async.length; + output = ssl->async.output; + sigSz = ssl->async.sigSz; + #ifndef NO_RSA + typeH = ssl->async.hashAlgo; + #endif + sigAlgo = ssl->async.sigAlgo; + #if !defined(NO_DH) || defined(HAVE_ECC) + verifySig = ssl->async.data; + #endif + + /* Advance key share state if not wolfCrypt */ + if (eType == WOLF_EVENT_TYPE_ASYNC_WOLFSSL) { + ssl->options.keyShareState++; + } + } + } + else +#endif { - #ifdef HAVE_QSH - word16 name; - int qshSz; - #endif - word16 length = 0; - word32 begin = *inOutIdx; - int ret = 0; + /* Reset state */ + ret = 0; + ssl->options.keyShareState = KEYSHARE_BEGIN; + } - (void)length; /* shut up compiler warnings */ - (void)begin; - (void)ssl; - (void)input; - (void)size; - (void)ret; - - - #ifdef WOLFSSL_CALLBACKS - if (ssl->hsInfoOn) - AddPacketName("ServerKeyExchange", &ssl->handShakeInfo); - if (ssl->toInfoOn) - AddLateName("ServerKeyExchange", &ssl->timeoutInfo); - #endif - - switch (ssl->specs.kea) + switch(ssl->options.keyShareState) + { + case KEYSHARE_BEGIN: { - #ifndef NO_PSK - case psk_kea: - { - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; + #ifdef WOLFSSL_CALLBACKS + if (ssl->hsInfoOn) + AddPacketName("ServerKeyExchange", &ssl->handShakeInfo); + if (ssl->toInfoOn) + AddLateName("ServerKeyExchange", &ssl->timeoutInfo); + #endif + + switch(ssl->specs.kea) + { + #ifndef NO_PSK + case psk_kea: + { + int srvHintLen; + + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + /* get PSK server hint from the wire */ + srvHintLen = min(length, MAX_PSK_ID_LEN - 1); + XMEMCPY(ssl->arrays->server_hint, input + idx, srvHintLen); + ssl->arrays->server_hint[srvHintLen] = 0; + idx += length; + break; + } + #endif /* !NO_PSK */ + #ifndef NO_DH + case diffie_hellman_kea: + { + /* p */ + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + if (length < ssl->options.minDhKeySz) { + WOLFSSL_MSG("Server using a DH key that is too small"); + SendAlert(ssl, alert_fatal, handshake_failure); + ERROR_OUT(DH_KEY_SIZE_E, exit_dske); + } + + ssl->buffers.serverDH_P.buffer = + (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_P.buffer) { + ssl->buffers.serverDH_P.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_dske); + } + + XMEMCPY(ssl->buffers.serverDH_P.buffer, input + idx, length); + idx += length; + + ssl->options.dhKeySz = length; + + /* g */ + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ssl->buffers.serverDH_G.buffer = + (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_G.buffer) { + ssl->buffers.serverDH_G.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_dske); + } + + XMEMCPY(ssl->buffers.serverDH_G.buffer, input + idx, length); + idx += length; + + /* pub */ + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ssl->buffers.serverDH_Pub.buffer = + (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_Pub.buffer) { + ssl->buffers.serverDH_Pub.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_dske); + } + + XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + idx, length); + idx += length; + break; + } + #endif /* !NO_DH */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: + { + byte b; + int curveId, curveOid; + + if ((idx - begin) + ENUM_LEN + OPAQUE16_LEN + OPAQUE8_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + b = input[idx++]; + if (b != named_curve) { + ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske); + } + + idx += 1; /* curve type, eat leading 0 */ + b = input[idx++]; + if ((curveOid = CheckCurveId(b)) < 0) { + ERROR_OUT(ECC_CURVE_ERROR, exit_dske); + } + + length = input[idx++]; + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + if (ssl->peerEccKey == NULL) { + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + ERROR_OUT(MEMORY_E, exit_dske); + } + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dske; + } + } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId); + if (ret != 0) { + goto exit_dske; + } + } + + curveId = wc_ecc_get_oid(curveOid, NULL, NULL); + if (wc_ecc_import_x963_ex(input + idx, length, + ssl->peerEccKey, curveId) != 0) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); + } + + idx += length; + ssl->peerEccKeyPresent = 1; + break; + } + #endif /* HAVE_ECC */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + { + int srvHintLen; + + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + /* get PSK server hint from the wire */ + srvHintLen = min(length, MAX_PSK_ID_LEN - 1); + XMEMCPY(ssl->arrays->server_hint, input + idx, srvHintLen); + ssl->arrays->server_hint[srvHintLen] = 0; + idx += length; + + /* p */ + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + if (length < ssl->options.minDhKeySz) { + WOLFSSL_MSG("Server using a DH key that is too small"); + SendAlert(ssl, alert_fatal, handshake_failure); + ERROR_OUT(DH_KEY_SIZE_E, exit_dske); + } + + ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(length, + ssl->heap, DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_P.buffer) { + ssl->buffers.serverDH_P.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_dske); + } + + XMEMCPY(ssl->buffers.serverDH_P.buffer, input + idx, length); + idx += length; + + ssl->options.dhKeySz = length; + + /* g */ + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(length, + ssl->heap, DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_G.buffer) { + ssl->buffers.serverDH_G.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_dske); + } + + XMEMCPY(ssl->buffers.serverDH_G.buffer, input + idx, length); + idx += length; + + /* pub */ + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(length, + ssl->heap, DYNAMIC_TYPE_DH); + if (ssl->buffers.serverDH_Pub.buffer) { + ssl->buffers.serverDH_Pub.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_dske); + } + + XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + idx, length); + idx += length; + break; + } + #endif /* !NO_DH || !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + byte b; + int curveOid, curveId; + int srvHintLen; + + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + /* get PSK server hint from the wire */ + srvHintLen = min(length, MAX_PSK_ID_LEN - 1); + XMEMCPY(ssl->arrays->server_hint, input + idx, srvHintLen); + ssl->arrays->server_hint[srvHintLen] = 0; + + idx += length; + + if ((idx - begin) + ENUM_LEN + OPAQUE16_LEN + + OPAQUE8_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + /* Check curve name and ID */ + b = input[idx++]; + if (b != named_curve) { + ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske); + } + + idx += 1; /* curve type, eat leading 0 */ + b = input[idx++]; + if ((curveOid = CheckCurveId(b)) < 0) { + ERROR_OUT(ECC_CURVE_ERROR, exit_dske); + } + + length = input[idx++]; + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + if (ssl->peerEccKey == NULL) { + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + ERROR_OUT(MEMORY_E, exit_dske); + } + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId); + if (ret != 0) { + goto exit_dske; + } + } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId); + if (ret != 0) { + goto exit_dske; + } + } + + curveId = wc_ecc_get_oid(curveOid, NULL, NULL); + if (wc_ecc_import_x963_ex(input + idx, length, + ssl->peerEccKey, curveId) != 0) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); + } + + idx += length; + ssl->peerEccKeyPresent = 1; + break; + } + #endif /* HAVE_ECC || !NO_PSK */ + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_dske; } - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_BUILD; + } /* case KEYSHARE_BEGIN */ - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; + case KEYSHARE_BUILD: + { + switch(ssl->specs.kea) + { + case psk_kea: + case dhe_psk_kea: + case ecdhe_psk_kea: + { + /* Nothing to do in this sub-state */ + break; + } + + case diffie_hellman_kea: + case ecc_diffie_hellman_kea: + { + #if defined(NO_DH) && !defined(HAVE_ECC) + ERROR_OUT(NOT_COMPILED_IN, exit_dske); + #else + byte hashAlgo = sha_mac; + enum wc_HashType hashType = WC_HASH_TYPE_NONE; + word16 verifySz; + + if (ssl->options.usingAnon_cipher) { + break; + } + + verifySz = (word16)(idx - begin); + if (verifySz > MAX_DH_SZ) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + if (IsAtLeastTLSv1_2(ssl)) { + if ((idx - begin) + ENUM_LEN + ENUM_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + hashAlgo = input[idx++]; + sigAlgo = input[idx++]; + + switch (hashAlgo) { + case sha512_mac: + #ifdef WOLFSSL_SHA512 + hashType = WC_HASH_TYPE_SHA512; + #endif + break; + case sha384_mac: + #ifdef WOLFSSL_SHA384 + hashType = WC_HASH_TYPE_SHA384; + #endif + break; + case sha256_mac: + #ifndef NO_SHA256 + hashType = WC_HASH_TYPE_SHA256; + #endif + break; + case sha_mac: + #ifndef NO_OLD_TLS + hashType = WC_HASH_TYPE_SHA; + #endif + break; + default: + WOLFSSL_MSG("Bad hash sig algo"); + break; + } + + if (hashType == WC_HASH_TYPE_NONE) { + ERROR_OUT(ALGO_ID_E, exit_dske); + } + } else { + /* only using sha and md5 for rsa */ + #ifndef NO_OLD_TLS + hashType = WC_HASH_TYPE_SHA; + if (sigAlgo == rsa_sa_algo) { + hashType = WC_HASH_TYPE_MD5_SHA; + } + #else + ERROR_OUT(ALGO_ID_E, exit_dske); + #endif + } + #ifndef NO_RSA + typeH = wc_HashGetOID(hashType); + #endif + + /* signature */ + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + ato16(input + idx, &length); + idx += OPAQUE16_LEN; + + if ((idx - begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_dske); + } + + /* buffer for signature */ + ssl->buffers.sig.buffer = (byte*)XMALLOC(SEED_LEN + verifySz, + ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ssl->buffers.sig.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_dske); + } + ssl->buffers.sig.length = SEED_LEN + verifySz; + + /* buffer for hash */ + ssl->buffers.digest.length = wc_HashGetDigestSize(hashType); + ssl->buffers.digest.buffer = (byte*)XMALLOC( + ssl->buffers.digest.length, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (ssl->buffers.digest.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_dske); + } + + /* build message to hash */ + XMEMCPY(ssl->buffers.sig.buffer, + ssl->arrays->clientRandom, RAN_LEN); + XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN], + ssl->arrays->serverRandom, RAN_LEN); + XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN * 2], + input + begin, verifySz); /* message */ + + /* Perform hash */ + ret = wc_Hash(hashType, + ssl->buffers.sig.buffer, ssl->buffers.sig.length, + ssl->buffers.digest.buffer, ssl->buffers.digest.length); + if (ret != 0) { + goto exit_dske; + } + + switch (sigAlgo) + { + #ifndef NO_RSA + case rsa_sa_algo: + { + if (ssl->peerRsaKey == NULL || + !ssl->peerRsaKeyPresent) { + ERROR_OUT(NO_PEER_KEY, exit_dske); + } + break; + } + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + case ecc_dsa_sa_algo: + { + if (!ssl->peerEccDsaKeyPresent) { + ERROR_OUT(NO_PEER_KEY, exit_dske); + } + break; + } + #endif /* HAVE_ECC */ + + default: + ret = ALGO_ID_E; + } /* switch (sigAlgo) */ + + #endif /* NO_DH && !HAVE_ECC */ + break; + } + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_dske; } - XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx, - min(length, MAX_PSK_ID_LEN)); + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_DO; + } /* case KEYSHARE_BUILD */ - ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0; - *inOutIdx += length; + case KEYSHARE_DO: + { + switch(ssl->specs.kea) + { + case psk_kea: + case dhe_psk_kea: + case ecdhe_psk_kea: + { + /* Nothing to do in this sub-state */ + break; + } + + case diffie_hellman_kea: + case ecc_diffie_hellman_kea: + { + #if defined(NO_DH) && !defined(HAVE_ECC) + ERROR_OUT(NOT_COMPILED_IN, exit_dske); + #else + if (ssl->options.usingAnon_cipher) { + break; + } + + if (verifySig == NULL) { + verifySig = (byte*)XMALLOC(length, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (!verifySig) { + ERROR_OUT(MEMORY_E, exit_dske); + } + XMEMCPY(verifySig, input + idx, length); + } + + switch (sigAlgo) + { + #ifndef NO_RSA + case rsa_sa_algo: + { + ret = RsaVerify(ssl, + verifySig, length, + &output, + ssl->peerRsaKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.peerRsaKey.buffer, + ssl->buffers.peerRsaKey.length, + ssl->RsaVerifyCtx + #else + NULL, 0, NULL + #endif + ); + + if (ret >= 0) { + sigSz = (word16)ret; + ret = 0; + } + break; + } + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + case ecc_dsa_sa_algo: + { + ret = EccVerify(ssl, + verifySig, length, + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.peerEccDsaKey.buffer, + ssl->buffers.peerEccDsaKey.length, + ssl->EccVerifyCtx + #else + NULL, 0, NULL + #endif + ); + break; + } + #endif /* HAVE_ECC */ + + default: + ret = ALGO_ID_E; + } /* switch (sigAlgo) */ + #endif /* NO_DH && !HAVE_ECC */ + break; + } + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_dske; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_VERIFY; + } /* case KEYSHARE_DO */ + + case KEYSHARE_VERIFY: + { + switch(ssl->specs.kea) + { + case psk_kea: + case dhe_psk_kea: + case ecdhe_psk_kea: + { + /* Nothing to do in this sub-state */ + break; + } + + case diffie_hellman_kea: + case ecc_diffie_hellman_kea: + { + #if defined(NO_DH) && !defined(HAVE_ECC) + ERROR_OUT(NOT_COMPILED_IN, exit_dske); + #else + if (ssl->options.usingAnon_cipher) { + break; + } + + /* increment index after verify is done */ + idx += length; + + switch(sigAlgo) + { + #ifndef NO_RSA + case rsa_sa_algo: + { + if (IsAtLeastTLSv1_2(ssl)) { + #ifdef WOLFSSL_SMALL_STACK + byte* encodedSig = NULL; + #else + byte encodedSig[MAX_ENCODED_SIG_SZ]; + #endif + word32 encSigSz; + + #ifdef WOLFSSL_SMALL_STACK + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, + ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig == NULL) { + ERROR_OUT(MEMORY_E, exit_dske); + } + #endif + + encSigSz = wc_EncodeSignature(encodedSig, + ssl->buffers.digest.buffer, + ssl->buffers.digest.length, typeH); + if (encSigSz != sigSz || !output || + XMEMCMP(output, encodedSig, + min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) { + ret = VERIFY_SIGN_ERROR; + } + #ifdef WOLFSSL_SMALL_STACK + XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + if (ret != 0) { + goto exit_dske; + } + } + else if (sigSz != FINISHED_SZ || !output || + XMEMCMP(output, ssl->buffers.digest.buffer, + FINISHED_SZ) != 0) { + ERROR_OUT(VERIFY_SIGN_ERROR, exit_dske); + } + break; + } + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + case ecc_dsa_sa_algo: + /* Nothing to do in this algo */ + break; + #endif /* HAVE_ECC */ + default: + ret = ALGO_ID_E; + } /* switch (sigAlgo) */ + #endif /* NO_DH && !HAVE_ECC */ + break; + } + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_dske; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_FINALIZE; + } /* case KEYSHARE_VERIFY */ + + case KEYSHARE_FINALIZE: + { + if (IsEncryptionOn(ssl, 0)) { + idx += ssl->keys.padSz; + } /* QSH extensions */ #ifdef HAVE_QSH if (ssl->peerQSHKeyPresent) { + word16 name; + int qshSz; + /* extension name */ - ato16(input + *inOutIdx, &name); - *inOutIdx += OPAQUE16_LEN; + ato16(input + idx, &name); + idx += OPAQUE16_LEN; if (name == TLSX_QUANTUM_SAFE_HYBRID) { - /* if qshSz is larger than 0 it is the length of buffer - used */ - if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, - size, 0)) < 0) { - return qshSz; + /* if qshSz is larger than 0 it is the length of + buffer used */ + if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + idx, + size, 0)) < 0) { + ERROR_OUT(qshSz, exit_dske); } - *inOutIdx += qshSz; + idx += qshSz; } else { - /* unknown extension sent server ignored - handshake */ - return BUFFER_ERROR; + /* unknown extension sent server ignored handshake */ + ERROR_OUT(BUFFER_ERROR, exit_dske); } } #endif - return 0; - } - #endif - #ifndef NO_DH - case diffie_hellman_kea: + /* Check for error */ + if (ret != 0) { + goto exit_dske; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_END; + } /* case KEYSHARE_FINALIZE */ + + case KEYSHARE_END: { - /* p */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - if (length < ssl->options.minDhKeySz) { - WOLFSSL_MSG("Server using a DH key that is too small"); - SendAlert(ssl, alert_fatal, handshake_failure); - return DH_KEY_SIZE_E; - } - - ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap, - DYNAMIC_TYPE_DH); - - if (ssl->buffers.serverDH_P.buffer) { - ssl->buffers.serverDH_P.length = length; - } - else { - return MEMORY_ERROR; - } - - XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length); - *inOutIdx += length; - - ssl->options.dhKeySz = length; - - /* g */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap, - DYNAMIC_TYPE_DH); - - if (ssl->buffers.serverDH_G.buffer) { - ssl->buffers.serverDH_G.length = length; - } - else { - return MEMORY_ERROR; - } - - XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length); - *inOutIdx += length; - - /* pub */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - ssl->buffers.serverDH_Pub.buffer = - (byte*) XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH); - - if (ssl->buffers.serverDH_Pub.buffer) { - ssl->buffers.serverDH_Pub.length = length; - } - else { - return MEMORY_ERROR; - } - - XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, - length); - *inOutIdx += length; - break; - } /* dh_kea */ - #endif /* NO_DH */ - - #ifdef HAVE_ECC - case ecc_diffie_hellman_kea: - { - byte b; - int curveId, curveOid; - - if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + - OPAQUE8_LEN > size) { - return BUFFER_ERROR; - } - - b = input[(*inOutIdx)++]; - - if (b != named_curve) { - return ECC_CURVETYPE_ERROR; - } - - *inOutIdx += 1; /* curve type, eat leading 0 */ - b = input[(*inOutIdx)++]; - - if ((curveOid = CheckCurveId(b)) < 0) { - return curveOid; - } - - length = input[(*inOutIdx)++]; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - if (ssl->peerEccKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - return MEMORY_E; - } - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); - } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); - } - - curveId = wc_ecc_get_oid(curveOid, NULL, NULL); - if (wc_ecc_import_x963_ex(input + *inOutIdx, length, - ssl->peerEccKey, curveId) != 0) { - return ECC_PEERKEY_ERROR; - } - - *inOutIdx += length; - ssl->peerEccKeyPresent = 1; + /* return index */ + *inOutIdx = idx; + ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; break; } - #endif /* HAVE_ECC */ - - #if !defined(NO_DH) && !defined(NO_PSK) - case dhe_psk_kea: - { - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx, - min(length, MAX_PSK_ID_LEN)); - - ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0; - *inOutIdx += length; - - /* p */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - if (length < ssl->options.minDhKeySz) { - WOLFSSL_MSG("Server using a DH key that is too small"); - SendAlert(ssl, alert_fatal, handshake_failure); - return DH_KEY_SIZE_E; - } - - ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap, - DYNAMIC_TYPE_DH); - - if (ssl->buffers.serverDH_P.buffer) { - ssl->buffers.serverDH_P.length = length; - } - else { - return MEMORY_ERROR; - } - - XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length); - *inOutIdx += length; - - ssl->options.dhKeySz = length; - - /* g */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap, - DYNAMIC_TYPE_DH); - - if (ssl->buffers.serverDH_G.buffer) { - ssl->buffers.serverDH_G.length = length; - } - else { - return MEMORY_ERROR; - } - - XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length); - *inOutIdx += length; - - /* pub */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap, - DYNAMIC_TYPE_DH); - - if (ssl->buffers.serverDH_Pub.buffer) { - ssl->buffers.serverDH_Pub.length = length; - } - else { - return MEMORY_ERROR; - } - - XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length); - *inOutIdx += length; - - break; - } - #endif /* !NO_DH || !NO_PSK */ - - #if defined(HAVE_ECC) && !defined(NO_PSK) - case ecdhe_psk_kea: - { - byte b; - int curveOid, curveId; - - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - return BUFFER_ERROR; - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - /* get PSK server hint from the wire */ - XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx, - min(length, MAX_PSK_ID_LEN)); - - ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0; - *inOutIdx += length; - - - if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + - OPAQUE8_LEN > size) { - return BUFFER_ERROR; - } - - /* Check curve name and ID */ - b = input[(*inOutIdx)++]; - if (b != named_curve) { - return ECC_CURVETYPE_ERROR; - } - - *inOutIdx += 1; /* curve type, eat leading 0 */ - b = input[(*inOutIdx)++]; - if ((curveOid = CheckCurveId(b)) < 0) { - return curveOid; - } - - length = input[(*inOutIdx)++]; - - if ((*inOutIdx - begin) + length > size) { - return BUFFER_ERROR; - } - - if (ssl->peerEccKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - return MEMORY_E; - } - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); - } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); - } - - curveId = wc_ecc_get_oid(curveOid, NULL, NULL); - if (wc_ecc_import_x963_ex(input + *inOutIdx, length, - ssl->peerEccKey, curveId) != 0) { - return ECC_PEERKEY_ERROR; - } - - *inOutIdx += length; - ssl->peerEccKeyPresent = 1; - - break; - } - #endif /* HAVE_ECC || !NO_PSK */ - } /* switch() */ - - #if !defined(NO_DH) || defined(HAVE_ECC) - if (!ssl->options.usingAnon_cipher && - (ssl->specs.kea == ecc_diffie_hellman_kea || - ssl->specs.kea == diffie_hellman_kea)) - { -#ifndef NO_OLD_TLS -#ifdef WOLFSSL_SMALL_STACK - Md5* md5 = NULL; - Sha* sha = NULL; -#else - Md5 md5[1]; - Sha sha[1]; -#endif -#endif -#ifndef NO_SHA256 -#ifdef WOLFSSL_SMALL_STACK - Sha256* sha256 = NULL; - byte* hash256 = NULL; -#else - Sha256 sha256[1]; - byte hash256[SHA256_DIGEST_SIZE]; -#endif -#endif -#ifdef WOLFSSL_SHA384 -#ifdef WOLFSSL_SMALL_STACK - Sha384* sha384 = NULL; - byte* hash384 = NULL; -#else - Sha384 sha384[1]; - byte hash384[SHA384_DIGEST_SIZE]; -#endif -#endif -#ifdef WOLFSSL_SHA512 -#ifdef WOLFSSL_SMALL_STACK - Sha512* sha512 = NULL; - byte* hash512 = NULL; -#else - Sha512 sha512[1]; - byte hash512[SHA512_DIGEST_SIZE]; -#endif -#endif -#ifdef WOLFSSL_SMALL_STACK - byte* hash = NULL; - byte* messageVerify = NULL; -#else - byte hash[FINISHED_SZ]; - byte messageVerify[MAX_DH_SZ]; -#endif - byte hashAlgo = sha_mac; - byte sigAlgo = ssl->specs.sig_algo; - word16 verifySz = (word16) (*inOutIdx - begin); - -#ifndef NO_OLD_TLS - byte doMd5 = 0; - byte doSha = 0; -#endif -#ifndef NO_SHA256 - byte doSha256 = 0; -#endif -#ifdef WOLFSSL_SHA384 - byte doSha384 = 0; -#endif -#ifdef WOLFSSL_SHA512 - byte doSha512 = 0; -#endif - - (void)hash; - (void)sigAlgo; - (void)hashAlgo; - - /* save message for hash verify */ - if (verifySz > MAX_DH_SZ) { - ERROR_OUT(BUFFER_ERROR, done); - } - - #ifdef WOLFSSL_SMALL_STACK - messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (messageVerify == NULL) { - ERROR_OUT(MEMORY_E, done); - } - #endif - - XMEMCPY(messageVerify, input + begin, verifySz); - - if (IsAtLeastTLSv1_2(ssl)) { - byte setHash = 0; - if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size) { - ERROR_OUT(BUFFER_ERROR, done); - } - - hashAlgo = input[(*inOutIdx)++]; - sigAlgo = input[(*inOutIdx)++]; - - switch (hashAlgo) { - case sha512_mac: - #ifdef WOLFSSL_SHA512 - doSha512 = 1; - setHash = 1; - #endif - break; - - case sha384_mac: - #ifdef WOLFSSL_SHA384 - doSha384 = 1; - setHash = 1; - #endif - break; - - case sha256_mac: - #ifndef NO_SHA256 - doSha256 = 1; - setHash = 1; - #endif - break; - - case sha_mac: - #ifndef NO_OLD_TLS - doSha = 1; - setHash = 1; - #endif - break; - - default: - ERROR_OUT(ALGO_ID_E, done); - } - - if (setHash == 0) { - ERROR_OUT(ALGO_ID_E, done); - } - - } else { - /* only using sha and md5 for rsa */ - #ifndef NO_OLD_TLS - doSha = 1; - if (sigAlgo == rsa_sa_algo) { - doMd5 = 1; - } - #else - ERROR_OUT(ALGO_ID_E, done); - #endif - } - - /* signature */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, done); - } - - ato16(input + *inOutIdx, &length); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, done); - } - - /* inOutIdx updated at the end of the function */ - - /* verify signature */ - #ifdef WOLFSSL_SMALL_STACK - hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (hash == NULL) { - ERROR_OUT(MEMORY_E, done); - } - #endif - -#ifndef NO_OLD_TLS - /* md5 */ - #ifdef WOLFSSL_SMALL_STACK - if (doMd5) { - md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (md5 == NULL) { - ERROR_OUT(MEMORY_E, done); - } - } - #endif - if (doMd5) { - wc_InitMd5(md5); - wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN); - wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN); - wc_Md5Update(md5, messageVerify, verifySz); - wc_Md5Final(md5, hash); - } - /* sha */ - #ifdef WOLFSSL_SMALL_STACK - if (doSha) { - sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sha == NULL) { - ERROR_OUT(MEMORY_E, done); - } - } - #endif - if (doSha) { - ret = wc_InitSha(sha); - if (ret != 0) { - goto done; - } - wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN); - wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN); - wc_ShaUpdate(sha, messageVerify, verifySz); - wc_ShaFinal(sha, hash + MD5_DIGEST_SIZE); - } -#endif - -#ifndef NO_SHA256 - #ifdef WOLFSSL_SMALL_STACK - if (doSha256) { - sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (sha256 == NULL || hash256 == NULL) { - ERROR_OUT(MEMORY_E, done); - } - } - #endif - if (doSha256) { - if (!(ret = wc_InitSha256(sha256)) - && !(ret = wc_Sha256Update(sha256, ssl->arrays->clientRandom, - RAN_LEN)) - && !(ret = wc_Sha256Update(sha256, ssl->arrays->serverRandom, - RAN_LEN)) - && !(ret = wc_Sha256Update(sha256, messageVerify, verifySz))) { - ret = wc_Sha256Final(sha256, hash256); - } - if (ret != 0) { - goto done; - } - } -#endif - -#ifdef WOLFSSL_SHA384 - #ifdef WOLFSSL_SMALL_STACK - if (doSha384) { - sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (sha384 == NULL || hash384 == NULL) { - ERROR_OUT(MEMORY_E, done); - } - } - #endif - if (doSha384) { - if (!(ret = wc_InitSha384(sha384)) - && !(ret = wc_Sha384Update(sha384, ssl->arrays->clientRandom, - RAN_LEN)) - && !(ret = wc_Sha384Update(sha384, ssl->arrays->serverRandom, - RAN_LEN)) - && !(ret = wc_Sha384Update(sha384, messageVerify, verifySz))) { - ret = wc_Sha384Final(sha384, hash384); - } - if (ret != 0) { - goto done; - } - } -#endif - -#ifdef WOLFSSL_SHA512 - #ifdef WOLFSSL_SMALL_STACK - if (doSha512) { - sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (sha512 == NULL || hash512 == NULL) { - ERROR_OUT(MEMORY_E, done); - } - } - #endif - if (doSha512) { - if (!(ret = wc_InitSha512(sha512)) - && !(ret = wc_Sha512Update(sha512, ssl->arrays->clientRandom, - RAN_LEN)) - && !(ret = wc_Sha512Update(sha512, ssl->arrays->serverRandom, - RAN_LEN)) - && !(ret = wc_Sha512Update(sha512, messageVerify, verifySz))) { - ret = wc_Sha512Final(sha512, hash512); - } - if (ret != 0) { - goto done; - } - } -#endif - - switch (sigAlgo) - { -#ifndef NO_RSA - /* rsa */ - case rsa_sa_algo: - { - byte* out = NULL; - word32 verifiedSz = 0; - - if (ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent) { - ERROR_OUT(NO_PEER_KEY, done); - } - - verifiedSz = RsaVerify(ssl, - (byte *)input + *inOutIdx, - length, - &out, - ssl->peerRsaKey, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.peerRsaKey.buffer, - ssl->buffers.peerRsaKey.length, - ssl->RsaVerifyCtx - #else - NULL, 0, NULL - #endif - ); - - if (IsAtLeastTLSv1_2(ssl)) { - word32 encSigSz; -#ifndef NO_OLD_TLS - byte* digest = &hash[MD5_DIGEST_SIZE]; - int typeH = SHAh; - int digestSz = SHA_DIGEST_SIZE; -#else - byte* digest = hash256; - int typeH = SHA256h; - int digestSz = SHA256_DIGEST_SIZE; -#endif -#ifdef WOLFSSL_SMALL_STACK - byte* encodedSig = NULL; -#else - byte encodedSig[MAX_ENCODED_SIG_SZ]; -#endif - - if (hashAlgo == sha_mac) { - #ifndef NO_SHA - digest = &hash[MD5_DIGEST_SIZE]; - typeH = SHAh; - digestSz = SHA_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha256_mac) { - #ifndef NO_SHA256 - digest = hash256; - typeH = SHA256h; - digestSz = SHA256_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha384_mac) { - #ifdef WOLFSSL_SHA384 - digest = hash384; - typeH = SHA384h; - digestSz = SHA384_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha512_mac) { - #ifdef WOLFSSL_SHA512 - digest = hash512; - typeH = SHA512h; - digestSz = SHA512_DIGEST_SIZE; - #endif - } - - #ifdef WOLFSSL_SMALL_STACK - encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (encodedSig == NULL) { - ERROR_OUT(MEMORY_E, done); - } - #endif - - if (digest == NULL) { - ERROR_OUT(ALGO_ID_E, done); - } - encSigSz = wc_EncodeSignature(encodedSig, digest, digestSz, - typeH); - if (encSigSz != verifiedSz || !out || XMEMCMP(out, encodedSig, - min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) { - ret = VERIFY_SIGN_ERROR; - } - #ifdef WOLFSSL_SMALL_STACK - XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - if (ret != 0) { - goto done; - } - } - else if (verifiedSz != FINISHED_SZ || !out || XMEMCMP(out, - hash, FINISHED_SZ) != 0) { - ERROR_OUT(VERIFY_SIGN_ERROR, done); - } - break; - } -#endif -#ifdef HAVE_ECC - /* ecdsa */ - case ecc_dsa_sa_algo: - { -#ifndef NO_OLD_TLS - byte* digest = &hash[MD5_DIGEST_SIZE]; - word32 digestSz = SHA_DIGEST_SIZE; -#else - byte* digest = hash256; - word32 digestSz = SHA256_DIGEST_SIZE; -#endif - - if (!ssl->peerEccDsaKeyPresent) - ERROR_OUT(NO_PEER_KEY, done); - - if (IsAtLeastTLSv1_2(ssl)) { - if (hashAlgo == sha_mac) { - #ifndef NO_SHA - digest = &hash[MD5_DIGEST_SIZE]; - digestSz = SHA_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha256_mac) { - #ifndef NO_SHA256 - digest = hash256; - digestSz = SHA256_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha384_mac) { - #ifdef WOLFSSL_SHA384 - digest = hash384; - digestSz = SHA384_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha512_mac) { - #ifdef WOLFSSL_SHA512 - digest = hash512; - digestSz = SHA512_DIGEST_SIZE; - #endif - } - } - - ret = EccVerify(ssl, - input + *inOutIdx, length, - digest, digestSz, - ssl->peerEccDsaKey, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.peerEccDsaKey.buffer, - ssl->buffers.peerEccDsaKey.length, - ssl->EccVerifyCtx - #else - NULL, 0, NULL - #endif - ); - break; - } -#endif /* HAVE_ECC */ default: - ERROR_OUT(ALGO_ID_E, done); - } /* switch (sigAlgo) */ + ret = INPUT_CASE_ERROR; + } /* switch(ssl->options.keyShareState) */ - /* signature length */ - *inOutIdx += length; +exit_dske: - ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; + WOLFSSL_LEAVE("DoServerKeyExchange", ret); - done: -#ifdef WOLFSSL_SMALL_STACK - #ifndef NO_OLD_TLS - XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER); + /* Handle cleanup for stack variables here */ + +#ifdef WOLFSSL_ASYNC_CRYPT + /* Handle WC_PENDING_E */ + if (ret == WC_PENDING_E) { + /* Store variables needed for async */ + XMEMSET(&ssl->async, 0, sizeof(ssl->async)); + ssl->async.idx = idx; + ssl->async.length = length; + ssl->async.output = output; + ssl->async.sigSz = sigSz; + #ifndef NO_RSA + ssl->async.hashAlgo = typeH; #endif - #ifndef NO_SHA256 - XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); + ssl->async.sigAlgo = sigAlgo; + #if !defined(NO_DH) || defined(HAVE_ECC) + ssl->async.data = verifySig; #endif - #ifdef WOLFSSL_SHA384 - XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - #ifdef WOLFSSL_SHA512 - XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - if (ret != 0) { - return ret; + + /* Mark message as not recevied so it can process again */ + ssl->msgsReceived.got_server_key_exchange = 0; + + /* Push event to queue */ + ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, &ssl->event); + if (ret == 0) { + return WC_PENDING_E; } } +#endif /* WOLFSSL_ASYNC_CRYPT */ - if (IsEncryptionOn(ssl, 0)) { - *inOutIdx += ssl->keys.padSz; - } - - - /* QSH extensions */ -#ifdef HAVE_QSH - if (ssl->peerQSHKeyPresent) { - /* extension name */ - ato16(input + *inOutIdx, &name); - *inOutIdx += OPAQUE16_LEN; - - if (name == TLSX_QUANTUM_SAFE_HYBRID) { - /* if qshSz is larger than 0 it is the length of buffer used */ - if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, - size, 0)) < 0) { - return qshSz; - } - *inOutIdx += qshSz; - } - else { - /* unknown extension sent server ignored - handshake */ - return BUFFER_ERROR; - } +#if !defined(NO_DH) || defined(HAVE_ECC) + if (verifySig) { + XFREE(verifySig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + verifySig = NULL; } #endif - return 0; -#else /* !NO_DH or HAVE_ECC */ - return NOT_COMPILED_IN; /* not supported by build */ -#endif /* !NO_DH or HAVE_ECC */ - } + /* Final cleanup */ + FreeKeyExchange(ssl); + + return ret; +} #ifdef HAVE_QSH @@ -14574,161 +14695,249 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) #endif /* HAVE_QSH */ - int SendClientKeyExchange(WOLFSSL* ssl) - { -#ifdef WOLFSSL_SMALL_STACK - byte* encSecret = NULL; -#else - byte encSecret[MAX_ENCRYPT_SZ]; -#endif - word32 encSz = 0; - word32 idx = 0; - int ret = 0; - byte doUserRsa = 0; +int SendClientKeyExchange(WOLFSSL* ssl) +{ + int ret = 0; + int sendSz = 0; + word32 length_lcl = 0; + word32* length = &length_lcl; + byte* output = NULL; + byte* encSecret = NULL; + word32 encSz = 0; - #ifdef HAVE_QSH - word32 qshSz = 0; - if (ssl->peerQSHKeyPresent) { - qshSz = QSH_KeyGetSize(ssl); + (void)length; + + WOLFSSL_ENTER("SendClientKeyExchange"); + +#ifdef WOLFSSL_ASYNC_CRYPT + /* use async pointer for length */ + length = &ssl->async.length; + + ret = wolfAsync_EventPop(&ssl->event, WOLF_EVENT_TYPE_ASYNC_ANY); + if (ret != WC_NOT_PENDING_E) { + WOLF_EVENT_TYPE eType = ssl->event.type; + + /* Clear event */ + XMEMSET(&ssl->event, 0, sizeof(ssl->event)); + + /* Check for error */ + if (ret < 0) { + goto exit_scke; } - #endif + else { + /* Restore variables needed for async */ + output = ssl->async.output; + sendSz = ssl->async.sendSz; + encSecret = ssl->async.data; + encSz = ssl->async.sigSz; - (void)doUserRsa; + /* Advance key share state if not wolfCrypt */ + if (eType == WOLF_EVENT_TYPE_ASYNC_WOLFSSL) { + ssl->options.keyShareState++; + } + } + } + else +#endif + { + /* Reset state */ + ret = 0; + ssl->options.keyShareState = KEYSHARE_BEGIN; + } -#ifdef HAVE_PK_CALLBACKS - #ifndef NO_RSA - if (ssl->ctx->RsaEncCb) - doUserRsa = 1; - #endif /* NO_RSA */ -#endif /*HAVE_PK_CALLBACKS */ - - #ifdef WOLFSSL_SMALL_STACK - encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (encSecret == NULL) - return MEMORY_E; - #endif - - switch (ssl->specs.kea) { - #ifndef NO_RSA - case rsa_kea: - ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, - SECRET_LEN); - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } - - ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; - ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; - ssl->arrays->preMasterSz = SECRET_LEN; - - if (ssl->peerRsaKey == NULL || ssl->peerRsaKeyPresent == 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - - if (doUserRsa) { - #ifdef HAVE_PK_CALLBACKS - #ifndef NO_RSA - encSz = MAX_ENCRYPT_SZ; - ret = ssl->ctx->RsaEncCb(ssl, - ssl->arrays->preMasterSecret, - SECRET_LEN, - encSecret, &encSz, - ssl->buffers.peerRsaKey.buffer, - ssl->buffers.peerRsaKey.length, - ssl->RsaEncCtx); - #endif /* NO_RSA */ - #endif /*HAVE_PK_CALLBACKS */ - } - else { - ret = wc_RsaPublicEncrypt(ssl->arrays->preMasterSecret, - SECRET_LEN, encSecret, MAX_ENCRYPT_SZ, - ssl->peerRsaKey, ssl->rng); - if (ret > 0) { - encSz = ret; - ret = 0; /* set success to 0 */ + switch(ssl->options.keyShareState) + { + case KEYSHARE_BEGIN: + { + switch (ssl->specs.kea) { + #ifndef NO_RSA + case rsa_kea: + if (ssl->peerRsaKey == NULL || + ssl->peerRsaKeyPresent == 0) { + ERROR_OUT(NO_PEER_KEY, exit_scke); } - } - break; - #endif - #ifndef NO_DH - case diffie_hellman_kea: - { - buffer serverP = ssl->buffers.serverDH_P; - buffer serverG = ssl->buffers.serverDH_G; - buffer serverPub = ssl->buffers.serverDH_Pub; - #ifdef WOLFSSL_SMALL_STACK - byte* priv = NULL; - #else - byte priv[ENCRYPT_LEN]; - #endif - word32 privSz = 0; - - if (serverP.buffer == NULL || serverG.buffer == NULL || - serverPub.buffer == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; + break; + #endif + #ifndef NO_DH + case diffie_hellman_kea: + if (ssl->buffers.serverDH_P.buffer == NULL || + ssl->buffers.serverDH_G.buffer == NULL || + ssl->buffers.serverDH_Pub.buffer == NULL) { + ERROR_OUT(NO_PEER_KEY, exit_scke); } - - #ifdef WOLFSSL_SMALL_STACK - priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (priv == NULL) { - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; + break; + #endif /* NO_DH */ + #ifndef NO_PSK + case psk_kea: + /* sanity check that PSK client callback has been set */ + if (ssl->options.client_psk_cb == NULL) { + WOLFSSL_MSG("No client PSK callback set"); + ERROR_OUT(PSK_KEY_ERROR, exit_scke); + } + break; + #endif /* NO_PSK */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + if (ssl->buffers.serverDH_P.buffer == NULL || + ssl->buffers.serverDH_G.buffer == NULL || + ssl->buffers.serverDH_Pub.buffer == NULL) { + ERROR_OUT(NO_PEER_KEY, exit_scke); } - #endif - - ret = DhAgree(ssl, - serverP.buffer, serverP.length, - serverG.buffer, serverG.length, - priv, &privSz, - encSecret, &encSz, - serverPub.buffer, serverPub.length, - ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz); - - #ifdef WOLFSSL_SMALL_STACK - XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - } - break; - #endif /* NO_DH */ - #ifndef NO_PSK - case psk_kea: - { - byte* pms = ssl->arrays->preMasterSecret; /* sanity check that PSK client callback has been set */ if (ssl->options.client_psk_cb == NULL) { WOLFSSL_MSG("No client PSK callback set"); - return PSK_KEY_ERROR; + ERROR_OUT(PSK_KEY_ERROR, exit_scke); } + break; + #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + /* sanity check that PSK client callback has been set */ + if (ssl->options.client_psk_cb == NULL) { + WOLFSSL_MSG("No client PSK callback set"); + ERROR_OUT(PSK_KEY_ERROR, exit_scke); + } + + /* Check client ECC public key */ + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || + !ssl->peerEccKey->dp) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + + /* create private key */ + ssl->sigKey = XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); + } + ssl->sigType = DYNAMIC_TYPE_ECC; + + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_scke; + } + ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, ssl->peerEccKey); + break; + #endif /* HAVE_ECC && !NO_PSK */ + #ifdef HAVE_NTRU + case ntru_kea: + if (ssl->peerNtruKeyPresent == 0) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + break; + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: + { + ecc_key* peerKey; + + if (ssl->specs.static_ecdh) { + /* TODO: EccDsa is really fixed Ecc change naming */ + if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || + !ssl->peerEccDsaKey->dp) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + peerKey = ssl->peerEccDsaKey; + } + else { + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || + !ssl->peerEccKey->dp) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + peerKey = ssl->peerEccKey; + } + if (peerKey == NULL) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + + /* create private key */ + ssl->sigKey = XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); + } + ssl->sigType = DYNAMIC_TYPE_ECC; + + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_scke; + } + ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey); + break; + } + #endif /* HAVE_ECC */ + + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_scke; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_BUILD; + } /* case KEYSHARE_BEGIN */ + + case KEYSHARE_BUILD: + { + encSz = MAX_ENCRYPT_SZ; + encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encSecret == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); + } + + switch(ssl->specs.kea) + { + #ifndef NO_RSA + case rsa_kea: + { + ret = wc_RNG_GenerateBlock(ssl->rng, + ssl->arrays->preMasterSecret, SECRET_LEN); + if (ret != 0) { + goto exit_scke; + } + + ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; + ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; + ssl->arrays->preMasterSz = SECRET_LEN; + break; + } + #endif /* !NO_RSA */ + #ifndef NO_DH + case diffie_hellman_kea: + { + ssl->buffers.sig.length = ENCRYPT_LEN; + ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (ssl->buffers.sig.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); + } + break; + } + #endif /* !NO_DH */ + #ifndef NO_PSK + case psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, ssl->arrays->server_hint, ssl->arrays->client_identity, MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); if (ssl->arrays->psk_keySz == 0 || ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return PSK_KEY_ERROR; + ERROR_OUT(PSK_KEY_ERROR, exit_scke); } encSz = (word32)XSTRLEN(ssl->arrays->client_identity); if (encSz > MAX_PSK_ID_LEN) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return CLIENT_ID_ERROR; + ERROR_OUT(CLIENT_ID_ERROR, exit_scke); } - XMEMCPY(encSecret, ssl->arrays->client_identity, encSz); + XMEMCPY(encSecret, + ssl->arrays->client_identity, encSz); /* make psk pre master secret */ /* length of key + length 0s + length of key + key */ @@ -14742,92 +14951,286 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4; ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz); ssl->arrays->psk_keySz = 0; /* No further need */ + break; } - break; - #endif /* NO_PSK */ - #if !defined(NO_DH) && !defined(NO_PSK) - case dhe_psk_kea: + #endif /* !NO_PSK */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: { - byte* pms = ssl->arrays->preMasterSecret; - byte* es = encSecret; - buffer serverP = ssl->buffers.serverDH_P; - buffer serverG = ssl->buffers.serverDH_G; - buffer serverPub = ssl->buffers.serverDH_Pub; - #ifdef WOLFSSL_SMALL_STACK - byte* priv = NULL; - #else - byte priv[ENCRYPT_LEN]; - #endif - word32 privSz = 0; - word32 pubSz = 0; - word32 esSz = 0; + word32 esSz = 0; + output = encSecret; - if (serverP.buffer == 0 || serverG.buffer == 0 || - serverPub.buffer == 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - - /* sanity check that PSK client callback has been set */ - if (ssl->options.client_psk_cb == NULL) { - WOLFSSL_MSG("No client PSK callback set"); - return PSK_KEY_ERROR; - } ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, ssl->arrays->server_hint, ssl->arrays->client_identity, MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); if (ssl->arrays->psk_keySz == 0 || ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return PSK_KEY_ERROR; + ERROR_OUT(PSK_KEY_ERROR, exit_scke); } esSz = (word32)XSTRLEN(ssl->arrays->client_identity); if (esSz > MAX_PSK_ID_LEN) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return CLIENT_ID_ERROR; + ERROR_OUT(CLIENT_ID_ERROR, exit_scke); } - #ifdef WOLFSSL_SMALL_STACK - priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL, + ssl->buffers.sig.length = ENCRYPT_LEN; + ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (priv == NULL) { - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; + if (ssl->buffers.sig.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); } - #endif - c16toa((word16)esSz, es); - es += OPAQUE16_LEN; - XMEMCPY(es, ssl->arrays->client_identity, esSz); - es += esSz; + + c16toa((word16)esSz, output); + output += OPAQUE16_LEN; + XMEMCPY(output, ssl->arrays->client_identity, esSz); + output += esSz; encSz = esSz + OPAQUE16_LEN; - ret = DhAgree(ssl, - serverP.buffer, serverP.length, - serverG.buffer, serverG.length, - priv, &privSz, - es + OPAQUE16_LEN, &pubSz, - serverPub.buffer, serverPub.length, - pms + OPAQUE16_LEN, &ssl->arrays->preMasterSz); + *length = 0; + break; + } + #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + word32 esSz = 0; + output = encSecret; - #ifdef WOLFSSL_SMALL_STACK - XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; + /* Send PSK client identity */ + ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, + ssl->arrays->server_hint, ssl->arrays->client_identity, + MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { + ERROR_OUT(PSK_KEY_ERROR, exit_scke); } - c16toa((word16)pubSz, es); - encSz += pubSz + OPAQUE16_LEN; + esSz = (word32)XSTRLEN(ssl->arrays->client_identity); + if (esSz > MAX_PSK_ID_LEN) { + ERROR_OUT(CLIENT_ID_ERROR, exit_scke); + } + + /* place size and identity in output buffer sz:identity */ + c16toa((word16)esSz, output); + output += OPAQUE16_LEN; + XMEMCPY(output, ssl->arrays->client_identity, esSz); + output += esSz; + encSz = esSz + OPAQUE16_LEN; + + /* Place ECC key in output buffer, leaving room for size */ + *length = MAX_ENCRYPT_SZ; + ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, + output + 1, length); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + } + + *output = (byte)*length; /* place size of key in output buffer */ + encSz += *length + 1; + + /* Create shared ECC key leaving room at the begining + of buffer for size of shared key. Note sizeof + preMasterSecret is ENCRYPT_LEN currently 512 */ + *length = sizeof(ssl->arrays->preMasterSecret) - OPAQUE16_LEN; + break; + } + #endif /* HAVE_ECC && !NO_PSK */ + #ifdef HAVE_NTRU + case ntru_kea: + { + ret = wc_RNG_GenerateBlock(ssl->rng, + ssl->arrays->preMasterSecret, SECRET_LEN); + if (ret != 0) { + goto exit_scke; + } + + ssl->arrays->preMasterSz = SECRET_LEN; + encSz = MAX_ENCRYPT_SZ; + break; + } + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: + { + /* precede export with 1 byte length */ + *length = MAX_ENCRYPT_SZ; + ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, + encSecret + 1, length); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + } + + encSecret[0] = (byte)*length; + encSz = *length + 1; + + *length = sizeof(ssl->arrays->preMasterSecret); + break; + } + #endif /* HAVE_ECC */ + + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_scke; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_DO; + } /* case KEYSHARE_BUILD */ + + case KEYSHARE_DO: + { + switch(ssl->specs.kea) + { + #ifndef NO_RSA + case rsa_kea: + { + ret = RsaEnc(ssl, + ssl->arrays->preMasterSecret, SECRET_LEN, + encSecret, &encSz, + ssl->peerRsaKey, + #if defined(HAVE_PK_CALLBACKS) + ssl->buffers.peerRsaKey.buffer, + ssl->buffers.peerRsaKey.length, + ssl->RsaEncCtx + #else + NULL, 0, NULL + #endif + ); + break; + } + #endif /* !NO_RSA */ + #ifndef NO_DH + case diffie_hellman_kea: + { + ret = DhAgree(ssl, + ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length, + ssl->buffers.sig.buffer, &ssl->buffers.sig.length, + encSecret, &encSz, + ssl->buffers.serverDH_Pub.buffer, + ssl->buffers.serverDH_Pub.length, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz); + break; + } + #endif /* !NO_DH */ + #ifndef NO_PSK + case psk_kea: + { + break; + } + #endif /* !NO_PSK */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + { + ret = DhAgree(ssl, + ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length, + ssl->buffers.sig.buffer, &ssl->buffers.sig.length, + output + OPAQUE16_LEN, length, + ssl->buffers.serverDH_Pub.buffer, + ssl->buffers.serverDH_Pub.length, + ssl->arrays->preMasterSecret + OPAQUE16_LEN, + &ssl->arrays->preMasterSz); + break; + } + #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + ret = EccSharedSecret(ssl, (ecc_key*)ssl->sigKey, + ssl->peerEccKey, + ssl->arrays->preMasterSecret + OPAQUE16_LEN, + length); + break; + } + #endif /* HAVE_ECC && !NO_PSK */ + #ifdef HAVE_NTRU + case ntru_kea: + { + word32 rc; + DRBG_HANDLE drbg; + + rc = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg); + if (rc != DRBG_OK) { + ERROR_OUT(NTRU_DRBG_ERROR, exit_scke); + } + rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen, + ssl->peerNtruKey, + ssl->arrays->preMasterSz, + ssl->arrays->preMasterSecret, + &encSz, + encSecret); + ntru_crypto_drbg_uninstantiate(drbg); + if (rc != NTRU_OK) { + ERROR_OUT(NTRU_ENCRYPT_ERROR, exit_scke); + } + ret = 0; + break; + } + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: + { + ecc_key* peerKey = (ssl->specs.static_ecdh) ? + ssl->peerEccDsaKey : ssl->peerEccKey; + + ret = EccSharedSecret(ssl, (ecc_key*)ssl->sigKey, peerKey, + ssl->arrays->preMasterSecret, length); + break; + } + #endif /* HAVE_ECC */ + + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_scke; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_VERIFY; + } /* case KEYSHARE_DO */ + + case KEYSHARE_VERIFY: + { + switch(ssl->specs.kea) + { + #ifndef NO_RSA + case rsa_kea: + { + break; + } + #endif /* !NO_RSA */ + #ifndef NO_DH + case diffie_hellman_kea: + { + break; + } + #endif /* !NO_DH */ + #ifndef NO_PSK + case psk_kea: + { + break; + } + #endif /* !NO_PSK */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; + + c16toa((word16)*length, output); + encSz += *length + OPAQUE16_LEN; c16toa((word16)ssl->arrays->preMasterSz, pms); ssl->arrays->preMasterSz += OPAQUE16_LEN; pms += ssl->arrays->preMasterSz; @@ -14838,121 +15241,21 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) pms += OPAQUE16_LEN; XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); ssl->arrays->preMasterSz += - ssl->arrays->psk_keySz + OPAQUE16_LEN; + ssl->arrays->psk_keySz + OPAQUE16_LEN; ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz); ssl->arrays->psk_keySz = 0; /* No further need */ + break; } - break; - #endif /* !NO_DH && !NO_PSK */ - #if defined(HAVE_ECC) && !defined(NO_PSK) - case ecdhe_psk_kea: + #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: { byte* pms = ssl->arrays->preMasterSecret; - byte* es = encSecret; - ecc_key myKey; - ecc_key* peerKey = NULL; - word32 size = MAX_ENCRYPT_SZ; - word32 esSz = 0; - - /* sanity check that PSK client callback has been set */ - if (ssl->options.client_psk_cb == NULL) { - WOLFSSL_MSG("No client PSK callback set"); - return PSK_KEY_ERROR; - } - - /* Send PSK client identity */ - ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, - ssl->arrays->server_hint, ssl->arrays->client_identity, - MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); - if (ssl->arrays->psk_keySz == 0 || - ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return PSK_KEY_ERROR; - } - esSz = (word32)XSTRLEN(ssl->arrays->client_identity); - - if (esSz > MAX_PSK_ID_LEN) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return CLIENT_ID_ERROR; - } - - /* place size and identity in output buffer sz:identity */ - c16toa((word16)esSz, es); - es += OPAQUE16_LEN; - XMEMCPY(es, ssl->arrays->client_identity, esSz); - es += esSz; - encSz = esSz + OPAQUE16_LEN; - - /* Send Client ECC public key */ - if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || - !ssl->peerEccKey->dp) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - peerKey = ssl->peerEccKey; - - if (peerKey == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - - wc_ecc_init_h(&myKey, ssl->heap); - ret = wc_ecc_make_key(ssl->rng, peerKey->dp->size, &myKey); - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ECC_MAKEKEY_ERROR; - } - - /* Place ECC key in output buffer, leaving room for size */ - ret = wc_ecc_export_x963(&myKey, es + 1, &size); - *es = (byte)size; /* place size of key in output buffer */ - encSz += size + 1; - - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - ret = ECC_EXPORT_ERROR; - } - else { - /* Create shared ECC key leaving room at the begining - of buffer for size of shared key. Note sizeof - preMasterSecret is ENCRYPT_LEN currently 512 */ - size = sizeof(ssl->arrays->preMasterSecret) - - OPAQUE16_LEN; - - ret = EccSharedSecret(ssl, &myKey, peerKey, - ssl->arrays->preMasterSecret + OPAQUE16_LEN, &size); - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - ret = ECC_SHARED_ERROR; - } - } - - wc_ecc_free(&myKey); - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } /* Create pre master secret is the concatination of eccSize + eccSharedKey + pskSize + pskKey */ - c16toa((word16)size, pms); - ssl->arrays->preMasterSz += OPAQUE16_LEN + size; + c16toa((word16)*length, pms); + ssl->arrays->preMasterSz += OPAQUE16_LEN + *length; pms += ssl->arrays->preMasterSz; c16toa((word16)ssl->arrays->psk_keySz, pms); @@ -14963,157 +15266,71 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz); ssl->arrays->psk_keySz = 0; /* No further need */ + break; } - break; - #endif /* HAVE_ECC && !NO_PSK */ - #ifdef HAVE_NTRU - case ntru_kea: + #endif /* HAVE_ECC && !NO_PSK */ + #ifdef HAVE_NTRU + case ntru_kea: { - word32 rc; - word16 cipherLen = MAX_ENCRYPT_SZ; - DRBG_HANDLE drbg; - - ret = wc_RNG_GenerateBlock(ssl->rng, - ssl->arrays->preMasterSecret, SECRET_LEN); - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } - - ssl->arrays->preMasterSz = SECRET_LEN; - - if (ssl->peerNtruKeyPresent == 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - - rc = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg); - if (rc != DRBG_OK) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NTRU_DRBG_ERROR; - } - - rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen, - ssl->peerNtruKey, - ssl->arrays->preMasterSz, - ssl->arrays->preMasterSecret, - &cipherLen, encSecret); - ntru_crypto_drbg_uninstantiate(drbg); - if (rc != NTRU_OK) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NTRU_ENCRYPT_ERROR; - } - - encSz = cipherLen; - ret = 0; + break; } - break; - #endif /* HAVE_NTRU */ - #ifdef HAVE_ECC - case ecc_diffie_hellman_kea: + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: { - ecc_key myKey; - ecc_key* peerKey = NULL; - word32 size = MAX_ENCRYPT_SZ; - - if (ssl->specs.static_ecdh) { - /* TODO: EccDsa is really fixed Ecc change naming */ - if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || - !ssl->peerEccDsaKey->dp) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - peerKey = ssl->peerEccDsaKey; - } - else { - if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || - !ssl->peerEccKey->dp) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - peerKey = ssl->peerEccKey; - } - - if (peerKey == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return NO_PEER_KEY; - } - - wc_ecc_init_h(&myKey, ssl->heap); - ret = wc_ecc_make_key_ex(ssl->rng, 0, &myKey, peerKey->dp->id); - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ECC_MAKEKEY_ERROR; - } - - /* precede export with 1 byte length */ - ret = wc_ecc_export_x963(&myKey, encSecret + 1, &size); - encSecret[0] = (byte)size; - encSz = size + 1; - - if (ret != 0) - ret = ECC_EXPORT_ERROR; - else { - size = sizeof(ssl->arrays->preMasterSecret); - ret = EccSharedSecret(ssl, &myKey, peerKey, - ssl->arrays->preMasterSecret, &size); - if (ret != 0) - ret = ECC_SHARED_ERROR; - } - - ssl->arrays->preMasterSz = size; - wc_ecc_free(&myKey); + ssl->arrays->preMasterSz = *length; + break; } - break; - #endif /* HAVE_ECC */ - default: - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ALGO_ID_E; /* unsupported kea */ - } + #endif /* HAVE_ECC */ - if (ret == 0) { - byte *output; - int sendSz; - word32 tlsSz = 0; + default: + ret = BAD_KEA_TYPE_E; + } /* switch(ssl->specs.kea) */ - if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea) + /* Check for error */ + if (ret != 0) { + goto exit_scke; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_FINALIZE; + } /* case KEYSHARE_VERIFY */ + + case KEYSHARE_FINALIZE: + { + word32 tlsSz = 0; + word32 idx = 0; + + #ifdef HAVE_QSH + word32 qshSz = 0; + if (ssl->peerQSHKeyPresent) { + qshSz = QSH_KeyGetSize(ssl); + } + #endif + + if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea) { tlsSz = 2; + } if (ssl->specs.kea == ecc_diffie_hellman_kea || ssl->specs.kea == dhe_psk_kea || - ssl->specs.kea == ecdhe_psk_kea) /* always off */ + ssl->specs.kea == ecdhe_psk_kea) { /* always off */ tlsSz = 0; + } - sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; + sendSz = encSz + tlsSz + idx; - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA; - idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA; - } - #endif + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA; + sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA; + } + #endif - if (IsEncryptionOn(ssl, 1)) + if (IsEncryptionOn(ssl, 1)) { sendSz += MAX_MSG_EXTRA; + } #ifdef HAVE_QSH encSz += qshSz; @@ -15122,24 +15339,21 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; + goto exit_scke; } /* get output buffer */ output = ssl->buffers.outputBuffer.buffer + ssl->buffers.outputBuffer.length; - -#ifdef HAVE_QSH + #ifdef HAVE_QSH if (ssl->peerQSHKeyPresent) { byte idxSave = idx; idx = sendSz - qshSz; - if (QSH_KeyExchangeWrite(ssl, 0) != 0) - return MEMORY_E; + if (QSH_KeyExchangeWrite(ssl, 0) != 0) { + ERROR_OUT(MEMORY_E, exit_scke); + } /* extension type */ c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx); @@ -15147,20 +15361,21 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) /* write to output and check amount written */ if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx) - > qshSz - OPAQUE16_LEN) - return MEMORY_E; + > qshSz - OPAQUE16_LEN) { + ERROR_OUT(MEMORY_E, exit_scke); + } idx = idxSave; } -#endif + #endif AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl); -#ifdef HAVE_QSH + #ifdef HAVE_QSH if (ssl->peerQSHKeyPresent) { encSz -= qshSz; } -#endif + #endif if (tlsSz) { c16toa((word16)encSz, &output[idx]); idx += 2; @@ -15175,10 +15390,7 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (input == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return MEMORY_E; + ERROR_OUT(MEMORY_E, exit_scke); } XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); @@ -15186,246 +15398,374 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) handshake, 1, 0); XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (sendSz < 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return sendSz; - } - } else { - ret = HashOutput(ssl, output, sendSz, 0); - if (ret != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } - } - - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } - } - #endif - - #ifdef WOLFSSL_CALLBACKS - if (ssl->hsInfoOn) - AddPacketName("ClientKeyExchange", &ssl->handShakeInfo); - if (ssl->toInfoOn) - AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo, - output, sendSz, ssl->heap); - #endif - - ssl->buffers.outputBuffer.length += sendSz; - - if (ssl->options.groupMessages) - ret = 0; - else - ret = SendBuffered(ssl); - } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - - if (ret == 0 || ret == WANT_WRITE) { - int tmpRet = MakeMasterSecret(ssl); - if (tmpRet != 0) - ret = tmpRet; /* save WANT_WRITE unless more serious */ - ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; - } - /* No further need for PMS */ - ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz); - ssl->arrays->preMasterSz = 0; - - return ret; - } - -#ifndef NO_CERTS - - - int SendCertificateVerify(WOLFSSL* ssl) - { - byte *output; - int sendSz = MAX_CERT_VERIFY_SZ, length, ret; - word32 idx = 0; - word32 sigOutSz = 0; -#ifndef NO_RSA - RsaKey key; - int initRsaKey = 0; -#endif - int usingEcc = 0; -#ifdef HAVE_ECC - ecc_key eccKey; -#endif - - (void)idx; - - if (ssl->options.sendVerify == SEND_BLANK_CERT) - return 0; /* sent blank cert, can't verify */ - - if (IsEncryptionOn(ssl, 1)) - sendSz += MAX_MSG_EXTRA; - - /* check for available size */ - if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) - return ret; - - /* get output buffer */ - output = ssl->buffers.outputBuffer.buffer + - ssl->buffers.outputBuffer.length; - - ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes); - if (ret != 0) - return ret; - -#ifdef HAVE_ECC - wc_ecc_init_h(&eccKey, ssl->heap); -#endif -#ifndef NO_RSA - ret = wc_InitRsaKey(&key, ssl->heap); - if (ret == 0) initRsaKey = 1; - if (ret == 0) - ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &key, - ssl->buffers.key->length); - if (ret == 0) { - int keySz = wc_RsaEncryptSize(&key); - if (keySz < 0) { /* check if keySz has error case */ - return keySz; - } - - sigOutSz = (word32)keySz; - if (keySz < ssl->options.minRsaKeySz) { - WOLFSSL_MSG("RSA key size too small"); - return RSA_KEY_SIZE_E; - } - } - else -#endif - { - #ifdef HAVE_ECC - WOLFSSL_MSG("Trying ECC client cert, RSA didn't work"); - - if (ssl->buffers.key == NULL) { - WOLFSSL_MSG("ECC Key missing"); - return NO_PRIVATE_KEY; - } - - idx = 0; - ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &eccKey, - ssl->buffers.key->length); - if (ret == 0) { - WOLFSSL_MSG("Using ECC client cert"); - usingEcc = 1; - sigOutSz = MAX_ENCODED_SIG_SZ; - - /* check minimum size of ECC key */ - if (wc_ecc_size(&eccKey) < ssl->options.minEccKeySz) { - WOLFSSL_MSG("ECC key size too small"); - return ECC_KEY_SIZE_E; + ERROR_OUT(sendSz, exit_scke); } } else { - WOLFSSL_MSG("Bad client cert type"); + ret = HashOutput(ssl, output, sendSz, 0); + if (ret != 0) { + goto exit_scke; + } } - #endif + + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl)) { + if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { + goto exit_scke; + } + } + #endif + + #ifdef WOLFSSL_CALLBACKS + if (ssl->hsInfoOn) + AddPacketName("ClientKeyExchange", &ssl->handShakeInfo); + if (ssl->toInfoOn) + AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo, + output, sendSz, ssl->heap); + #endif + + /* Check for error */ + if (ret != 0) { + goto exit_scke; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_END; + } /* case KEYSHARE_FINALIZE */ + + case KEYSHARE_END: + { + ssl->buffers.outputBuffer.length += sendSz; + + if (!ssl->options.groupMessages) { + ret = SendBuffered(ssl); + } + if (ret == 0 || ret == WANT_WRITE) { + int tmpRet = MakeMasterSecret(ssl); + if (tmpRet != 0) { + ret = tmpRet; /* save WANT_WRITE unless more serious */ + } + ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; + } + break; } + default: + ret = INPUT_CASE_ERROR; + } /* switch(ssl->options.keyShareState) */ + +exit_scke: + + WOLFSSL_LEAVE("SendClientKeyExchange", ret); + + /* Handle cleanup for stack variables here */ + + +#ifdef WOLFSSL_ASYNC_CRYPT + /* Handle WC_PENDING_E */ + if (ret == WC_PENDING_E) { + /* Store variables needed for async */ + length_lcl = ssl->async.length; + XMEMSET(&ssl->async, 0, sizeof(ssl->async)); + ssl->async.output = output; + ssl->async.sendSz = sendSz; + ssl->async.data = encSecret; + ssl->async.sigSz = encSz; + ssl->async.length = length_lcl; + + /* Push event to queue */ + ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, &ssl->event); if (ret == 0) { - byte* verify = (byte*)&output[RECORD_HEADER_SZ + - HANDSHAKE_HEADER_SZ]; -#ifndef NO_OLD_TLS - byte* signBuffer = ssl->hsHashes->certHashes.md5; -#else - byte* signBuffer = NULL; -#endif - word32 signSz = FINISHED_SZ; - word32 extraSz = 0; /* tls 1.2 hash/sig */ -#ifdef WOLFSSL_SMALL_STACK - byte* encodedSig = NULL; -#else - byte encodedSig[MAX_ENCODED_SIG_SZ]; + return WC_PENDING_E; + } + } #endif -#ifdef WOLFSSL_SMALL_STACK - encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (encodedSig == NULL) { - #ifndef NO_RSA - if (initRsaKey) - wc_FreeRsaKey(&key); - #endif - #ifdef HAVE_ECC - wc_ecc_free(&eccKey); - #endif - return MEMORY_E; + /* No further need for PMS */ + ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz); + ssl->arrays->preMasterSz = 0; + + if (encSecret) { + XFREE(encSecret, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + encSecret = NULL; + } + + /* Final cleanup */ + FreeKeyExchange(ssl); + + return ret; +} + + +#ifndef NO_CERTS + +int SendCertificateVerify(WOLFSSL* ssl) +{ + byte* output = NULL; + int sendSz = 0, length = 0, ret; + byte* verify = NULL; + word32 idx = 0; + word32 extraSz = 0; +#ifndef NO_RSA + byte* verifySig = NULL; +#endif + + WOLFSSL_ENTER("SendCertificateVerify"); + +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_EventPop(&ssl->event, WOLF_EVENT_TYPE_ASYNC_ANY); + if (ret != WC_NOT_PENDING_E) { + WOLF_EVENT_TYPE eType = ssl->event.type; + + /* Clear event */ + XMEMSET(&ssl->event, 0, sizeof(ssl->event)); + + /* Check for error */ + if (ret < 0) { + goto exit_scv; + } + else { + /* Restore variables needed for async */ + output = ssl->async.output; + sendSz = ssl->async.sendSz; + extraSz = ssl->async.sigSz; + length = ssl->async.length; + idx = ssl->async.idx; + #ifndef NO_RSA + verifySig = ssl->async.data; + #endif + + /* Advance key share state if not wolfCrypt */ + if (eType == WOLF_EVENT_TYPE_ASYNC_WOLFSSL) { + ssl->options.keyShareState++; } + } + } + else #endif + { + /* Reset state */ + ret = 0; + ssl->options.keyShareState = KEYSHARE_BEGIN; + } - (void)encodedSig; - (void)signSz; - (void)signBuffer; - - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) - verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; - #endif - length = sigOutSz; - if (IsAtLeastTLSv1_2(ssl)) { - verify[0] = ssl->suites->hashAlgo; - verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo; - extraSz = HASH_SIG_SIZE; + switch(ssl->options.keyShareState) + { + case KEYSHARE_BEGIN: + { + if (ssl->options.sendVerify == SEND_BLANK_CERT) { + return 0; /* sent blank cert, can't verify */ } - if (usingEcc) { -#ifdef HAVE_ECC - word32 localSz = MAX_ENCODED_SIG_SZ; - word32 digestSz; - byte* digest; -#ifndef NO_OLD_TLS - /* old tls default */ - digestSz = SHA_DIGEST_SIZE; - digest = ssl->hsHashes->certHashes.sha; -#else - /* new tls default */ - digestSz = SHA256_DIGEST_SIZE; - digest = ssl->hsHashes->certHashes.sha256; -#endif + sendSz = MAX_CERT_VERIFY_SZ; + if (IsEncryptionOn(ssl, 1)) { + sendSz += MAX_MSG_EXTRA; + } - if (IsAtLeastTLSv1_2(ssl)) { - if (ssl->suites->hashAlgo == sha_mac) { - #ifndef NO_SHA - digest = ssl->hsHashes->certHashes.sha; - digestSz = SHA_DIGEST_SIZE; - #endif - } - else if (ssl->suites->hashAlgo == sha256_mac) { - #ifndef NO_SHA256 - digest = ssl->hsHashes->certHashes.sha256; - digestSz = SHA256_DIGEST_SIZE; - #endif - } - else if (ssl->suites->hashAlgo == sha384_mac) { - #ifdef WOLFSSL_SHA384 - digest = ssl->hsHashes->certHashes.sha384; - digestSz = SHA384_DIGEST_SIZE; - #endif - } - else if (ssl->suites->hashAlgo == sha512_mac) { - #ifdef WOLFSSL_SHA512 - digest = ssl->hsHashes->certHashes.sha512; - digestSz = SHA512_DIGEST_SIZE; - #endif - } + /* check for available size */ + if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) { + goto exit_scv; + } + + /* get output buffer */ + output = ssl->buffers.outputBuffer.buffer + + ssl->buffers.outputBuffer.length; + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_BUILD; + } /* case KEYSHARE_BEGIN */ + + case KEYSHARE_BUILD: + { + int keySz; + int typeH; + + ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes); + if (ret != 0) { + goto exit_scv; + } + + #ifndef NO_RSA + ssl->sigKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap, + DYNAMIC_TYPE_RSA); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + ssl->sigType = DYNAMIC_TYPE_RSA; + + ret = wc_InitRsaKey_ex((RsaKey*)ssl->sigKey, ssl->heap, ssl->devId); + if (ret != 0) { + goto exit_scv; + } + + WOLFSSL_MSG("Trying RSA client cert"); + + ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx, + (RsaKey*)ssl->sigKey, ssl->buffers.key->length); + if (ret == 0) { + keySz = wc_RsaEncryptSize((RsaKey*)ssl->sigKey); + if (keySz < 0) { /* check if keySz has error case */ + ERROR_OUT(keySz, exit_scv); } + length = (word32)keySz; + if (keySz < ssl->options.minRsaKeySz) { + WOLFSSL_MSG("RSA key size too small"); + ERROR_OUT(RSA_KEY_SIZE_E, exit_scv); + } + } + else + #endif /* !NO_RSA */ + { + #ifdef HAVE_ECC + if (ssl->sigKey) { + XFREE(ssl->sigKey, ssl->heap, DYNAMIC_TYPE_RSA); + } + ssl->sigKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap, + DYNAMIC_TYPE_ECC); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + ssl->sigType = DYNAMIC_TYPE_ECC; + + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, ssl->devId); + if (ret != 0) { + goto exit_scv; + } + + WOLFSSL_MSG("Trying ECC client cert, RSA didn't work"); + + if (ssl->buffers.key == NULL) { + WOLFSSL_MSG("ECC Key missing"); + ERROR_OUT(NO_PRIVATE_KEY, exit_scv); + } + + idx = 0; + ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, + (ecc_key*)ssl->sigKey, ssl->buffers.key->length); + if (ret != 0) { + WOLFSSL_MSG("Bad client cert type"); + goto exit_scv; + } + + WOLFSSL_MSG("Using ECC client cert"); + length = MAX_ENCODED_SIG_SZ; + + /* check minimum size of ECC key */ + keySz = wc_ecc_size((ecc_key*)ssl->sigKey); + if (keySz < ssl->options.minEccKeySz) { + WOLFSSL_MSG("ECC key size too small"); + ERROR_OUT(ECC_KEY_SIZE_E, exit_scv); + } + #endif + } + + + /* idx is used to track verify pointer offset to output */ + idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + verify = &output[RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ]; + extraSz = 0; /* tls 1.2 hash/sig */ + + /* build encoded signature buffer */ + ssl->buffers.sig.length = MAX_ENCODED_SIG_SZ; + ssl->buffers.sig.buffer = (byte*)XMALLOC(ssl->buffers.sig.length, + ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ssl->buffers.sig.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + } + #endif + + #ifndef NO_OLD_TLS + /* old tls default */ + ssl->buffers.digest.length = SHA_DIGEST_SIZE; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha; + typeH = SHAh; + #else + /* new tls default */ + ssl->buffers.digest.length = SHA256_DIGEST_SIZE; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256; + typeH = SHA256h; + #endif + + if (IsAtLeastTLSv1_2(ssl)) { + verify[0] = ssl->suites->hashAlgo; + verify[1] = (ssl->sigType == DYNAMIC_TYPE_ECC) ? + ecc_dsa_sa_algo : rsa_sa_algo; + extraSz = HASH_SIG_SIZE; + + switch (ssl->suites->hashAlgo) { + #ifndef NO_SHA + case sha_mac: + ssl->buffers.digest.length = SHA_DIGEST_SIZE; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha; + typeH = SHAh; + break; + #endif /* NO_SHA */ + #ifndef NO_SHA256 + case sha256_mac: + ssl->buffers.digest.length = SHA256_DIGEST_SIZE; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256; + typeH = SHA256h; + break; + #endif /* !NO_SHA256 */ + #ifdef WOLFSSL_SHA384 + case sha384_mac: + ssl->buffers.digest.length = SHA384_DIGEST_SIZE; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384; + typeH = SHA384h; + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case sha512_mac: + ssl->buffers.digest.length = SHA512_DIGEST_SIZE; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512; + typeH = SHA512h; + break; + #endif /* WOLFSSL_SHA512 */ + } /* switch */ + } + #ifndef NO_OLD_TLS + else { + /* if old TLS load MD5 hash as value to sign */ + XMEMCPY(ssl->buffers.sig.buffer, ssl->hsHashes->certHashes.md5, + FINISHED_SZ); + } + #endif + + (void)typeH; + + #ifndef NO_RSA + if (ssl->sigType == DYNAMIC_TYPE_RSA) { + ssl->buffers.sig.length = FINISHED_SZ; + ssl->sigLen = ENCRYPT_LEN; + + if (IsAtLeastTLSv1_2(ssl)) { + ssl->buffers.sig.length = wc_EncodeSignature( + ssl->buffers.sig.buffer, ssl->buffers.digest.buffer, + ssl->buffers.digest.length, typeH); + } + + c16toa((word16)length, verify + extraSz); /* prepend hdr */ + } + #endif /* !NO_RSA */ + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_DO; + } /* case KEYSHARE_BUILD */ + + case KEYSHARE_DO: + { + #ifdef HAVE_ECC + if (ssl->sigType == DYNAMIC_TYPE_ECC) { ret = EccSign(ssl, - digest, digestSz, - encodedSig, &localSz, - &eccKey, + ssl->buffers.digest.buffer, ssl->buffers.digest.length, + ssl->buffers.sig.buffer, &ssl->buffers.sig.length, + (ecc_key*)ssl->sigKey, #if defined(HAVE_PK_CALLBACKS) ssl->buffers.key->buffer, ssl->buffers.key->length, @@ -15434,85 +15774,17 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) NULL, 0, NULL #endif ); - if (ret == 0) { - length = localSz; - c16toa((word16)length, verify + extraSz); /* prepend hdr */ - XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length); - } -#endif /* HAVE_ECC */ } -#ifndef NO_RSA - else { - word32 ioLen = ENCRYPT_LEN; - - if (IsAtLeastTLSv1_2(ssl)) { - /* - * MSVC Compiler complains because it can not - * guarantee any of the conditionals will succeed in - * assigning a value before wc_EncodeSignature executes. - */ - byte* digest = NULL; - int digestSz = 0; - int typeH = 0; - int didSet = 0; - - if (ssl->suites->hashAlgo == sha_mac) { - #ifndef NO_SHA - digest = ssl->hsHashes->certHashes.sha; - typeH = SHAh; - digestSz = SHA_DIGEST_SIZE; - didSet = 1; - #endif - } - else if (ssl->suites->hashAlgo == sha256_mac) { - #ifndef NO_SHA256 - digest = ssl->hsHashes->certHashes.sha256; - typeH = SHA256h; - digestSz = SHA256_DIGEST_SIZE; - didSet = 1; - #endif - } - else if (ssl->suites->hashAlgo == sha384_mac) { - #ifdef WOLFSSL_SHA384 - digest = ssl->hsHashes->certHashes.sha384; - typeH = SHA384h; - digestSz = SHA384_DIGEST_SIZE; - didSet = 1; - #endif - } - else if (ssl->suites->hashAlgo == sha512_mac) { - #ifdef WOLFSSL_SHA512 - digest = ssl->hsHashes->certHashes.sha512; - typeH = SHA512h; - digestSz = SHA512_DIGEST_SIZE; - didSet = 1; - #endif - } - - if (didSet == 0) { - /* defaults */ - #ifndef NO_OLD_TLS - digest = ssl->hsHashes->certHashes.sha; - digestSz = SHA_DIGEST_SIZE; - typeH = SHAh; - #else - digest = ssl->hsHashes->certHashes.sha256; - digestSz = SHA256_DIGEST_SIZE; - typeH = SHA256h; - #endif - } - - signSz = wc_EncodeSignature(encodedSig, digest,digestSz,typeH); - signBuffer = encodedSig; - } - - c16toa((word16)length, verify + extraSz); /* prepend hdr */ + #endif /* HAVE_ECC */ + #ifndef NO_RSA + if (ssl->sigType == DYNAMIC_TYPE_RSA) { + /* restore verify pointer */ + verify = &output[idx]; ret = RsaSign(ssl, - signBuffer, signSz, - verify + extraSz + VERIFY_HEADER, - &ioLen, - &key, + ssl->buffers.sig.buffer, ssl->buffers.sig.length, + verify + extraSz + VERIFY_HEADER, &ssl->sigLen, + (RsaKey*)ssl->sigKey, ssl->buffers.key->buffer, ssl->buffers.key->length, #ifdef HAVE_PK_CALLBACKS @@ -15521,27 +15793,67 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) NULL #endif ); - if (ret == 0) { - /* check for signature faults */ - ret = VerifyRsaSign(ssl, - verify + extraSz + VERIFY_HEADER, - ioLen, - signBuffer, - signSz, - &key); - } } -#endif -#ifdef WOLFSSL_SMALL_STACK - XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + #endif /* !NO_RSA */ - if (ret == 0) { - AddHeaders(output, length + extraSz + VERIFY_HEADER, - certificate_verify, ssl); + /* Check for error */ + if (ret != 0) { + goto exit_scv; + } - sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length + - extraSz + VERIFY_HEADER; + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_VERIFY; + } /* case KEYSHARE_DO */ + + case KEYSHARE_VERIFY: + { + /* restore verify pointer */ + verify = &output[idx]; + + #ifdef HAVE_ECC + if (ssl->sigType == DYNAMIC_TYPE_ECC) { + length = ssl->buffers.sig.length; + c16toa((word16)ssl->buffers.sig.length, verify + extraSz); /* prepend hdr */ + XMEMCPY(verify + extraSz + VERIFY_HEADER, + ssl->buffers.sig.buffer, ssl->buffers.sig.length); + } + #endif /* HAVE_ECC */ + #ifndef NO_RSA + if (ssl->sigType == DYNAMIC_TYPE_RSA) { + if (verifySig == NULL) { + verifySig = (byte*)XMALLOC(ssl->sigLen, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (verifySig == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + XMEMCPY(verifySig, verify + extraSz + VERIFY_HEADER, + ssl->sigLen); + } + + /* check for signature faults */ + ret = VerifyRsaSign(ssl, + verifySig, ssl->sigLen, + ssl->buffers.sig.buffer, ssl->buffers.sig.length, + (RsaKey*)ssl->sigKey); + } + #endif /* !NO_RSA */ + + /* Check for error */ + if (ret != 0) { + goto exit_scv; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_FINALIZE; + } /* case KEYSHARE_VERIFY */ + + case KEYSHARE_FINALIZE: + { + AddHeaders(output, length + extraSz + VERIFY_HEADER, + certificate_verify, ssl); + + sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length + + extraSz + VERIFY_HEADER; #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { @@ -15549,66 +15861,118 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) } #endif - if (IsEncryptionOn(ssl, 1)) { - byte* input; - int inputSz = sendSz - RECORD_HEADER_SZ; - /* build msg adds rec hdr */ - input = (byte*)XMALLOC(inputSz, ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (input == NULL) - ret = MEMORY_E; - else { + if (IsEncryptionOn(ssl, 1)) { + byte* input; + int inputSz = sendSz - RECORD_HEADER_SZ; + /* build msg adds rec hdr */ + input = (byte*)XMALLOC(inputSz, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (input == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz); sendSz = BuildMessage(ssl, output, MAX_CERT_VERIFY_SZ +MAX_MSG_EXTRA, input, inputSz, handshake, 1, 0); XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (sendSz < 0) + if (sendSz < 0) { ret = sendSz; + } } - } else { - ret = HashOutput(ssl, output, sendSz, 0); - } - - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) - return ret; - } - #endif + else { + ret = HashOutput(ssl, output, sendSz, 0); } - } -#ifndef NO_RSA - if (initRsaKey) - wc_FreeRsaKey(&key); -#endif -#ifdef HAVE_ECC - wc_ecc_free(&eccKey); -#endif - if (ret == 0) { - #ifdef WOLFSSL_CALLBACKS - if (ssl->hsInfoOn) - AddPacketName("CertificateVerify", &ssl->handShakeInfo); - if (ssl->toInfoOn) - AddPacketInfo("CertificateVerify", &ssl->timeoutInfo, - output, sendSz, ssl->heap); - #endif + #ifdef WOLFSSL_DTLS + if (IsDtlsNotSctpMode(ssl)) { + ret = DtlsPoolSave(ssl, output, sendSz); + } + #endif + + /* Check for error */ + if (ret != 0) { + goto exit_scv; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_END; + } /* case KEYSHARE_FINALIZE */ + + case KEYSHARE_END: + { + #ifdef WOLFSSL_CALLBACKS + if (ssl->hsInfoOn) + AddPacketName("CertificateVerify", &ssl->handShakeInfo); + if (ssl->toInfoOn) + AddPacketInfo("CertificateVerify", &ssl->timeoutInfo, + output, sendSz, ssl->heap); + #endif + ssl->buffers.outputBuffer.length += sendSz; - if (ssl->options.groupMessages) - return 0; - else - return SendBuffered(ssl); + + if (!ssl->options.groupMessages) { + ret = SendBuffered(ssl); } - else - return ret; + break; + } + default: + ret = INPUT_CASE_ERROR; + } /* switch(ssl->options.keyShareState) */ + +exit_scv: + + WOLFSSL_LEAVE("SendCertificateVerify", ret); + + /* Handle cleanup for stack variables here */ + + +#ifdef WOLFSSL_ASYNC_CRYPT + /* Handle WC_PENDING_E */ + if (ret == WC_PENDING_E) { + /* Store variables needed for async */ + XMEMSET(&ssl->async, 0, sizeof(ssl->async)); + ssl->async.output = output; + ssl->async.sendSz = sendSz; + ssl->async.sigSz = extraSz; + ssl->async.length = length; + ssl->async.idx = idx; + #ifndef NO_RSA + ssl->async.data = verifySig; + #endif + + /* Push event to queue */ + ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, &ssl->event); + if (ret == 0) { + return WC_PENDING_E; + } } +#endif + +#ifndef NO_RSA + if (verifySig) { + XFREE(verifySig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + verifySig = NULL; + } +#endif + + /* Digest is not allocated, so do this to prevent free */ + ssl->buffers.digest.buffer = NULL; + ssl->buffers.digest.length = 0; + + /* Final cleanup */ + FreeKeyExchange(ssl); + + return ret; +} + #endif /* NO_CERTS */ + #ifdef HAVE_SESSION_TICKET -int DoSessionTicket(WOLFSSL* ssl, - const byte* input, word32* inOutIdx, word32 size) +int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, + word32 size) { word32 begin = *inOutIdx; word32 lifetime; @@ -15722,6 +16086,10 @@ int DoSessionTicket(WOLFSSL* ssl, length -= (ID_LEN - sessIdSz); /* adjust ID_LEN assumption */ } #endif /* HAVE_SESSION_TICKET */ +#else + if (ssl->options.haveEMS) { + length += HELLO_EXT_SZ_SZ + HELLO_EXT_SZ; + } #endif /* check for avalaible size */ @@ -15795,11 +16163,25 @@ int DoSessionTicket(WOLFSSL* ssl, /* last, extensions */ #ifdef HAVE_TLS_EXTENSIONS TLSX_WriteResponse(ssl, output + idx); +#else +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_SZ, output + idx); + idx += HELLO_EXT_SZ_SZ; + + c16toa(HELLO_EXT_EXTMS, output + idx); + idx += HELLO_EXT_TYPE_SZ; + c16toa(0, output + idx); + /*idx += HELLO_EXT_SZ_SZ;*/ + /* idx is not used after this point. uncomment the line above + * if adding any more extentions in the future. */ + } +#endif #endif ssl->buffers.outputBuffer.length += sendSz; #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -15935,15 +16317,25 @@ int DoSessionTicket(WOLFSSL* ssl, qshSz = QSH_KeyGetSize(ssl); } #endif + #ifndef NO_RSA + byte* verifySig = NULL; + #endif (void)ssl; (void)sigSz; (void)length; (void)idx; + WOLFSSL_ENTER("SendServerKeyExchange"); + #ifdef WOLFSSL_ASYNC_CRYPT - ret = wolfSSL_async_pop(ssl, WOLF_EVENT_TYPE_ASYNC_ACCEPT); - if (ret != ASYNC_NOT_PENDING) { + ret = wolfAsync_EventPop(&ssl->event, WOLF_EVENT_TYPE_ASYNC_ANY); + if (ret != WC_NOT_PENDING_E) { + WOLF_EVENT_TYPE eType = ssl->event.type; + + /* Clear event */ + XMEMSET(&ssl->event, 0, sizeof(ssl->event)); + /* Check for error */ if (ret < 0) { goto exit_sske; @@ -15955,9 +16347,14 @@ int DoSessionTicket(WOLFSSL* ssl, idx = ssl->async.idx; sigSz = ssl->async.sigSz; length = ssl->async.length; + #ifndef NO_RSA + verifySig = ssl->async.data; + #endif - /* Advance key share state */ - ssl->options.keyShareState++; + /* Advance key share state if not wolfCrypt */ + if (eType == WOLF_EVENT_TYPE_ASYNC_WOLFSSL) { + ssl->options.keyShareState++; + } } } else @@ -15978,8 +16375,7 @@ int DoSessionTicket(WOLFSSL* ssl, #if defined(HAVE_ECC) && !defined(NO_PSK) case ecdhe_psk_kea: { - /* pub key size */ - WOLFSSL_MSG("Using ephemeral ECDH"); + WOLFSSL_MSG("Using ephemeral ECDH PSK"); break; } #endif /* HAVE_ECC && !NO_PSK */ @@ -16073,9 +16469,18 @@ int DoSessionTicket(WOLFSSL* ssl, WOLFSSL_MSG("EccTempKey Memory error"); ERROR_OUT(MEMORY_E, exit_sske); } - wc_ecc_init_h(ssl->eccTempKey, ssl->heap); + ret = wc_ecc_init_ex(ssl->eccTempKey, ssl->heap, ssl->devId); + if (ret != 0) + goto exit_sske; + } + + if (ssl->eccTempKeyPresent == 0) { + /* TODO: Need to first do wc_EccPrivateKeyDecode, then we know curve dp */ + ret = EccMakeKey(ssl, ssl->eccTempKey, NULL); + if (ret == 0 || ret == WC_PENDING_E) { + ssl->eccTempKeyPresent = 1; + } } - ret = EccMakeTempKey(ssl); break; } #endif /* HAVE_ECC */ @@ -16325,8 +16730,8 @@ int DoSessionTicket(WOLFSSL* ssl, } ssl->sigType = DYNAMIC_TYPE_RSA; - ret = wc_InitRsaKey((RsaKey*)ssl->sigKey, - ssl->heap); + ret = wc_InitRsaKey_ex((RsaKey*)ssl->sigKey, + ssl->heap, ssl->devId); if (ret != 0) { goto exit_sske; } @@ -16360,7 +16765,9 @@ int DoSessionTicket(WOLFSSL* ssl, } ssl->sigType = DYNAMIC_TYPE_ECC; - wc_ecc_init_h((ecc_key*)ssl->sigKey, ssl->heap); + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, ssl->devId); + if (ret != 0) + goto exit_sske; ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &i, (ecc_key*)ssl->sigKey, @@ -16560,40 +16967,11 @@ int DoSessionTicket(WOLFSSL* ssl, /* write sig size here */ c16toa((word16)ssl->sigLen, output + idx); idx += LENGTH_SZ; - - ret = RsaSign(ssl, - ssl->buffers.sig.buffer, - ssl->buffers.sig.length, - output + idx, - &ssl->sigLen, - (RsaKey*)ssl->sigKey, - ssl->buffers.key->buffer, - ssl->buffers.key->length, - #ifdef HAVE_PK_CALLBACKS - ssl->RsaSignCtx - #else - NULL - #endif - ); break; } #endif /* !NO_RSA */ case ecc_dsa_sa_algo: { - ret = EccSign(ssl, - ssl->buffers.sig.buffer, - ssl->buffers.sig.length, - output + LENGTH_SZ + idx, - &ssl->sigLen, - (ecc_key*)ssl->sigKey, - #if defined(HAVE_PK_CALLBACKS) - ssl->buffers.key->buffer, - ssl->buffers.key->length, - ssl->EccSignCtx - #else - NULL, 0, NULL - #endif - ); break; } } /* switch(ssl->specs.sig_algo) */ @@ -16618,14 +16996,15 @@ int DoSessionTicket(WOLFSSL* ssl, word32 i = 0; int keySz; - ssl->sigKey = XMALLOC(sizeof(RsaKey), ssl->heap, + ssl->sigKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap, DYNAMIC_TYPE_RSA); if (ssl->sigKey == NULL) { ERROR_OUT(MEMORY_E, exit_sske); } ssl->sigType = DYNAMIC_TYPE_RSA; - ret = wc_InitRsaKey((RsaKey*)ssl->sigKey,ssl->heap); + ret = wc_InitRsaKey_ex((RsaKey*)ssl->sigKey, + ssl->heap, ssl->devId); if (ret != 0) { goto exit_sske; } @@ -16712,154 +17091,256 @@ int DoSessionTicket(WOLFSSL* ssl, } #endif - if (!ssl->options.usingAnon_cipher) { - /* Determine hash type */ - if (IsAtLeastTLSv1_2(ssl)) { - output[idx++] = ssl->suites->hashAlgo; - output[idx++] = ssl->suites->sigAlgo; + if (ssl->options.usingAnon_cipher) { + break; + } - switch (ssl->suites->hashAlgo) { - case sha512_mac: - #ifdef WOLFSSL_SHA512 - hashType = WC_HASH_TYPE_SHA512; - #endif - break; - case sha384_mac: - #ifdef WOLFSSL_SHA384 - hashType = WC_HASH_TYPE_SHA384; - #endif - break; - case sha256_mac: - #ifndef NO_SHA256 - hashType = WC_HASH_TYPE_SHA256; - #endif - break; - case sha_mac: - #ifndef NO_OLD_TLS - hashType = WC_HASH_TYPE_SHA; - #endif - break; - default: - WOLFSSL_MSG("Bad hash sig algo"); - break; - } + /* Determine hash type */ + if (IsAtLeastTLSv1_2(ssl)) { + output[idx++] = ssl->suites->hashAlgo; + output[idx++] = ssl->suites->sigAlgo; - if (hashType == WC_HASH_TYPE_NONE) { - ERROR_OUT(ALGO_ID_E, exit_sske); - } - } else { - /* only using sha and md5 for rsa */ - #ifndef NO_OLD_TLS - hashType = WC_HASH_TYPE_SHA; - if (ssl->suites->sigAlgo == rsa_sa_algo) { - hashType = WC_HASH_TYPE_MD5_SHA; - } - #else + switch (ssl->suites->hashAlgo) { + case sha512_mac: + #ifdef WOLFSSL_SHA512 + hashType = WC_HASH_TYPE_SHA512; + #endif + break; + case sha384_mac: + #ifdef WOLFSSL_SHA384 + hashType = WC_HASH_TYPE_SHA384; + #endif + break; + case sha256_mac: + #ifndef NO_SHA256 + hashType = WC_HASH_TYPE_SHA256; + #endif + break; + case sha_mac: + #ifndef NO_OLD_TLS + hashType = WC_HASH_TYPE_SHA; + #endif + break; + default: + WOLFSSL_MSG("Bad hash sig algo"); + break; + } + + if (hashType == WC_HASH_TYPE_NONE) { ERROR_OUT(ALGO_ID_E, exit_sske); - #endif } - - /* signature size */ - c16toa((word16)sigSz, output + idx); - idx += LENGTH_SZ; - - /* Assemble buffer to hash for signature */ - sigDataSz = RAN_LEN + RAN_LEN + preSigSz; - sigDataBuf = (byte*)XMALLOC(sigDataSz, ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (sigDataBuf == NULL) { - ERROR_OUT(MEMORY_E, exit_sske); + } else { + /* only using sha and md5 for rsa */ + #ifndef NO_OLD_TLS + hashType = WC_HASH_TYPE_SHA; + if (ssl->suites->sigAlgo == rsa_sa_algo) { + hashType = WC_HASH_TYPE_MD5_SHA; } - XMEMCPY(sigDataBuf, ssl->arrays->clientRandom, RAN_LEN); - XMEMCPY(sigDataBuf+RAN_LEN, ssl->arrays->serverRandom, RAN_LEN); - XMEMCPY(sigDataBuf+RAN_LEN+RAN_LEN, output + preSigIdx, preSigSz); + #else + ERROR_OUT(ALGO_ID_E, exit_sske); + #endif + } - ssl->buffers.sig.length = wc_HashGetDigestSize(hashType); - ssl->buffers.sig.buffer = (byte*)XMALLOC( - ssl->buffers.sig.length, ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (ssl->buffers.sig.buffer == NULL) { - ERROR_OUT(MEMORY_E, exit_sske); - } + /* signature size */ + c16toa((word16)sigSz, output + idx); + idx += LENGTH_SZ; - /* Perform hash */ - ret = wc_Hash(hashType, sigDataBuf, sigDataSz, - ssl->buffers.sig.buffer, ssl->buffers.sig.length); - if (ret != 0) { - goto exit_sske; - } + /* Assemble buffer to hash for signature */ + sigDataSz = RAN_LEN + RAN_LEN + preSigSz; + sigDataBuf = (byte*)XMALLOC(sigDataSz, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (sigDataBuf == NULL) { + ERROR_OUT(MEMORY_E, exit_sske); + } + XMEMCPY(sigDataBuf, ssl->arrays->clientRandom, RAN_LEN); + XMEMCPY(sigDataBuf+RAN_LEN, ssl->arrays->serverRandom, RAN_LEN); + XMEMCPY(sigDataBuf+RAN_LEN+RAN_LEN, output + preSigIdx, preSigSz); - ssl->sigLen = sigSz; + ssl->buffers.sig.length = wc_HashGetDigestSize(hashType); + ssl->buffers.sig.buffer = (byte*)XMALLOC( + ssl->buffers.sig.length, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (ssl->buffers.sig.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_sske); + } - /* Sign hash to create signature */ - switch (ssl->suites->sigAlgo) + /* Perform hash */ + ret = wc_Hash(hashType, sigDataBuf, sigDataSz, + ssl->buffers.sig.buffer, ssl->buffers.sig.length); + if (ret != 0) { + goto exit_sske; + } + + ssl->sigLen = sigSz; + + /* Sign hash to create signature */ + switch (ssl->suites->sigAlgo) + { + #ifndef NO_RSA + case rsa_sa_algo: { - #ifndef NO_RSA - case rsa_sa_algo: - { - /* For TLS 1.2 re-encode signature */ - if (IsAtLeastTLSv1_2(ssl)) { - int typeH = 0; - byte* encodedSig = (byte*)XMALLOC( - MAX_ENCODED_SIG_SZ, ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (encodedSig == NULL) { - ERROR_OUT(MEMORY_E, exit_sske); - } - - switch (ssl->suites->hashAlgo) { - case sha512_mac: - #ifdef WOLFSSL_SHA512 - typeH = SHA512h; - #endif - break; - case sha384_mac: - #ifdef WOLFSSL_SHA384 - typeH = SHA384h; - #endif - break; - case sha256_mac: - #ifndef NO_SHA256 - typeH = SHA256h; - #endif - break; - case sha_mac: - #ifndef NO_OLD_TLS - typeH = SHAh; - #endif - break; - default: - break; - } - - ssl->buffers.sig.length = wc_EncodeSignature(encodedSig, - ssl->buffers.sig.buffer, ssl->buffers.sig.length, typeH); - - /* Replace sig buffer with new one */ - XFREE(ssl->buffers.sig.buffer, ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - ssl->buffers.sig.buffer = encodedSig; + /* For TLS 1.2 re-encode signature */ + if (IsAtLeastTLSv1_2(ssl)) { + int typeH = 0; + byte* encodedSig = (byte*)XMALLOC( + MAX_ENCODED_SIG_SZ, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig == NULL) { + ERROR_OUT(MEMORY_E, exit_sske); } - ret = RsaSign(ssl, - ssl->buffers.sig.buffer, - ssl->buffers.sig.length, - output + idx, - &ssl->sigLen, - (RsaKey*)ssl->sigKey, - ssl->buffers.key->buffer, - ssl->buffers.key->length, - #ifdef HAVE_PK_CALLBACKS - ssl->RsaSignCtx - #else - NULL - #endif - ); + switch (ssl->suites->hashAlgo) { + case sha512_mac: + #ifdef WOLFSSL_SHA512 + typeH = SHA512h; + #endif + break; + case sha384_mac: + #ifdef WOLFSSL_SHA384 + typeH = SHA384h; + #endif + break; + case sha256_mac: + #ifndef NO_SHA256 + typeH = SHA256h; + #endif + break; + case sha_mac: + #ifndef NO_OLD_TLS + typeH = SHAh; + #endif + break; + default: + break; + } + + ssl->buffers.sig.length = wc_EncodeSignature(encodedSig, + ssl->buffers.sig.buffer, ssl->buffers.sig.length, typeH); + + /* Replace sig buffer with new one */ + XFREE(ssl->buffers.sig.buffer, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + ssl->buffers.sig.buffer = encodedSig; + } + break; + } + #endif /* NO_RSA */ + } /* switch (ssl->suites->sigAlgo) */ + break; + } + #endif /* !defined(NO_DH) && !defined(NO_RSA) */ + } /* switch(ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_sske; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_DO; + } /* case KEYSHARE_BUILD */ + + case KEYSHARE_DO: + { + switch(ssl->specs.kea) + { + #ifndef NO_PSK + case psk_kea: + { + break; + } + #endif /* !NO_PSK */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + { + break; + } + #endif /* !defined(NO_DH) && !defined(NO_PSK) */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + break; + } + #endif /* HAVE_ECC && !NO_PSK */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: + { + /* Sign hash to create signature */ + switch (ssl->specs.sig_algo) + { + #ifndef NO_RSA + case rsa_sa_algo: + { + ret = RsaSign(ssl, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + output + idx, + &ssl->sigLen, + (RsaKey*)ssl->sigKey, + ssl->buffers.key->buffer, + ssl->buffers.key->length, + #ifdef HAVE_PK_CALLBACKS + ssl->RsaSignCtx + #else + NULL + #endif + ); + break; + } + #endif /* !NO_RSA */ + case ecc_dsa_sa_algo: + { + ret = EccSign(ssl, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + output + LENGTH_SZ + idx, + &ssl->sigLen, + (ecc_key*)ssl->sigKey, + #if defined(HAVE_PK_CALLBACKS) + ssl->buffers.key->buffer, + ssl->buffers.key->length, + ssl->EccSignCtx + #else + NULL, 0, NULL + #endif + ); + break; + } + } /* switch(ssl->specs.sig_algo) */ + break; + } + #endif /* HAVE_ECC */ + #if !defined(NO_DH) && !defined(NO_RSA) + case diffie_hellman_kea: + { + /* Sign hash to create signature */ + switch (ssl->suites->sigAlgo) + { + #ifndef NO_RSA + case rsa_sa_algo: + { + if (ssl->options.usingAnon_cipher) { break; } - #endif /* NO_RSA */ - } /* switch (ssl->suites->sigAlgo) */ - } /* !ssl->options.usingAnon_cipher */ + + ret = RsaSign(ssl, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + output + idx, + &ssl->sigLen, + (RsaKey*)ssl->sigKey, + ssl->buffers.key->buffer, + ssl->buffers.key->length, + #ifdef HAVE_PK_CALLBACKS + ssl->RsaSignCtx + #else + NULL + #endif + ); + break; + } + #endif /* NO_RSA */ + } /* switch (ssl->suites->sigAlgo) */ break; } @@ -16873,7 +17354,7 @@ int DoSessionTicket(WOLFSSL* ssl, /* Advance state and proceed */ ssl->options.keyShareState = KEYSHARE_VERIFY; - } /* case KEYSHARE_BUILD */ + } /* case KEYSHARE_DO */ case KEYSHARE_VERIFY: { @@ -16908,13 +17389,21 @@ int DoSessionTicket(WOLFSSL* ssl, #ifndef NO_RSA case rsa_sa_algo: { + if (verifySig == NULL) { + verifySig = (byte*)XMALLOC(ssl->sigLen, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (!verifySig) { + ERROR_OUT(MEMORY_E, exit_sske); + } + XMEMCPY(verifySig, output + idx, ssl->sigLen); + } + /* check for signature faults */ ret = VerifyRsaSign(ssl, - output + idx, - ssl->sigLen, - ssl->buffers.sig.buffer, - ssl->buffers.sig.length, - (RsaKey*)ssl->sigKey); + verifySig, ssl->sigLen, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + (RsaKey*)ssl->sigKey); break; } #endif @@ -16942,15 +17431,25 @@ int DoSessionTicket(WOLFSSL* ssl, #ifndef NO_RSA case rsa_sa_algo: { - if (!ssl->options.usingAnon_cipher) { - /* check for signature faults */ - ret = VerifyRsaSign(ssl, - output + idx, - ssl->sigLen, - ssl->buffers.sig.buffer, - ssl->buffers.sig.length, - (RsaKey*)ssl->sigKey); + if (ssl->options.usingAnon_cipher) { + break; } + + if (verifySig == NULL) { + verifySig = (byte*)XMALLOC(ssl->sigLen, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (!verifySig) { + ERROR_OUT(MEMORY_E, exit_sske); + } + XMEMCPY(verifySig, output + idx, ssl->sigLen); + } + + /* check for signature faults */ + ret = VerifyRsaSign(ssl, + verifySig, ssl->sigLen, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + (RsaKey*)ssl->sigKey); break; } #endif @@ -17006,7 +17505,7 @@ int DoSessionTicket(WOLFSSL* ssl, #endif /* HAVE_ECC */ #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { goto exit_sske; } @@ -17053,6 +17552,8 @@ int DoSessionTicket(WOLFSSL* ssl, exit_sske: + WOLFSSL_LEAVE("SendServerKeyExchange", ret); + /* Handle cleanup for stack variables here */ #if defined(HAVE_ECC) if (exportBuf) { @@ -17067,7 +17568,8 @@ int DoSessionTicket(WOLFSSL* ssl, } #endif -#ifdef WOLFSSL_ASYNC_CRYPT + + #ifdef WOLFSSL_ASYNC_CRYPT /* Handle WC_PENDING_E */ if (ret == WC_PENDING_E) { /* Store variables needed for async */ @@ -17077,14 +17579,24 @@ int DoSessionTicket(WOLFSSL* ssl, ssl->async.idx = idx; ssl->async.length = length; ssl->async.sigSz = sigSz; + #ifndef NO_RSA + ssl->async.data = verifySig; + #endif /* Push event to queue */ - ret = wolfSSL_async_push(ssl, WOLF_EVENT_TYPE_ASYNC_ACCEPT); + ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, &ssl->event); if (ret == 0) { return WC_PENDING_E; } } -#endif + #endif + + #ifndef NO_RSA + if (verifySig) { + XFREE(verifySig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + verifySig = NULL; + } + #endif /* Final cleanup */ FreeKeyExchange(ssl); @@ -17460,7 +17972,7 @@ int DoSessionTicket(WOLFSSL* ssl, XMEMCPY(&pv, input + i, OPAQUE16_LEN); ssl->chVersion = pv; /* store */ #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret; #if defined(NO_SHA) && defined(NO_SHA256) #error "DTLS needs either SHA or SHA-256" @@ -17537,7 +18049,7 @@ int DoSessionTicket(WOLFSSL* ssl, /* random */ XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN); if (ret != 0) return ret; } @@ -17570,7 +18082,7 @@ int DoSessionTicket(WOLFSSL* ssl, XMEMCPY(ssl->arrays->sessionID, input + i, b); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); if (ret != 0) return ret; } @@ -17624,7 +18136,7 @@ int DoSessionTicket(WOLFSSL* ssl, XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { int ret = wc_HmacUpdate(&cookieHmac, input + i - OPAQUE16_LEN, clSuites.suiteSz + OPAQUE16_LEN); @@ -17640,8 +18152,13 @@ int DoSessionTicket(WOLFSSL* ssl, if ((i - begin) + b > helloSz) return BUFFER_ERROR; + if (b == 0) { + WOLFSSL_MSG("No compression types in list"); + return COMPRESSION_ERROR; + } + #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { byte newCookie[MAX_COOKIE_LEN]; int ret; @@ -17679,23 +18196,34 @@ int DoSessionTicket(WOLFSSL* ssl, } #endif /* WOLFSSL_DTLS */ - if (ssl->options.usingCompression) { - int match = 0; + { + /* copmression match types */ + int matchNo = 0; + int matchZlib = 0; while (b--) { byte comp = input[i++]; - if (comp == ZLIB_COMPRESSION) - match = 1; + if (comp == NO_COMPRESSION) { + matchNo = 1; + } + if (comp == ZLIB_COMPRESSION) { + matchZlib = 1; + } } - if (!match) { - WOLFSSL_MSG("Not matching compression, turning off"); + if (ssl->options.usingCompression == 0 && matchNo) { + WOLFSSL_MSG("Matched No Compression"); + } else if (ssl->options.usingCompression && matchZlib) { + WOLFSSL_MSG("Matched zlib Compression"); + } else if (ssl->options.usingCompression && matchNo) { + WOLFSSL_MSG("Could only match no compression, turning off"); ssl->options.usingCompression = 0; /* turn off */ + } else { + WOLFSSL_MSG("Could not match compression"); + return COMPRESSION_ERROR; } } - else - i += b; /* ignore, since we're not on */ *inOutIdx = i; @@ -17768,6 +18296,10 @@ int DoSessionTicket(WOLFSSL* ssl, if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX) clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX; } +#ifdef HAVE_EXTENDED_MASTER + else if (extId == HELLO_EXT_EXTMS) + ssl->options.haveEMS = 1; +#endif else i += extSz; @@ -17801,6 +18333,22 @@ int DoSessionTicket(WOLFSSL* ssl, WOLFSSL_MSG("Session lookup for resume failed"); ssl->options.resuming = 0; } + else if (session->haveEMS != ssl->options.haveEMS) { + /* RFC 7627, 5.3, server-side */ + /* if old sess didn't have EMS, but new does, full handshake */ + if (!session->haveEMS && ssl->options.haveEMS) { + WOLFSSL_MSG("Attempting to resume a session that didn't " + "use EMS with a new session with EMS. Do full " + "handshake."); + ssl->options.resuming = 0; + } + /* if old sess used EMS, but new doesn't, MUST abort */ + else if (session->haveEMS && !ssl->options.haveEMS) { + WOLFSSL_MSG("Trying to resume a session with EMS without " + "using EMS"); + return EXT_MASTER_SECRET_NEEDED_E; + } + } else { if (MatchSuite(ssl, &clSuites) < 0) { WOLFSSL_MSG("Unsupported cipher suite, ClientHello"); @@ -17830,179 +18378,329 @@ int DoSessionTicket(WOLFSSL* ssl, return MatchSuite(ssl, &clSuites); } + #if !defined(NO_RSA) || defined(HAVE_ECC) - static int DoCertificateVerify(WOLFSSL* ssl, byte* input, word32* inOutIdx, - word32 size) + + static int DoCertificateVerify(WOLFSSL* ssl, byte* input, + word32* inOutIdx, word32 size) { + int ret = 0; + byte* output = NULL; + word32 sendSz = 0; word16 sz = 0; - int ret = VERIFY_CERT_ERROR; /* start in error state */ + word32 sigSz = 0; byte hashAlgo = sha_mac; byte sigAlgo = anonymous_sa_algo; - word32 begin = *inOutIdx; + word32 idx = *inOutIdx, begin = *inOutIdx; - #ifdef WOLFSSL_CALLBACKS - if (ssl->hsInfoOn) - AddPacketName("CertificateVerify", &ssl->handShakeInfo); - if (ssl->toInfoOn) - AddLateName("CertificateVerify", &ssl->timeoutInfo); - #endif + WOLFSSL_ENTER("DoCertificateVerify"); + (void)sigSz; + (void)output; + (void)sendSz; - if (IsAtLeastTLSv1_2(ssl)) { - if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size) - return BUFFER_ERROR; + #ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_EventPop(&ssl->event, WOLF_EVENT_TYPE_ASYNC_ANY); + if (ret != WC_NOT_PENDING_E) { + WOLF_EVENT_TYPE eType = ssl->event.type; - hashAlgo = input[(*inOutIdx)++]; - sigAlgo = input[(*inOutIdx)++]; - } + /* Clear event */ + XMEMSET(&ssl->event, 0, sizeof(ssl->event)); - if ((*inOutIdx - begin) + OPAQUE16_LEN > size) - return BUFFER_ERROR; - - ato16(input + *inOutIdx, &sz); - *inOutIdx += OPAQUE16_LEN; - - if ((*inOutIdx - begin) + sz > size || sz > ENCRYPT_LEN) - return BUFFER_ERROR; - - /* RSA */ -#ifndef NO_RSA - if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) { - byte* out = NULL; - int outLen = 0; - - WOLFSSL_MSG("Doing RSA peer cert verify"); - - outLen = RsaVerify(ssl, - input + *inOutIdx, - sz, - &out, - ssl->peerRsaKey, -#ifdef HAVE_PK_CALLBACKS - ssl->buffers.peerRsaKey.buffer, - ssl->buffers.peerRsaKey.length, - ssl->RsaVerifyCtx -#else - NULL, 0, NULL -#endif - ); - - if (IsAtLeastTLSv1_2(ssl)) { -#ifdef WOLFSSL_SMALL_STACK - byte* encodedSig = NULL; -#else - byte encodedSig[MAX_ENCODED_SIG_SZ]; -#endif - word32 sigSz; - byte* digest = ssl->hsHashes->certHashes.sha; - int typeH = SHAh; - int digestSz = SHA_DIGEST_SIZE; - -#ifdef WOLFSSL_SMALL_STACK - encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (encodedSig == NULL) - return MEMORY_E; -#endif - - if (sigAlgo != rsa_sa_algo) { - WOLFSSL_MSG("Oops, peer sent RSA key but not in verify"); - } - - if (hashAlgo == sha256_mac) { - #ifndef NO_SHA256 - digest = ssl->hsHashes->certHashes.sha256; - typeH = SHA256h; - digestSz = SHA256_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha384_mac) { - #ifdef WOLFSSL_SHA384 - digest = ssl->hsHashes->certHashes.sha384; - typeH = SHA384h; - digestSz = SHA384_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha512_mac) { - #ifdef WOLFSSL_SHA512 - digest = ssl->hsHashes->certHashes.sha512; - typeH = SHA512h; - digestSz = SHA512_DIGEST_SIZE; - #endif - } - - sigSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH); - - if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig, - min(sigSz, MAX_ENCODED_SIG_SZ)) == 0) - ret = 0; /* verified */ - -#ifdef WOLFSSL_SMALL_STACK - XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + /* Check for error */ + if (ret < 0) { + goto exit_dcv; } - else { - if (outLen == FINISHED_SZ && out && XMEMCMP(out, - &ssl->hsHashes->certHashes, - FINISHED_SZ) == 0) { - ret = 0; /* verified */ + else { + /* Restore variables needed for async */ + output = ssl->async.output; + sendSz = ssl->async.sendSz; + idx = ssl->async.idx; + sigSz = ssl->async.sigSz; + sz = ssl->async.length; + sigAlgo = ssl->async.sigAlgo; + hashAlgo = ssl->async.hashAlgo; + + /* Advance key share state if not wolfCrypt */ + if (eType == WOLF_EVENT_TYPE_ASYNC_WOLFSSL) { + ssl->options.keyShareState++; } } } -#endif -#ifdef HAVE_ECC - if (ssl->peerEccDsaKeyPresent) { - byte* digest = ssl->hsHashes->certHashes.sha; - word32 digestSz = SHA_DIGEST_SIZE; + else + #endif + { + /* Reset state */ + ret = 0; + ssl->options.keyShareState = KEYSHARE_BEGIN; + } - WOLFSSL_MSG("Doing ECC peer cert verify"); - - if (IsAtLeastTLSv1_2(ssl)) { - if (sigAlgo != ecc_dsa_sa_algo) { - WOLFSSL_MSG("Oops, peer sent ECC key but not in verify"); - } - - if (hashAlgo == sha256_mac) { - #ifndef NO_SHA256 - digest = ssl->hsHashes->certHashes.sha256; - digestSz = SHA256_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha384_mac) { - #ifdef WOLFSSL_SHA384 - digest = ssl->hsHashes->certHashes.sha384; - digestSz = SHA384_DIGEST_SIZE; - #endif - } - else if (hashAlgo == sha512_mac) { - #ifdef WOLFSSL_SHA512 - digest = ssl->hsHashes->certHashes.sha512; - digestSz = SHA512_DIGEST_SIZE; - #endif - } - } - - ret = EccVerify(ssl, - input + *inOutIdx, sz, - digest, digestSz, - ssl->peerEccDsaKey, - #ifdef HAVE_PK_CALLBACKS - ssl->buffers.peerEccDsaKey.buffer, - ssl->buffers.peerEccDsaKey.length, - ssl->EccVerifyCtx - #else - NULL, 0, NULL + switch(ssl->options.keyShareState) + { + case KEYSHARE_BEGIN: + { + #ifdef WOLFSSL_CALLBACKS + if (ssl->hsInfoOn) + AddPacketName("CertificateVerify", &ssl->handShakeInfo); + if (ssl->toInfoOn) + AddLateName("CertificateVerify", &ssl->timeoutInfo); #endif - ); - } -#endif - *inOutIdx += sz; - if (ret == 0) - ssl->options.havePeerVerify = 1; + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_BUILD; + } /* case KEYSHARE_BEGIN */ + + case KEYSHARE_BUILD: + { + if (IsAtLeastTLSv1_2(ssl)) { + if ((idx - begin) + ENUM_LEN + ENUM_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dcv); + } + + hashAlgo = input[idx++]; + sigAlgo = input[idx++]; + } + + if ((idx - begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dcv); + } + + ato16(input + idx, &sz); + idx += OPAQUE16_LEN; + + if ((idx - begin) + sz > size || sz > ENCRYPT_LEN) { + ERROR_OUT(BUFFER_ERROR, exit_dcv); + } + + #ifdef HAVE_ECC + if (ssl->peerEccDsaKeyPresent) { + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha; + ssl->buffers.digest.length = SHA_DIGEST_SIZE; + + WOLFSSL_MSG("Doing ECC peer cert verify"); + + if (IsAtLeastTLSv1_2(ssl)) { + if (sigAlgo != ecc_dsa_sa_algo) { + WOLFSSL_MSG("Oops, peer sent ECC key but not in verify"); + } + + if (hashAlgo == sha256_mac) { + #ifndef NO_SHA256 + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256; + ssl->buffers.digest.length = SHA256_DIGEST_SIZE; + #endif + } + else if (hashAlgo == sha384_mac) { + #ifdef WOLFSSL_SHA384 + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384; + ssl->buffers.digest.length = SHA384_DIGEST_SIZE; + #endif + } + else if (hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512; + ssl->buffers.digest.length = SHA512_DIGEST_SIZE; + #endif + } + } + } + #endif /* HAVE_ECC */ + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_DO; + } /* case KEYSHARE_BUILD */ + + case KEYSHARE_DO: + { + #ifndef NO_RSA + if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) { + WOLFSSL_MSG("Doing RSA peer cert verify"); + + ret = RsaVerify(ssl, + input + idx, + sz, + &output, + ssl->peerRsaKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.peerRsaKey.buffer, + ssl->buffers.peerRsaKey.length, + ssl->RsaVerifyCtx + #else + NULL, 0, NULL + #endif + ); + if (ret >= 0) { + sendSz = ret; + ret = 0; + } + } + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + if (ssl->peerEccDsaKeyPresent) { + WOLFSSL_MSG("Doing ECC peer cert verify"); + + ret = EccVerify(ssl, + input + idx, sz, + ssl->buffers.digest.buffer, ssl->buffers.digest.length, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.peerEccDsaKey.buffer, + ssl->buffers.peerEccDsaKey.length, + ssl->EccVerifyCtx + #else + NULL, 0, NULL + #endif + ); + } + #endif /* HAVE_ECC */ + + /* Check for error */ + if (ret != 0) { + goto exit_dcv; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_VERIFY; + } /* case KEYSHARE_DO */ + + case KEYSHARE_VERIFY: + { + #ifndef NO_RSA + if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) { + if (IsAtLeastTLSv1_2(ssl)) { + #ifdef WOLFSSL_SMALL_STACK + byte* encodedSig = NULL; + #else + byte encodedSig[MAX_ENCODED_SIG_SZ]; + #endif + int typeH = SHAh; + + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha; + ssl->buffers.digest.length = SHA_DIGEST_SIZE; + + #ifdef WOLFSSL_SMALL_STACK + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig == NULL) { + ERROR_OUT(MEMORY_E, exit_dcv); + } + #endif + + if (sigAlgo != rsa_sa_algo) { + WOLFSSL_MSG("Oops, peer sent RSA key but not in verify"); + } + + switch (hashAlgo) { + #ifndef NO_SHA256 + case sha256_mac: + typeH = SHA256h; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256; + ssl->buffers.digest.length = SHA256_DIGEST_SIZE; + break; + #endif /* !NO_SHA256 */ + #ifdef WOLFSSL_SHA384 + case sha384_mac: + typeH = SHA384h; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384; + ssl->buffers.digest.length = SHA384_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case sha512_mac: + typeH = SHA512h; + ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512; + ssl->buffers.digest.length = SHA512_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA512 */ + } /* switch */ + + sigSz = wc_EncodeSignature(encodedSig, + ssl->buffers.digest.buffer, ssl->buffers.digest.length, + typeH); + + if (sendSz != sigSz || !output || XMEMCMP(output, + encodedSig, min(sigSz, MAX_ENCODED_SIG_SZ)) != 0) { + ret = VERIFY_CERT_ERROR; + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + } + else { + if (sendSz != FINISHED_SZ || !output || XMEMCMP(output, + &ssl->hsHashes->certHashes, FINISHED_SZ) != 0) { + ret = VERIFY_CERT_ERROR; + } + } + } + #endif /* !NO_RSA */ + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_FINALIZE; + } /* case KEYSHARE_VERIFY */ + + case KEYSHARE_FINALIZE: + { + ssl->options.havePeerVerify = 1; + + /* Set final index */ + idx += sz; + *inOutIdx = idx; + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_END; + } /* case KEYSHARE_FINALIZE */ + + case KEYSHARE_END: + { + break; + } + default: + ret = INPUT_CASE_ERROR; + } /* switch(ssl->options.keyShareState) */ + + exit_dcv: + + WOLFSSL_LEAVE("DoCertificateVerify", ret); + + /* Handle cleanup for stack variables here */ + + + #ifdef WOLFSSL_ASYNC_CRYPT + /* Handle WC_PENDING_E */ + if (ret == WC_PENDING_E) { + /* Store variables needed for async */ + XMEMSET(&ssl->async, 0, sizeof(ssl->async)); + ssl->async.output = output; + ssl->async.sendSz = sendSz; + ssl->async.idx = idx; + ssl->async.sigSz = sigSz; + ssl->async.length = sz; + ssl->async.sigAlgo = sigAlgo; + ssl->async.hashAlgo = hashAlgo; + + /* Mark message as not recevied so it can process again */ + ssl->msgsReceived.got_certificate_verify = 0; + + /* Push event to queue */ + ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, &ssl->event); + if (ret == 0) { + return WC_PENDING_E; + } + } + #endif /* WOLFSSL_ASYNC_CRYPT */ + + /* Digest is not allocated, so do this to prevent free */ + ssl->buffers.digest.buffer = NULL; + ssl->buffers.digest.length = 0; + + /* Final cleanup */ + FreeKeyExchange(ssl); return ret; } + #endif /* !NO_RSA || HAVE_ECC */ int SendServerHelloDone(WOLFSSL* ssl) @@ -18026,7 +18724,7 @@ int DoSessionTicket(WOLFSSL* ssl, AddHeaders(output, 0, server_hello_done, ssl); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return 0; } @@ -18063,6 +18761,7 @@ int DoSessionTicket(WOLFSSL* ssl, byte suite[SUITE_LEN]; /* cipher suite when created */ byte msecret[SECRET_LEN]; /* master secret */ word32 timestamp; /* born on */ + word16 haveEMS; /* have extended master secret */ } InternalTicket; /* fit within SESSION_TICKET_LEN */ @@ -18084,6 +18783,8 @@ int DoSessionTicket(WOLFSSL* ssl, int ret; byte zeros[WOLFSSL_TICKET_MAC_SZ]; /* biggest cmp size */ + XMEMSET(&it, 0, sizeof(it)); + /* build internal */ it.pv.major = ssl->version.major; it.pv.minor = ssl->version.minor; @@ -18093,6 +18794,7 @@ int DoSessionTicket(WOLFSSL* ssl, XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN); c32toa(LowResTimer(), (byte*)&it.timestamp); + it.haveEMS = ssl->options.haveEMS; /* build external */ XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket)); @@ -18184,8 +18886,12 @@ int DoSessionTicket(WOLFSSL* ssl, } /* get master secret */ - if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) + if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) { XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN); + /* Copy the haveExtendedMasterSecret property from the ticket to + * the saved session, so the property may be checked later. */ + ssl->session.haveEMS = it->haveEMS; + } return ret; } @@ -18200,13 +18906,6 @@ int DoSessionTicket(WOLFSSL* ssl, word32 length = SESSION_HINT_SZ + LENGTH_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; - #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { - length += DTLS_RECORD_EXTRA; - idx += DTLS_RECORD_EXTRA; - } - #endif - if (ssl->options.createTicket) { ret = CreateTicket(ssl); if (ret != 0) return ret; @@ -18215,6 +18914,12 @@ int DoSessionTicket(WOLFSSL* ssl, length += ssl->session.ticketLen; sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + } + #endif /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) return ret; @@ -18237,6 +18942,13 @@ int DoSessionTicket(WOLFSSL* ssl, XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen); /* idx += ssl->session.ticketLen; */ + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) + return ret; + } + #endif + ret = HashOutput(ssl, output, sendSz, 0); if (ret != 0) return ret; ssl->buffers.outputBuffer.length += sendSz; @@ -18296,7 +19008,7 @@ int DoSessionTicket(WOLFSSL* ssl, return SendBuffered(ssl); } -#endif +#endif /* WOLFSSL_DTLS */ static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size) @@ -18314,12 +19026,19 @@ int DoSessionTicket(WOLFSSL* ssl, (void)idx; (void)output; + WOLFSSL_ENTER("DoClientKeyExchange"); + #ifdef WOLFSSL_ASYNC_CRYPT - /* Use async output pointer */ + /* use async pointer for output */ output = &ssl->async.output; - ret = wolfSSL_async_pop(ssl, WOLF_EVENT_TYPE_ASYNC_ACCEPT); - if (ret != ASYNC_NOT_PENDING) { + ret = wolfAsync_EventPop(&ssl->event, WOLF_EVENT_TYPE_ASYNC_ANY); + if (ret != WC_NOT_PENDING_E) { + WOLF_EVENT_TYPE eType = ssl->event.type; + + /* Clear event */ + XMEMSET(&ssl->event, 0, sizeof(ssl->event)); + /* Check for error */ if (ret < 0) { goto exit_dcke; @@ -18329,12 +19048,14 @@ int DoSessionTicket(WOLFSSL* ssl, idx = ssl->async.idx; length = ssl->async.length; - /* Advance state */ - ssl->options.keyShareState++; + /* Advance key share state if not wolfCrypt */ + if (eType == WOLF_EVENT_TYPE_ASYNC_WOLFSSL) { + ssl->options.keyShareState++; + } } } else - #endif + #endif /* WOLFSSL_ASYNC_CRYPT */ { /* Reset state */ ret = 0; @@ -18374,7 +19095,7 @@ int DoSessionTicket(WOLFSSL* ssl, return NO_PEER_CERT; } } - #endif + #endif /* !NO_CERTS */ #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) { @@ -18489,13 +19210,14 @@ int DoSessionTicket(WOLFSSL* ssl, } ssl->sigType = DYNAMIC_TYPE_RSA; - ret = wc_InitRsaKey((RsaKey*)ssl->sigKey, ssl->heap); + ret = wc_InitRsaKey_ex((RsaKey*)ssl->sigKey, ssl->heap, + ssl->devId); if (ret != 0) { goto exit_dcke; } - ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &i, - (RsaKey*)ssl->sigKey, ssl->buffers.key->length); + ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, + &i, (RsaKey*)ssl->sigKey, ssl->buffers.key->length); if (ret != 0) { goto exit_dcke; } @@ -18532,22 +19254,7 @@ int DoSessionTicket(WOLFSSL* ssl, ERROR_OUT(BUFFER_ERROR, exit_dcke); } - /* These RSA variables persist throughout DoClientKeyExchange */ *output = NULL; - ret = RsaDec(ssl, - input + idx, - length, - output, - &ssl->sigLen, - (RsaKey*)ssl->sigKey, - #if defined(HAVE_PK_CALLBACKS) - ssl->buffers.key->buffer, - ssl->buffers.key->length, - ssl->RsaDecCtx - #else - NULL, 0, NULL - #endif - ); break; } /* rsa_kea */ #endif /* !NO_RSA */ @@ -18636,7 +19343,6 @@ int DoSessionTicket(WOLFSSL* ssl, idx += cipherLen; ssl->arrays->preMasterSz = plainLen; - break; } #endif /* HAVE_NTRU */ @@ -18656,7 +19362,10 @@ int DoSessionTicket(WOLFSSL* ssl, } ssl->sigType = DYNAMIC_TYPE_ECC; - wc_ecc_init_h((ecc_key*)ssl->sigKey, ssl->heap); + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, ssl->devId); + if (ret != 0) { + goto exit_dcke; + } ret = wc_EccPrivateKeyDecode( ssl->buffers.key->buffer, @@ -18666,7 +19375,7 @@ int DoSessionTicket(WOLFSSL* ssl, if (ret == 0) { private_key = (ecc_key*)ssl->sigKey; if (wc_ecc_size(private_key) < - ssl->options.minEccKeySz) { + ssl->options.minEccKeySz) { WOLFSSL_MSG("ECC key too small"); ERROR_OUT(ECC_KEY_SIZE_E, exit_dcke); } @@ -18692,11 +19401,19 @@ int DoSessionTicket(WOLFSSL* ssl, WOLFSSL_MSG("PeerEccKey Memory error"); ERROR_OUT(MEMORY_E, exit_dcke); } - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ wc_ecc_free(ssl->peerEccKey); ssl->peerEccKeyPresent = 0; - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } } if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey, @@ -18710,12 +19427,8 @@ int DoSessionTicket(WOLFSSL* ssl, ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); if (ret != 0) { - ERROR_OUT(ECC_SHARED_ERROR, exit_dcke); + goto exit_dcke; } - - /* Generate shared secret */ - ret = EccSharedSecret(ssl, private_key, ssl->peerEccKey, - ssl->arrays->preMasterSecret, &ssl->sigLen); break; } #endif /* HAVE_ECC */ @@ -18735,28 +19448,13 @@ int DoSessionTicket(WOLFSSL* ssl, ERROR_OUT(BUFFER_ERROR, exit_dcke); } - ret = DhAgree(ssl, - ssl->buffers.serverDH_P.buffer, - ssl->buffers.serverDH_P.length, - ssl->buffers.serverDH_G.buffer, - ssl->buffers.serverDH_G.length, - ssl->buffers.serverDH_Priv.buffer, - &ssl->buffers.serverDH_Priv.length, - NULL, - 0, - input + idx, - clientPubSz, - ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz); - - idx += clientPubSz; + ssl->sigLen = clientPubSz; break; } #endif /* !NO_DH */ #if !defined(NO_DH) && !defined(NO_PSK) case dhe_psk_kea: { - byte* pms = ssl->arrays->preMasterSecret; word16 clientSz; /* Read in the PSK hint */ @@ -18791,41 +19489,7 @@ int DoSessionTicket(WOLFSSL* ssl, ERROR_OUT(BUFFER_ERROR, exit_dcke); } - ret = DhAgree(ssl, - ssl->buffers.serverDH_P.buffer, - ssl->buffers.serverDH_P.length, - ssl->buffers.serverDH_G.buffer, - ssl->buffers.serverDH_G.length, - ssl->buffers.serverDH_Priv.buffer, - &ssl->buffers.serverDH_Priv.length, - NULL, - 0, - input + idx, - clientSz, - pms + OPAQUE16_LEN, - &ssl->arrays->preMasterSz); - - idx += clientSz; - c16toa((word16)ssl->arrays->preMasterSz, pms); - ssl->arrays->preMasterSz += OPAQUE16_LEN; - pms += ssl->arrays->preMasterSz; - - /* Use the PSK hint to look up the PSK and add it to the - * preMasterSecret here. */ - ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl, - ssl->arrays->client_identity, ssl->arrays->psk_key, - MAX_PSK_KEY_LEN); - - if (ssl->arrays->psk_keySz == 0 || - ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { - ERROR_OUT(PSK_KEY_ERROR, exit_dcke); - } - - c16toa((word16) ssl->arrays->psk_keySz, pms); - pms += OPAQUE16_LEN; - - XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); - ssl->arrays->preMasterSz += ssl->arrays->psk_keySz + OPAQUE16_LEN; + ssl->sigLen = clientSz; break; } #endif /* !NO_DH && !NO_PSK */ @@ -18873,11 +19537,19 @@ int DoSessionTicket(WOLFSSL* ssl, WOLFSSL_MSG("PeerEccKey Memory error"); ERROR_OUT(MEMORY_E, exit_dcke); } - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ wc_ecc_free(ssl->peerEccKey); ssl->peerEccKeyPresent = 0; - wc_ecc_init_h(ssl->peerEccKey, ssl->heap); + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } } if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey, ssl->eccTempKey->dp->id)) { @@ -18890,6 +19562,121 @@ int DoSessionTicket(WOLFSSL* ssl, /* Note sizeof preMasterSecret is ENCRYPT_LEN currently 512 */ ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); + if (ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + } + break; + } + #endif /* HAVE_ECC && !NO_PSK */ + default: + ret = BAD_KEA_TYPE_E; + } /* switch (ssl->specs.kea) */ + + /* Check for error */ + if (ret != 0) { + goto exit_dcke; + } + + /* Advance state and proceed */ + ssl->options.keyShareState = KEYSHARE_DO; + } /* KEYSHARE_BUILD */ + + case KEYSHARE_DO: + { + switch (ssl->specs.kea) { + #ifndef NO_RSA + case rsa_kea: + { + ret = RsaDec(ssl, + input + idx, + length, + output, + &ssl->sigLen, + (RsaKey*)ssl->sigKey, + #if defined(HAVE_PK_CALLBACKS) + ssl->buffers.key->buffer, + ssl->buffers.key->length, + ssl->RsaDecCtx + #else + NULL, 0, NULL + #endif + ); + break; + } /* rsa_kea */ + #endif /* !NO_RSA */ + #ifndef NO_PSK + case psk_kea: + { + break; + } + #endif /* !NO_PSK */ + #ifdef HAVE_NTRU + case ntru_kea: + { + break; + } + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: + { + ecc_key* private_key = ssl->eccTempKey; + if (ssl->specs.static_ecdh) { + private_key = (ecc_key*)ssl->sigKey; + } + + /* Generate shared secret */ + ret = EccSharedSecret(ssl, private_key, ssl->peerEccKey, + ssl->arrays->preMasterSecret, &ssl->sigLen); + break; + } + #endif /* HAVE_ECC */ + #ifndef NO_DH + case diffie_hellman_kea: + { + word16 clientPubSz = (word16)ssl->sigLen; + + ret = DhAgree(ssl, + ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length, + ssl->buffers.serverDH_Priv.buffer, + &ssl->buffers.serverDH_Priv.length, + NULL, + 0, + input + idx, + clientPubSz, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz); + break; + } + #endif /* !NO_DH */ + #if !defined(NO_DH) && !defined(NO_PSK) + case dhe_psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; + word16 clientSz = ssl->sigLen; + + ret = DhAgree(ssl, + ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length, + ssl->buffers.serverDH_Priv.buffer, + &ssl->buffers.serverDH_Priv.length, + NULL, + 0, + input + idx, + clientSz, + pms + OPAQUE16_LEN, + &ssl->arrays->preMasterSz); + break; + } + #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { /* Generate shared secret */ ret = EccSharedSecret(ssl, ssl->eccTempKey, @@ -18910,7 +19697,7 @@ int DoSessionTicket(WOLFSSL* ssl, /* Advance state and proceed */ ssl->options.keyShareState = KEYSHARE_VERIFY; - } /* KEYSHARE_BUILD */ + } /* KEYSHARE_DO */ case KEYSHARE_VERIFY: { @@ -18956,12 +19743,38 @@ int DoSessionTicket(WOLFSSL* ssl, #ifndef NO_DH case diffie_hellman_kea: { + word16 clientPubSz = (word16)ssl->sigLen; + idx += clientPubSz; break; } #endif /* !NO_DH */ #if !defined(NO_DH) && !defined(NO_PSK) case dhe_psk_kea: { + byte* pms = ssl->arrays->preMasterSecret; + word16 clientSz = ssl->sigLen; + + idx += clientSz; + c16toa((word16)ssl->arrays->preMasterSz, pms); + ssl->arrays->preMasterSz += OPAQUE16_LEN; + pms += ssl->arrays->preMasterSz; + + /* Use the PSK hint to look up the PSK and add it to the + * preMasterSecret here. */ + ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl, + ssl->arrays->client_identity, ssl->arrays->psk_key, + MAX_PSK_KEY_LEN); + + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { + ERROR_OUT(PSK_KEY_ERROR, exit_dcke); + } + + c16toa((word16) ssl->arrays->psk_keySz, pms); + pms += OPAQUE16_LEN; + + XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->preMasterSz += ssl->arrays->psk_keySz + OPAQUE16_LEN; break; } #endif /* !NO_DH && !NO_PSK */ @@ -19034,7 +19847,7 @@ int DoSessionTicket(WOLFSSL* ssl, ERROR_OUT(BUFFER_ERROR, exit_dcke); } } - #endif + #endif /* HAVE_QSH */ ret = MakeMasterSecret(ssl); /* Check for error */ @@ -19064,26 +19877,32 @@ int DoSessionTicket(WOLFSSL* ssl, } /* switch(ssl->options.keyShareState) */ exit_dcke: + + WOLFSSL_LEAVE("DoClientKeyExchange", ret); + + /* Handle cleanup for stack variables here */ + + #ifdef WOLFSSL_ASYNC_CRYPT /* Handle WC_PENDING_E */ if (ret == WC_PENDING_E) { /* Store variables needed for async */ + output_lcl = ssl->async.output; XMEMSET(&ssl->async, 0, sizeof(ssl->async)); ssl->async.idx = idx; ssl->async.length = length; + ssl->async.output = output_lcl; - /* Adjust the index so header will be re-evaluated */ - *inOutIdx -= HANDSHAKE_HEADER_SZ; /* Mark message as not recevied so it can process again */ ssl->msgsReceived.got_client_key_exchange = 0; /* Push event to queue */ - ret = wolfSSL_async_push(ssl, WOLF_EVENT_TYPE_ASYNC_ACCEPT); + ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, &ssl->event); if (ret == 0) { return WC_PENDING_E; } } - #endif + #endif /* WOLFSSL_ASYNC_CRYPT */ /* Cleanup PMS */ ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz); diff --git a/src/io.c b/src/io.c index ed0971dffa..a37052b3a9 100644 --- a/src/io.c +++ b/src/io.c @@ -1015,7 +1015,7 @@ static int process_http_response(int sfd, byte** respBuf, XMEMCPY(recvBuf, start, len); /* receive the OCSP response data */ - do { + while (len < recvBufSz) { result = (int)recv(sfd, (char*)recvBuf+len, recvBufSz-len, 0); if (result > 0) len += result; @@ -1023,7 +1023,7 @@ static int process_http_response(int sfd, byte** respBuf, WOLFSSL_MSG("process_http_response recv ocsp from peer failed"); return -1; } - } while (len != recvBufSz); + } *respBuf = recvBuf; return recvBufSz; diff --git a/src/keys.c b/src/keys.c index dd3207c88e..50e8885219 100644 --- a/src/keys.c +++ b/src/keys.c @@ -2070,18 +2070,18 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, dec->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER); if (dec && dec->arc4 == NULL) return MEMORY_E; -#ifdef HAVE_CAVIUM - if (devId != NO_CAVIUM_DEVICE) { +#ifdef WOLFSSL_ASYNC_CRYPT + if (devId != INVALID_DEVID) { if (enc) { - if (wc_Arc4InitCavium(enc->arc4, devId) != 0) { - WOLFSSL_MSG("Arc4InitCavium failed in SetKeys"); - return CAVIUM_INIT_E; + if (wc_Arc4AsyncInit(enc->arc4, devId) != 0) { + WOLFSSL_MSG("Arc4AsyncInit failed in SetKeys"); + return ASYNC_INIT_E; } } if (dec) { - if (wc_Arc4InitCavium(dec->arc4, devId) != 0) { - WOLFSSL_MSG("Arc4InitCavium failed in SetKeys"); - return CAVIUM_INIT_E; + if (wc_Arc4AsyncInit(dec->arc4, devId) != 0) { + WOLFSSL_MSG("Arc4AsyncInit failed in SetKeys"); + return ASYNC_INIT_E; } } } @@ -2282,18 +2282,18 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, dec->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER); if (dec && dec->des3 == NULL) return MEMORY_E; -#ifdef HAVE_CAVIUM - if (devId != NO_CAVIUM_DEVICE) { +#ifdef WOLFSSL_ASYNC_CRYPT + if (devId != INVALID_DEVID) { if (enc) { - if (wc_Des3_InitCavium(enc->des3, devId) != 0) { - WOLFSSL_MSG("Des3_InitCavium failed in SetKeys"); - return CAVIUM_INIT_E; + if (wc_Des3AsyncInit(enc->des3, devId) != 0) { + WOLFSSL_MSG("Des3AsyncInit failed in SetKeys"); + return ASYNC_INIT_E; } } if (dec) { - if (wc_Des3_InitCavium(dec->des3, devId) != 0) { - WOLFSSL_MSG("Des3_InitCavium failed in SetKeys"); - return CAVIUM_INIT_E; + if (wc_Des3AsyncInit(dec->des3, devId) != 0) { + WOLFSSL_MSG("Des3AsyncInit failed in SetKeys"); + return ASYNC_INIT_E; } } } @@ -2346,18 +2346,18 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); if (dec && dec->aes == NULL) return MEMORY_E; -#ifdef HAVE_CAVIUM - if (devId != NO_CAVIUM_DEVICE) { +#ifdef WOLFSSL_ASYNC_CRYPT + if (devId != INVALID_DEVID) { if (enc) { - if (wc_AesInitCavium(enc->aes, devId) != 0) { - WOLFSSL_MSG("AesInitCavium failed in SetKeys"); - return CAVIUM_INIT_E; + if (wc_AesAsyncInit(enc->aes, devId) != 0) { + WOLFSSL_MSG("AesAsyncInit failed in SetKeys"); + return ASYNC_INIT_E; } } if (dec) { - if (wc_AesInitCavium(dec->aes, devId) != 0) { - WOLFSSL_MSG("AesInitCavium failed in SetKeys"); - return CAVIUM_INIT_E; + if (wc_AesAsyncInit(dec->aes, devId) != 0) { + WOLFSSL_MSG("AesAsyncInit failed in SetKeys"); + return ASYNC_INIT_E; } } } @@ -2675,14 +2675,14 @@ static int SetAuthKeys(OneTimeAuth* authentication, Keys* keys, */ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) { - int devId = NO_CAVIUM_DEVICE, ret, copy = 0; + int devId = INVALID_DEVID, ret, copy = 0; Ciphers* wc_encrypt = NULL; Ciphers* wc_decrypt = NULL; Keys* keys = &ssl->keys; (void)copy; -#ifdef HAVE_CAVIUM +#ifdef WOLFSSL_ASYNC_CRYPT devId = ssl->devId; #endif diff --git a/src/sniffer.c b/src/sniffer.c index 577d59110b..49627960b6 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -90,6 +90,7 @@ enum { EXT_TYPE_SZ = 2, /* Extension length */ MAX_INPUT_SZ = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA + MTU_EXTRA, /* Max input sz of reassembly */ + EXT_MASTER_SECRET = 0x17, /* Extended Master Secret Extension ID */ TICKET_EXT_ID = 0x23 /* Session Ticket Extension ID */ }; @@ -253,7 +254,8 @@ static const char* const msgTable[] = "Clear ACK Fault", /* 81 */ - "Bad Decrypt Size" + "Bad Decrypt Size", + "Extended Master Secret Hash Error" }; @@ -329,6 +331,9 @@ typedef struct Flags { byte srvAckFault; /* server acked unseen data from client */ byte cliSkipPartial; /* client skips partial data to catch up */ byte srvSkipPartial; /* server skips partial data to catch up */ +#ifdef HAVE_EXTENDED_MASTER + byte expectEms; /* expect extended master secret */ +#endif } Flags; @@ -341,6 +346,24 @@ typedef struct FinCaputre { } FinCaputre; +typedef struct HsHashes { +#ifndef NO_OLD_TLS +#ifndef NO_SHA + Sha hashSha; +#endif +#ifndef NO_MD5 + Md5 hashMd5; +#endif +#endif +#ifndef NO_SHA256 + Sha256 hashSha256; +#endif +#ifdef WOLFSSL_SHA384 + Sha384 hashSha384; +#endif +} HsHashes; + + /* Sniffer Session holds info for each client/server SSL/TLS session */ typedef struct SnifferSession { SnifferServer* context; /* server context */ @@ -363,6 +386,9 @@ typedef struct SnifferSession { word32 srvReassemblyMemory; /* server packet memory used */ struct SnifferSession* next; /* for hash table list */ byte* ticketID; /* mac ID of session ticket */ +#ifdef HAVE_EXTENDED_MASTER + HsHashes* hash; +#endif } SnifferSession; @@ -483,6 +509,9 @@ static void FreeSnifferSession(SnifferSession* session) FreePacketList(session->srvReassemblyList); free(session->ticketID); +#ifdef HAVE_EXTENDED_MASTER + free(session->hash); +#endif } free(session); } @@ -533,6 +562,91 @@ void ssl_FreeSniffer(void) } +#ifdef HAVE_EXTENDED_MASTER + +static int HashInit(HsHashes* hash) +{ + int ret = 0; + + XMEMSET(hash, 0, sizeof(HsHashes)); + +#ifndef NO_OLD_TLS +#ifndef NO_SHA + if (ret == 0) + ret = wc_InitSha(&hash->hashSha); +#endif +#ifndef NO_MD5 + if (ret == 0) + wc_InitMd5(&hash->hashMd5); +#endif +#endif +#ifndef NO_SHA256 + if (ret == 0) + ret = wc_InitSha256(&hash->hashSha256); +#endif +#ifdef WOLFSSL_SHA384 + if (ret == 0) + ret = wc_InitSha384(&hash->hashSha384); +#endif + + return ret; +} + + +static int HashUpdate(HsHashes* hash, const byte* input, int sz) +{ + int ret = 0; + + input -= HANDSHAKE_HEADER_SZ; + sz += HANDSHAKE_HEADER_SZ; + +#ifndef NO_OLD_TLS +#ifndef NO_SHA + if (ret == 0) + ret = wc_ShaUpdate(&hash->hashSha, input, sz); +#endif +#ifndef NO_MD5 + if (ret == 0) + wc_Md5Update(&hash->hashMd5, input, sz); +#endif +#endif +#ifndef NO_SHA256 + if (ret == 0) + ret = wc_Sha256Update(&hash->hashSha256, input, sz); +#endif +#ifdef WOLFSSL_SHA384 + if (ret == 0) + ret = wc_Sha384Update(&hash->hashSha384, input, sz); +#endif + + return ret; +} + + +static int HashCopy(HS_Hashes* d, HsHashes* s) +{ +#ifndef NO_OLD_TLS +#ifndef NO_SHA + XMEMCPY(&d->hashSha, &s->hashSha, sizeof(Sha)); +#endif +#ifndef NO_MD5 + XMEMCPY(&d->hashMd5, &s->hashMd5, sizeof(Md5)); +#endif +#endif + +#ifndef NO_SHA256 + XMEMCPY(&d->hashSha256, &s->hashSha256, sizeof(Sha256)); +#endif +#ifdef WOLFSSL_SHA384 + XMEMCPY(&d->hashSha384, &s->hashSha384, sizeof(Sha384)); +#endif + + return 0; +} + +#endif + + /* Initialize a SnifferServer */ static void InitSnifferServer(SnifferServer* sniffer) { @@ -563,6 +677,9 @@ static void InitFlags(Flags* flags) flags->srvAckFault = 0; flags->cliSkipPartial = 0; flags->srvSkipPartial = 0; +#ifdef HAVE_EXTENDED_MASTER + flags->expectEms = 0; +#endif } @@ -600,6 +717,9 @@ static void InitSession(SnifferSession* session) InitFlags(&session->flags); InitFinCapture(&session->finCaputre); +#ifdef HAVE_EXTENDED_MASTER + session->hash = 0; +#endif } @@ -1483,13 +1603,17 @@ static int ProcessSessionTicket(const byte* input, int* sslBytes, /* Process Server Hello */ -static int ProcessServerHello(const byte* input, int* sslBytes, +static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, SnifferSession* session, char* error) { ProtocolVersion pv; byte b; int toRead = VERSION_SZ + RAN_LEN + ENUM_LEN; int doResume = 0; + int initialBytes = *sslBytes; + + (void)msgSz; + (void)initialBytes; /* make sure we didn't miss ClientHello */ if (session->flags.clientHello == 0) { @@ -1548,6 +1672,62 @@ static int ProcessServerHello(const byte* input, int* sslBytes, return -1; } +#ifdef HAVE_EXTENDED_MASTER + /* extensions */ + if ((initialBytes - *sslBytes) < msgSz) { + word16 len; + + /* skip extensions until extended master secret */ + /* make sure can read len */ + if (SUITE_LEN > *sslBytes) { + SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); + return -1; + } + len = (word16)((input[0] << 8) | input[1]); + input += SUITE_LEN; + *sslBytes -= SUITE_LEN; + /* make sure can read through all extensions */ + if (len > *sslBytes) { + SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE); + return -1; + } + + while (len >= EXT_TYPE_SZ + LENGTH_SZ) { + byte extType[EXT_TYPE_SZ]; + word16 extLen; + + extType[0] = input[0]; + extType[1] = input[1]; + input += EXT_TYPE_SZ; + *sslBytes -= EXT_TYPE_SZ; + + extLen = (word16)((input[0] << 8) | input[1]); + input += LENGTH_SZ; + *sslBytes -= LENGTH_SZ; + + /* make sure can read through individual extension */ + if (extLen > *sslBytes) { + SetError(SERVER_HELLO_INPUT_STR, error, session, + FATAL_ERROR_STATE); + return -1; + } + + if (extType[0] == 0x00 && extType[1] == EXT_MASTER_SECRET) { + session->flags.expectEms = 1; + } + + input += extLen; + *sslBytes -= extLen; + len -= extLen + EXT_TYPE_SZ + LENGTH_SZ; + } + } + + if (!session->flags.expectEms) { + free(session->hash); + session->hash = NULL; + } +#endif + if (session->sslServer->options.haveSessionId && XMEMCMP(session->sslServer->arrays->sessionID, session->sslClient->arrays->sessionID, ID_LEN) == 0) @@ -1758,7 +1938,7 @@ static int ProcessClientHello(const byte* input, int* sslBytes, return -1; } - while (len > EXT_TYPE_SZ + LENGTH_SZ) { + while (len >= EXT_TYPE_SZ + LENGTH_SZ) { byte extType[EXT_TYPE_SZ]; word16 extLen; @@ -1883,6 +2063,16 @@ static int DoHandShake(const byte* input, int* sslBytes, return -1; } +#ifdef HAVE_EXTENDED_MASTER + if (session->hash) { + if (HashUpdate(session->hash, input, size) != 0) { + SetError(EXTENDED_MASTER_HASH_STR, error, + session, FATAL_ERROR_STATE); + return -1; + } + } +#endif + switch (type) { case hello_verify_request: Trace(GOT_HELLO_VERIFY_STR); @@ -1896,7 +2086,7 @@ static int DoHandShake(const byte* input, int* sslBytes, break; case server_hello: Trace(GOT_SERVER_HELLO_STR); - ret = ProcessServerHello(input, sslBytes, session, error); + ret = ProcessServerHello(size, input, sslBytes, session, error); break; case certificate_request: Trace(GOT_CERT_REQ_STR); @@ -1923,7 +2113,32 @@ static int DoHandShake(const byte* input, int* sslBytes, break; case client_key_exchange: Trace(GOT_CLIENT_KEY_EX_STR); - ret = ProcessClientKeyExchange(input, sslBytes, session, error); +#ifdef HAVE_EXTENDED_MASTER + if (session->flags.expectEms && session->hash != NULL) { + if (HashCopy(session->sslServer->hsHashes, + session->hash) == 0 && + HashCopy(session->sslClient->hsHashes, + session->hash) == 0) { + + session->sslServer->options.haveEMS = 1; + session->sslClient->options.haveEMS = 1; + } + else { + SetError(EXTENDED_MASTER_HASH_STR, error, + session, FATAL_ERROR_STATE); + ret = -1; + } + XMEMSET(session->hash, 0, sizeof(HsHashes)); + free(session->hash); + session->hash = NULL; + } + else { + session->sslServer->options.haveEMS = 0; + session->sslClient->options.haveEMS = 0; + } +#endif + if (ret == 0) + ret = ProcessClientKeyExchange(input, sslBytes, session, error); break; case certificate_verify: Trace(GOT_CERT_VER_STR); @@ -2135,6 +2350,22 @@ static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo, return 0; } InitSession(session); +#ifdef HAVE_EXTENDED_MASTER + { + HsHashes* newHash = (HsHashes*)malloc(sizeof(HsHashes)); + if (newHash == NULL) { + SetError(MEMORY_STR, error, NULL, 0); + free(session); + return 0; + } + if (HashInit(newHash) != 0) { + SetError(EXTENDED_MASTER_HASH_STR, error, NULL, 0); + free(session); + return 0; + } + session->hash = newHash; + } +#endif session->server = ipInfo->dst; session->client = ipInfo->src; session->srvPort = (word16)tcpInfo->dstPort; diff --git a/src/ssl.c b/src/ssl.c index 11c313c455..f04ec12874 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -547,6 +547,61 @@ int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz) return SSL_NOT_IMPLEMENTED; #endif } + + +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) + +int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx) +{ + WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()"); + + if (ctx == NULL) + return BAD_FUNC_ARG; + + ctx->dtlsSctp = 1; + return SSL_SUCCESS; +} + + +int wolfSSL_dtls_set_sctp(WOLFSSL* ssl) +{ + WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()"); + + if (ssl == NULL) + return BAD_FUNC_ARG; + + ssl->options.dtlsSctp = 1; + return SSL_SUCCESS; +} + + +int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu) +{ + if (ctx == NULL || newMtu > MAX_RECORD_SIZE) + return BAD_FUNC_ARG; + + ctx->dtlsMtuSz = newMtu; + return SSL_SUCCESS; +} + + +int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + if (newMtu > MAX_RECORD_SIZE) { + ssl->error = BAD_FUNC_ARG; + return SSL_FAILURE; + } + + ssl->dtlsMtuSz = newMtu; + return SSL_SUCCESS; +} + + +#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ + #endif /* WOLFSSL_LEANPSK */ @@ -638,32 +693,10 @@ int wolfSSL_GetObjectSize(void) return sizeof(WOLFSSL); } #endif + + #ifdef WOLFSSL_STATIC_MEMORY - -int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap) -{ - word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; - word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; - - if (heap == NULL) { - return BAD_FUNC_ARG; - } - - XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP)); - - XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz)); - XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist)); - - if (InitMutex(&(heap->memory_mutex)) != 0) { - WOLFSSL_MSG("Error creating heap memory mutex"); - return BAD_MUTEX_E; - } - - return SSL_SUCCESS; -} - - int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method, unsigned char* buf, unsigned int sz, int flag, int max) @@ -680,34 +713,23 @@ int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method return BAD_FUNC_ARG; } - if (*ctx == NULL) { + if (*ctx == NULL || (*ctx)->heap == NULL) { if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) { return BUFFER_E; /* not enough memory for structures */ } heap = (WOLFSSL_HEAP*)buf; idx += sizeof(WOLFSSL_HEAP); - if (wolfSSL_init_memory_heap(heap) != SSL_SUCCESS) { + if (wolfSSL_init_memory_heap(heap) != 0) { return SSL_FAILURE; } hint = (WOLFSSL_HEAP_HINT*)(buf + idx); idx += sizeof(WOLFSSL_HEAP_HINT); XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT)); hint->memory = heap; - } - else if ((*ctx)->heap == NULL) { - if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) { - return BUFFER_E; /* not enough memory for structures */ + + if (*ctx && (*ctx)->heap == NULL) { + (*ctx)->heap = (void*)hint; } - heap = (WOLFSSL_HEAP*)buf; - idx += sizeof(WOLFSSL_HEAP); - if (wolfSSL_init_memory_heap(heap) != SSL_SUCCESS) { - return SSL_FAILURE; - } - hint = (WOLFSSL_HEAP_HINT*)(buf + idx); - idx += sizeof(WOLFSSL_HEAP_HINT); - XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT)); - hint->memory = heap; - (*ctx)->heap = (void*)hint; } else { #ifdef WOLFSSL_HEAP_TEST @@ -767,7 +789,7 @@ int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats) } } - return (ssl->heap)? 1 : 0; + return (ssl->heap) ? 1 : 0; } @@ -786,7 +808,7 @@ int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats) } } - return (ctx->heap)? 1 : 0; + return (ctx->heap) ? 1 : 0; } #endif /* WOLFSSL_STATIC_MEMORY */ @@ -1053,17 +1075,22 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek) #ifdef HAVE_ERRNO_H errno = 0; #endif + #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) + if (ssl->options.dtls) { ssl->dtls_expected_rx = max(sz + 100, MAX_MTU); +#ifdef WOLFSSL_SCTP + if (ssl->options.dtlsSctp) + ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz); +#endif + } #endif + sz = min(sz, OUTPUT_RECORD_SIZE); #ifdef HAVE_MAX_FRAGMENT - ret = ReceiveData(ssl, (byte*)data, - min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)),peek); -#else - ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek); + sz = min(sz, ssl->max_fragment); #endif + ret = ReceiveData(ssl, (byte*)data, sz, peek); WOLFSSL_LEAVE("wolfSSL_read_internal()", ret); @@ -1090,10 +1117,10 @@ int wolfSSL_read(WOLFSSL* ssl, void* data, int sz) } -#ifdef HAVE_CAVIUM +#ifdef WOLFSSL_ASYNC_CRYPT -/* let's use cavium, SSL_SUCCESS on ok */ -int wolfSSL_UseCavium(WOLFSSL* ssl, int devId) +/* let's use async hardware, SSL_SUCCESS on ok */ +int wolfSSL_UseAsync(WOLFSSL* ssl, int devId) { if (ssl == NULL) return BAD_FUNC_ARG; @@ -1104,8 +1131,8 @@ int wolfSSL_UseCavium(WOLFSSL* ssl, int devId) } -/* let's use cavium, SSL_SUCCESS on ok */ -int wolfSSL_CTX_UseCavium(WOLFSSL_CTX* ctx, int devId) +/* let's use async hardware, SSL_SUCCESS on ok */ +int wolfSSL_CTX_UseAsync(WOLFSSL_CTX* ctx, int devId) { if (ctx == NULL) return BAD_FUNC_ARG; @@ -1115,8 +1142,7 @@ int wolfSSL_CTX_UseCavium(WOLFSSL_CTX* ctx, int devId) return SSL_SUCCESS; } - -#endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ #ifdef HAVE_SNI @@ -1723,6 +1749,35 @@ WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl, } #endif + +#ifdef HAVE_EXTENDED_MASTER +#ifndef NO_WOLFSSL_CLIENT + +int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx) +{ + if (ctx == NULL) + return BAD_FUNC_ARG; + + ctx->haveEMS = 0; + + return SSL_SUCCESS; +} + + +int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + ssl->options.haveEMS = 0; + + return SSL_SUCCESS; +} + +#endif +#endif + + #ifndef WOLFSSL_LEANPSK int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags) @@ -4544,7 +4599,7 @@ int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz) InitDecodedCert(cert, der, sz, NULL); - if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) { + if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) { WOLFSSL_MSG("ParseCert failed"); } else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) { @@ -5020,7 +5075,7 @@ int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz) InitDecodedCert(cert, der, sz, NULL); - if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) { + if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) { WOLFSSL_MSG("ParseCert failed"); } else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) { @@ -6787,6 +6842,21 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } #endif + /* If SCTP is not enabled returns the state of the dtls option. + * If SCTP is enabled returns dtls && !sctp. */ + static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) + { + int result = ssl->options.dtls; + + if (result) { + #ifdef WOLFSSL_SCTP + result = !ssl->options.dtlsSctp; + #endif + } + + return result; + } + /* please see note at top of README if you get an error from connect */ int wolfSSL_connect(WOLFSSL* ssl) { @@ -6856,7 +6926,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, /* In DTLS, when resuming, we can go straight to FINISHED, * or do a cookie exchange and then skip to FINISHED, assume * we need the cookie exchange first. */ - if (ssl->options.dtls) + if (IsDtlsNotSctpMode(ssl)) neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE; #endif /* get response */ @@ -6868,7 +6938,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, /* if resumption failed, reset needed state */ else if (neededState == SERVER_FINISHED_COMPLETE) if (!ssl->options.resuming) { - if (!ssl->options.dtls) + if (!IsDtlsNotSctpMode(ssl)) neededState = SERVER_HELLODONE_COMPLETE; else neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE; @@ -6883,7 +6953,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, return SSL_SUCCESS; #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { /* re-init hashes, exclude first hello and verify request */ #ifndef NO_OLD_TLS wc_InitMd5(&ssl->hsHashes->hashMd5); @@ -6928,7 +6998,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, case HELLO_AGAIN_REPLY : #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE; @@ -7806,6 +7876,7 @@ int AddSession(WOLFSSL* ssl) XMEMCPY(SessionCache[row].Sessions[idx].masterSecret, ssl->arrays->masterSecret, SECRET_LEN); + SessionCache[row].Sessions[idx].haveEMS = ssl->options.haveEMS; XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays->sessionID, ID_LEN); SessionCache[row].Sessions[idx].sessionIDSz = ssl->arrays->sessionIDSz; @@ -19016,118 +19087,38 @@ void* wolfSSL_get_jobject(WOLFSSL* ssl) #endif /* WOLFSSL_JNI */ -#ifdef HAVE_WOLF_EVENT -static int _wolfSSL_CTX_poll(WOLFSSL_CTX* ctx, WOLFSSL* ssl, WOLF_EVENT* events, - int maxEvents, unsigned char flags, int* eventCount) + +#ifdef WOLFSSL_ASYNC_CRYPT +int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents, + WOLF_EVENT_FLAG flags, int* eventCount) { - WOLF_EVENT* event, *event_prev = NULL; - int count = 0, ret = SSL_ERROR_NONE; - - if (ctx == NULL || maxEvents <= 0) { + if (ctx == NULL) { return BAD_FUNC_ARG; } - /* Events arg can be NULL only if peek */ - if (events == NULL && !(flags & WOLF_POLL_FLAG_PEEK)) { + return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL, + events, maxEvents, flags, eventCount); +} + +int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags) +{ + int ret, eventCount = 0; + WOLF_EVENT* events[1]; + + if (ssl == NULL) { return BAD_FUNC_ARG; } -#ifndef SINGLE_THREADED - /* In single threaded mode "event_queue.lock" doesn't exist */ - if (LockMutex(&ctx->event_queue.lock) != 0) { - return BAD_MUTEX_E; - } -#endif - - /* Itterate event queue */ - for (event = ctx->event_queue.head; event != NULL; event = event->next) - { - byte removeEvent = 0; - - /* Optionally filter by ssl object pointer */ - if (ssl == NULL || (ssl == event->ssl)) { - if (flags & WOLF_POLL_FLAG_PEEK) { - if (events) { - /* Copy event data to provided buffer */ - XMEMCPY(&events[count], event, sizeof(WOLF_EVENT)); - } - count++; - } - else { - /* Check hardware */ - if (flags & WOLF_POLL_FLAG_CHECK_HW) { - #ifdef WOLFSSL_ASYNC_CRYPT - if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST && - event->type <= WOLF_EVENT_TYPE_ASYNC_LAST) - { - ret = wolfSSL_async_poll(event, flags); - } - #endif /* WOLFSSL_ASYNC_CRYPT */ - } - - /* If event is done then return in 'events' argument */ - if (event->done) { - /* Copy event data to provided buffer */ - XMEMCPY(&events[count], event, sizeof(WOLF_EVENT)); - count++; - removeEvent = 1; - } - } - } - - if (removeEvent) { - /* Remove from queue list */ - if (event_prev == NULL) { - ctx->event_queue.head = event->next; - if (ctx->event_queue.head == NULL) { - ctx->event_queue.tail = NULL; - } - } - else { - event_prev->next = event->next; - } - } - else { - /* Leave in queue, save prev pointer */ - event_prev = event; - } - - /* Check to make sure our event list isn't full */ - if (events && count >= maxEvents) { - break; /* Exit for */ - } - - /* Check for error */ - if (ret < 0) { - break; /* Exit for */ - } - } - -#ifndef SINGLE_THREADED - UnLockMutex(&ctx->event_queue.lock); -#endif - - /* Return number of properly populated events */ - if (eventCount) { - *eventCount = count; + /* not filtering on "ssl", since its the asyncDev */ + ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, NULL, + events, sizeof(events)/sizeof(events), flags, &eventCount); + if (ret == 0 && eventCount > 0) { + ret = 1; /* Success */ } return ret; } +#endif /* WOLFSSL_ASYNC_CRYPT */ -int wolfSSL_CTX_poll(WOLFSSL_CTX* ctx, WOLF_EVENT* events, - int maxEvents, unsigned char flags, int* eventCount) -{ - return _wolfSSL_CTX_poll(ctx, NULL, events, maxEvents, flags, eventCount); -} - -int wolfSSL_poll(WOLFSSL* ssl, WOLF_EVENT* events, - int maxEvents, unsigned char flags, int* eventCount) -{ - return _wolfSSL_CTX_poll(ssl->ctx, ssl, events, maxEvents, flags, - eventCount); -} - -#endif /* HAVE_WOLF_EVENT */ #endif /* WOLFCRYPT_ONLY */ diff --git a/src/tls.c b/src/tls.c index e13ae88a1e..648147c2ac 100644 --- a/src/tls.c +++ b/src/tls.c @@ -341,21 +341,23 @@ static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, #endif -int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) +int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen) { - const byte* side; - byte handshake_hash[HSHASH_SZ]; - word32 hashSz = FINISHED_SZ; + word32 hashSz = FINISHED_SZ; + + if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ) + return BAD_FUNC_ARG; #ifndef NO_OLD_TLS - wc_Md5GetHash(&ssl->hsHashes->hashMd5, handshake_hash); - wc_ShaGetHash(&ssl->hsHashes->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); + wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash); + wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[MD5_DIGEST_SIZE]); #endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 - if (ssl->specs.mac_algorithm <= sha256_mac || ssl->specs.mac_algorithm == blake2b_mac) { - int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,handshake_hash); + if (ssl->specs.mac_algorithm <= sha256_mac || + ssl->specs.mac_algorithm == blake2b_mac) { + int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash); if (ret != 0) return ret; @@ -365,7 +367,7 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) #endif #ifdef WOLFSSL_SHA384 if (ssl->specs.mac_algorithm == sha384_mac) { - int ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,handshake_hash); + int ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash); if (ret != 0) return ret; @@ -375,6 +377,23 @@ int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) #endif } + *hashLen = hashSz; + + return 0; +} + + +int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) +{ + int ret; + const byte* side; + byte handshake_hash[HSHASH_SZ]; + word32 hashSz = HSHASH_SZ; + + ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz); + if (ret < 0) + return ret; + if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) side = tls_client; else @@ -420,6 +439,10 @@ ProtocolVersion MakeTLSv1_2(void) } +#ifdef HAVE_EXTENDED_MASTER +static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] = + "extended master secret"; +#endif static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret"; static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion"; @@ -490,10 +513,41 @@ int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen, } +#ifdef HAVE_EXTENDED_MASTER + +/* External facing wrapper so user can call as well, 0 on success */ +int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen, + const byte* pms, word32 pmsLen, + const byte* sHash, word32 sHashLen, + int tls1_2, int hash_type) +{ + return PRF(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ, + sHash, sHashLen, tls1_2, hash_type); +} + +#endif /* HAVE_EXTENDED_MASTER */ + + int MakeTlsMasterSecret(WOLFSSL* ssl) { - int ret; + int ret; +#ifdef HAVE_EXTENDED_MASTER + byte handshake_hash[HSHASH_SZ]; + word32 hashSz = HSHASH_SZ; + if (ssl->options.haveEMS) { + + ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz); + if (ret < 0) + return ret; + + ret = wolfSSL_MakeTlsExtendedMasterSecret( + ssl->arrays->masterSecret, SECRET_LEN, + ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, + handshake_hash, hashSz, + IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); + } else +#endif ret = wolfSSL_MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN, ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, ssl->arrays->clientRandom, ssl->arrays->serverRandom, @@ -4434,7 +4488,13 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl) length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1); if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) - length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN; + length += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ + + ssl->suites->hashSigAlgoSz; + +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) + length += HELLO_EXT_SZ; +#endif } if (length) @@ -4465,15 +4525,15 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output) offset += TLSX_Write(ssl->ctx->extensions, output + offset, semaphore, 1); - if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) - { + if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) { int i; /* extension type */ c16toa(HELLO_EXT_SIG_ALGO, output + offset); offset += HELLO_EXT_TYPE_SZ; /* extension data length */ - c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset); + c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, + output + offset); offset += OPAQUE16_LEN; /* sig algos length */ @@ -4485,6 +4545,15 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output) output[offset] = ssl->suites->hashSigAlgo[i]; } +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_EXTMS, output + offset); + offset += HELLO_EXT_TYPE_SZ; + c16toa(0, output + offset); + offset += HELLO_EXT_SZ_SZ; + } +#endif + if (offset > OPAQUE16_LEN) c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ } @@ -4511,13 +4580,18 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl) } #endif +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) + length += HELLO_EXT_SZ; +#endif + if (TLSX_SupportExtensions(ssl)) length += TLSX_GetSize(ssl->extensions, semaphore, 0); /* All the response data is set at the ssl object only, so no ctx here. */ if (length) - length += OPAQUE16_LEN; /* for total length storage */ + length += OPAQUE16_LEN; /* for total length storage. */ return length; } @@ -4534,6 +4608,15 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output) offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0); +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_EXTMS, output + offset); + offset += HELLO_EXT_TYPE_SZ; + c16toa(0, output + offset); + offset += HELLO_EXT_SZ_SZ; + } +#endif + if (offset > OPAQUE16_LEN) c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ } @@ -4549,6 +4632,9 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, { int ret = 0; word16 offset = 0; +#ifdef HAVE_EXTENDED_MASTER + byte pendingEMS = 0; +#endif if (!ssl || !input || (isRequest && !suites)) return BAD_FUNC_ARG; @@ -4606,6 +4692,18 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, ret = CSR2_PARSE(ssl, input + offset, size, isRequest); break; +#ifdef HAVE_EXTENDED_MASTER + case HELLO_EXT_EXTMS: + WOLFSSL_MSG("Extended Master Secret extension received"); + +#ifndef NO_WOLFSSL_SERVER + if (isRequest) + ssl->options.haveEMS = 1; +#endif + pendingEMS = 1; + break; +#endif + case TLSX_RENEGOTIATION_INFO: WOLFSSL_MSG("Secure Renegotiation extension received"); @@ -4655,6 +4753,11 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, offset += size; } +#ifdef HAVE_EXTENDED_MASTER + if (!isRequest && ssl->options.haveEMS && !pendingEMS) + ssl->options.haveEMS = 0; +#endif + if (ret == 0) ret = SNI_VERIFY_PARSE(ssl, isRequest); diff --git a/tests/api.c b/tests/api.c index 689100e68d..b5d348ca07 100644 --- a/tests/api.c +++ b/tests/api.c @@ -29,6 +29,7 @@ #endif #include + #if defined(WOLFSSL_STATIC_MEMORY) #include #endif /* WOLFSSL_STATIC_MEMORY */ @@ -101,6 +102,22 @@ static int test_wolfSSL_Cleanup(void) return result; } + +/* Initialize the wolfCrypt state. + * POST: 0 success. + */ +static int test_wolfCrypt_Init(void) +{ + int result; + + printf(testingFmt, "wolfCrypt_Init()"); + result = wolfCrypt_Init(); + printf(resultFmt, result == 0 ? passed : failed); + + return result; + +} /* END test_wolfCrypt_Init */ + /*----------------------------------------------------------------------------* | Method Allocators *----------------------------------------------------------------------------*/ @@ -194,6 +211,32 @@ static void test_wolfSSL_CTX_use_certificate_file(void) #endif } +/* Test function for wolfSSL_CTX_use_certificate_buffer. Load cert into + * context using buffer. + * PRE: NO_CERTS not defined; USE_CERT_BUFFERS_2048 defined; compile with + * --enable-testcert flag. + */ +static int test_wolfSSL_CTX_use_certificate_buffer(void) +{ + #if !defined(NO_CERTS) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA) + WOLFSSL_CTX* ctx; + int ret; + + printf(testingFmt, "wolfSSL_CTX_use_certificate_buffer()"); + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); + + ret = wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048, + sizeof_server_cert_der_2048, SSL_FILETYPE_ASN1); + + printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + wolfSSL_CTX_free(ctx); + + return ret; + #else + return SSL_SUCCESS; + #endif + +} /*END test_wolfSSL_CTX_use_certificate_buffer*/ static void test_wolfSSL_CTX_use_PrivateKey_file(void) { @@ -486,6 +529,48 @@ static void test_wolfSSL_SetTmpDH_buffer(void) #endif } + +/* Test function for wolfSSL_SetMinVersion. Sets the minimum downgrade version + * allowed. + * POST: return 1 on success. + */ +static int test_wolfSSL_SetMinVersion(void) +{ + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + int failFlag, itr; + + #ifndef NO_OLD_TLS + const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1, + WOLFSSL_TLSV1_2}; + #else + const int versions[] = { WOLFSSL_TLSV1_2 }; + #endif + failFlag = SSL_SUCCESS; + + AssertTrue(wolfSSL_Init()); + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + ssl = wolfSSL_new(ctx); + + printf(testingFmt, "wolfSSL_SetMinVersion()"); + + for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++){ + if(wolfSSL_SetMinVersion(ssl, *(versions + itr)) != SSL_SUCCESS){ + failFlag = SSL_FAILURE; + } + } + + printf(resultFmt, failFlag == SSL_SUCCESS ? passed : failed); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + AssertTrue(wolfSSL_Cleanup()); + + return failFlag; + +} /* END test_wolfSSL_SetMinVersion */ + + /*----------------------------------------------------------------------------* | IO *----------------------------------------------------------------------------*/ @@ -537,6 +622,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) char msg[] = "I hear you fa shizzle!"; char input[1024]; int idx; + int ret, err = 0; #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); @@ -586,7 +672,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) } ssl = wolfSSL_new(ctx); - tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 1); + tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1); CloseSocket(sockfd); if (wolfSSL_set_fd(ssl, clientfd) != SSL_SUCCESS) { @@ -602,9 +688,22 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) #endif #endif - if (wolfSSL_accept(ssl) != SSL_SUCCESS) - { - int err = wolfSSL_get_error(ssl, 0); + do { +#ifdef WOLFSSL_ASYNC_CRYPT + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) { break; } else if (ret == 0) { continue; } + } +#endif + + err = 0; /* Reset error */ + ret = wolfSSL_accept(ssl); + if (ret != SSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + } + } while (ret != SSL_SUCCESS && err == WC_PENDING_E); + + if (ret != SSL_SUCCESS) { char buffer[WOLFSSL_MAX_ERROR_SZ]; printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); /*err_sys("SSL_accept failed");*/ @@ -666,6 +765,7 @@ static void test_client_nofail(void* args) char reply[1024]; int input; int msgSz = (int)XSTRLEN(msg); + int ret, err = 0; #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); @@ -700,18 +800,32 @@ static void test_client_nofail(void* args) } ssl = wolfSSL_new(ctx); - tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl); + tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port, + 0, 0, ssl); if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) { /*err_sys("SSL_set_fd failed");*/ goto done2; } - if (wolfSSL_connect(ssl) != SSL_SUCCESS) - { - int err = wolfSSL_get_error(ssl, 0); + do { +#ifdef WOLFSSL_ASYNC_CRYPT + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) { break; } else if (ret == 0) { continue; } + } +#endif + + err = 0; /* Reset error */ + ret = wolfSSL_connect(ssl); + if (ret != SSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + } + } while (ret != SSL_SUCCESS && err == WC_PENDING_E); + + if (ret != SSL_SUCCESS) { char buffer[WOLFSSL_MAX_ERROR_SZ]; - printf("err = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); - /*printf("SSL_connect failed");*/ + printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); + /*err_sys("SSL_connect failed");*/ goto done2; } @@ -759,6 +873,7 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) int len = (int) XSTRLEN(msg); char input[1024]; int idx; + int ret, err = 0; #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); @@ -805,14 +920,14 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) socklen_t cliLen; cliLen = sizeof(cliAddr); - tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0); + tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0, 0); idx = (int)recvfrom(sfd, input, sizeof(input), MSG_PEEK, (struct sockaddr*)&cliAddr, &cliLen); AssertIntGT(idx, 0); wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen); } else { - tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 1); + tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1); CloseSocket(sfd); } @@ -829,13 +944,27 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) if (callbacks->ssl_ready) callbacks->ssl_ready(ssl); - /* AssertIntEQ(SSL_SUCCESS, wolfSSL_accept(ssl)); */ - if (wolfSSL_accept(ssl) != SSL_SUCCESS) { - int err = wolfSSL_get_error(ssl, 0); + do { +#ifdef WOLFSSL_ASYNC_CRYPT + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) { break; } else if (ret == 0) { continue; } + } +#endif + + err = 0; /* Reset error */ + ret = wolfSSL_accept(ssl); + if (ret != SSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + } + } while (ret != SSL_SUCCESS && err == WC_PENDING_E); + + if (ret != SSL_SUCCESS) { char buffer[WOLFSSL_MAX_ERROR_SZ]; printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); - - } else { + /*err_sys("SSL_accept failed");*/ + } + else { if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) { input[idx] = 0; printf("Client message: %s\n", input); @@ -898,6 +1027,7 @@ static void run_wolfssl_client(void* args) int len = (int) XSTRLEN(msg); char input[1024]; int idx; + int ret, err = 0; #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); @@ -922,22 +1052,39 @@ static void run_wolfssl_client(void* args) ssl = wolfSSL_new(ctx); if (wolfSSL_dtls(ssl)) { - tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 1, ssl); + tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, + 1, 0, ssl); } else { - tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl); + tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, + 0, 0, ssl); } AssertIntEQ(SSL_SUCCESS, wolfSSL_set_fd(ssl, sfd)); if (callbacks->ssl_ready) callbacks->ssl_ready(ssl); - if (wolfSSL_connect(ssl) != SSL_SUCCESS) { - int err = wolfSSL_get_error(ssl, 0); + do { +#ifdef WOLFSSL_ASYNC_CRYPT + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) { break; } else if (ret == 0) { continue; } + } +#endif + + err = 0; /* Reset error */ + ret = wolfSSL_connect(ssl); + if (ret != SSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + } + } while (ret != SSL_SUCCESS && err == WC_PENDING_E); + + if (ret != SSL_SUCCESS) { char buffer[WOLFSSL_MAX_ERROR_SZ]; printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); - - } else { + /*err_sys("SSL_connect failed");*/ + } + else { AssertIntEQ(len, wolfSSL_write(ssl, msg, len)); if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) { @@ -1780,6 +1927,28 @@ static void test_wolfSSL_UseALPN(void) #endif } +static void test_wolfSSL_DisableExtendedMasterSecret(void) +{ +#ifdef HAVE_EXTENDED_MASTER + WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); + WOLFSSL *ssl = wolfSSL_new(ctx); + + AssertNotNull(ctx); + AssertNotNull(ssl); + + /* error cases */ + AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(NULL)); + AssertIntNE(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(NULL)); + + /* success cases */ + AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(ctx)); + AssertIntEQ(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(ssl)); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); +#endif +} + /*----------------------------------------------------------------------------* | X509 Tests *----------------------------------------------------------------------------*/ @@ -1827,6 +1996,126 @@ static void test_wolfSSL_X509_NAME_get_entry(void) #endif /* !NO_CERTS */ } +/* Testing function wolfSSL_CTX_SetMinVersion; sets the minimum downgrade + * version allowed. + * POST: 1 on success. + */ +static int test_wolfSSL_CTX_SetMinVersion(void) +{ + WOLFSSL_CTX* ctx; + int failFlag, itr; + + #ifndef NO_OLD_TLS + const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1, + WOLFSSL_TLSV1_2 }; + #else + const int versions[] = { WOLFSSL_TLSV1_2 }; + #endif + + failFlag = SSL_SUCCESS; + + AssertTrue(wolfSSL_Init()); + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + + printf(testingFmt, "wolfSSL_CTX_SetMinVersion()"); + + for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++){ + if(wolfSSL_CTX_SetMinVersion(ctx, *(versions + itr)) != SSL_SUCCESS){ + failFlag = SSL_FAILURE; + } + } + + printf(resultFmt, failFlag == SSL_SUCCESS ? passed : failed); + + wolfSSL_CTX_free(ctx); + AssertTrue(wolfSSL_Cleanup()); + + return failFlag; + +} /* END test_wolfSSL_CTX_SetMinVersion */ + + +/*----------------------------------------------------------------------------* + | OCSP Stapling + *----------------------------------------------------------------------------*/ + + +/* Testing wolfSSL_UseOCSPStapling function. OCSP stapling eliminates the need + * need to contact the CA, lowering the cost of cert revocation checking. + * PRE: HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST + * POST: 1 returned for success. + */ +static int test_wolfSSL_UseOCSPStapling(void) +{ + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && defined(HAVE_OCSP) + int ret; + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + + wolfSSL_Init(); + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + ssl = wolfSSL_new(ctx); + printf(testingFmt, "wolfSSL_UseOCSPStapling()"); + + ret = wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR2_OCSP, + WOLFSSL_CSR2_OCSP_USE_NONCE); + + printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + + if(ret != SSL_SUCCESS){ + wolfSSL_Cleanup(); + return SSL_FAILURE; + } + + return wolfSSL_Cleanup(); + #else + return SSL_SUCCESS; + #endif + +} /*END test_wolfSSL_UseOCSPStapling */ + + +/* Testing OCSP stapling version 2, wolfSSL_UseOCSPStaplingV2 funciton. OCSP + * stapling eliminates the need ot contact the CA and lowers cert revocation + * check. + * PRE: HAVE_CERTIFICATE_STATUS_REQUEST_V2 and HAVE_OCSP defined. + */ +static int test_wolfSSL_UseOCSPStaplingV2(void) +{ + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && defined(HAVE_OCSP) + int ret; + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + + wolfSSL_Init(); + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + ssl = wolfSSL_new(ctx); + printf(testingFmt, "wolfSSL_UseOCSPStaplingV2()"); + + ret = wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP, + WOLFSSL_CSR2_OCSP_USE_NONCE ); + + printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + + if(ret != SSL_SUCCESS){ + wolfSSL_Cleanup(); + return SSL_FAILURE; + } + + return wolfSSL_Cleanup(); + #else + return SSL_SUCCESS; + #endif + +} /*END test_wolfSSL_UseOCSPStaplingV2*/ + /*----------------------------------------------------------------------------* | Main @@ -1835,11 +2124,13 @@ static void test_wolfSSL_X509_NAME_get_entry(void) void ApiTest(void) { printf(" Begin API Tests\n"); - test_wolfSSL_Init(); - + AssertIntEQ(test_wolfSSL_Init(), SSL_SUCCESS); + /* wolfcrypt initialization tests */ + AssertFalse(test_wolfCrypt_Init()); test_wolfSSL_Method_Allocators(); test_wolfSSL_CTX_new(wolfSSLv23_server_method()); test_wolfSSL_CTX_use_certificate_file(); + AssertIntEQ(test_wolfSSL_CTX_use_certificate_buffer(), SSL_SUCCESS); test_wolfSSL_CTX_use_PrivateKey_file(); test_wolfSSL_CTX_load_verify_locations(); test_wolfSSL_CTX_trust_peer_cert(); @@ -1851,6 +2142,8 @@ void ApiTest(void) test_wolfSSL_SetTmpDH_buffer(); test_wolfSSL_read_write(); test_wolfSSL_dtls_export(); + AssertIntEQ(test_wolfSSL_SetMinVersion(), SSL_SUCCESS); + AssertIntEQ(test_wolfSSL_CTX_SetMinVersion(), SSL_SUCCESS); /* TLS extensions tests */ test_wolfSSL_UseSNI(); @@ -1858,10 +2151,16 @@ void ApiTest(void) test_wolfSSL_UseTruncatedHMAC(); test_wolfSSL_UseSupportedCurve(); test_wolfSSL_UseALPN(); + test_wolfSSL_DisableExtendedMasterSecret(); /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); - test_wolfSSL_Cleanup(); + /*OCSP Stapling. */ + AssertIntEQ(test_wolfSSL_UseOCSPStapling(), SSL_SUCCESS); + AssertIntEQ(test_wolfSSL_UseOCSPStaplingV2(), SSL_SUCCESS); + + AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS); printf(" End API Tests\n"); + } diff --git a/tests/suites.c b/tests/suites.c index c3864bd89a..f23c116ccc 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -48,6 +48,7 @@ static WOLFSSL_CTX* cipherSuiteCtx = NULL; static char nonblockFlag[] = "-N"; static char noVerifyFlag[] = "-d"; +static char disableEMSFlag[] = "-n"; static char flagSep[] = " "; #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) static char portFlag[] = "-p"; @@ -153,7 +154,8 @@ static int IsValidCipherSuite(const char* line, char* suite) static int execute_test_case(int svr_argc, char** svr_argv, int cli_argc, char** cli_argv, - int addNoVerify, int addNonBlocking) + int addNoVerify, int addNonBlocking, + int addDisableEMS) { #ifdef WOLFSSL_TIRTOS func_args cliArgs = {0}; @@ -270,6 +272,18 @@ static int execute_test_case(int svr_argc, char** svr_argv, cliArgs.argc = cli_argc; } } + if (addDisableEMS) { + printf("repeating test without extended master secret\n"); + added += 4; /* -n plus terminator */ + if (added >= MAX_COMMAND_SZ) + printf("client command line too long\n"); + else { + cli_argv[cli_argc++] = disableEMSFlag; + strcat(commandLine, disableEMSFlag); + strcat(commandLine, flagSep); + cliArgs.argc = cli_argc; + } + } printf("trying client command line[%d]: %s\n", tests++, commandLine); InitTcpReady(&ready); @@ -437,12 +451,26 @@ static void test_harness(void* vargs) } if (do_it) { - ret = execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs,0,0); + ret = execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 0, 0); /* don't repeat if not supported in build */ if (ret == 0) { - execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 0, 1); - execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 0); - execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 1, 0); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 0, 0); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 1, 0); +#ifdef HAVE_EXTENDED_MASTER + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 0, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 1, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 0, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 1, 1); +#endif } svrArgsSz = 1; cliArgsSz = 1; @@ -513,6 +541,16 @@ int SuiteTest(void) exit(EXIT_FAILURE); } #endif +#ifdef WOLFSSL_SCTP + /* add dtls-sctp extra suites */ + strcpy(argv0[1], "tests/test-sctp.conf"); + printf("starting dtls-sctp extra cipher suite tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + exit(EXIT_FAILURE); + } +#endif #ifndef WC_STRICT_SIG #if !defined(NO_RSA) && defined(HAVE_ECC) /* testing mixed ECC/RSA cert */ /* add extra signature test suites */ diff --git a/tests/test-sctp.conf b/tests/test-sctp.conf new file mode 100644 index 0000000000..26fe6fd7cb --- /dev/null +++ b/tests/test-sctp.conf @@ -0,0 +1,1111 @@ +# server DTLSv1 DHE-RSA-CHACHA20-POLY1305 +-G +-v 2 +-l DHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1 DHE-RSA-CHACHA20-POLY1305 +-G +-v 2 +-l DHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1 ECDHE-RSA-CHACHA20-POLY1305 +-G +-v 2 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1 ECDHE-RSA-CHACHA20-POLY1305 +-G +-v 2 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1 ECDHE-EDCSA-CHACHA20-POLY1305 +-G +-v 2 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1 ECDHE-ECDSA-CHACHA20-POLY1305 +-G +-v 2 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-G +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-G +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-G +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-G +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305 +-G +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305 +-G +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/server-ecc.pem + +# server TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-G +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 DHE-PSK-CHACHA20-POLY1305 +-G +-v 3 +-s +-l DHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-G +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# client TLSv1.2 ECDHE-PSK-CHACHA20-POLY1305 +-G +-v 3 +-s +-l ECDHE-PSK-CHACHA20-POLY1305 + +# server TLSv1.2 PSK-CHACHA20-POLY1305 +-G +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# client TLSv1.2 PSK-CHACHA20-POLY1305 +-G +-v 3 +-s +-l PSK-CHACHA20-POLY1305 + +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-G +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-G +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-G +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-G +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305-OLD +-G +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-G +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-A ./certs/server-ecc.pem + +# server DTLSv1 RC4-SHA +-G +-v 2 +-l RC4-SHA + +# client DTLSv1 RC4-SHA +-G +-v 2 +-l RC4-SHA + +# server DTLSv1.2 RC4-SHA +-G +-v 3 +-l RC4-SHA + +# client DTLSv1.2 RC4-SHA +-G +-v 3 +-l RC4-SHA + +# server DTLSv1 IDEA-CBC-SHA +-G +-v 2 +-l IDEA-CBC-SHA + +# client DTLSv1 IDEA-CBC-SHA +-G +-v 2 +-l IDEA-CBC-SHA + +# server DTLSv1 DES-CBC3-SHA +-G +-v 2 +-l DES-CBC3-SHA + +# client DTLSv1 DES-CBC3-SHA +-G +-v 2 +-l DES-CBC3-SHA + +# server DTLSv1.2 DES-CBC3-SHA +-G +-v 3 +-l DES-CBC3-SHA + +# client DTLSv1.2 DES-CBC3-SHA +-G +-v 3 +-l DES-CBC3-SHA + +# server DTLSv1 AES128-SHA +-G +-v 2 +-l AES128-SHA + +# client DTLSv1 AES128-SHA +-G +-v 2 +-l AES128-SHA + +# server DTLSv1.2 AES128-SHA +-G +-v 3 +-l AES128-SHA + +# client DTLSv1.2 AES128-SHA +-G +-v 3 +-l AES128-SHA + +# server DTLSv1 AES256-SHA +-G +-v 2 +-l AES256-SHA + +# client DTLSv1 AES256-SHA +-G +-v 2 +-l AES256-SHA + +# server DTLSv1.2 AES256-SHA +-G +-v 3 +-l AES256-SHA + +# client DTLSv1.2 AES256-SHA +-G +-v 3 +-l AES256-SHA + +# server DTLSv1 AES128-SHA256 +-G +-v 2 +-l AES128-SHA256 + +# client DTLSv1 AES128-SHA256 +-G +-v 2 +-l AES128-SHA256 + +# server DTLSv1.2 AES128-SHA256 +-G +-v 3 +-l AES128-SHA256 + +# client DTLSv1.2 AES128-SHA256 +-G +-v 3 +-l AES128-SHA256 + +# server DTLSv1 AES256-SHA256 +-G +-v 2 +-l AES256-SHA256 + +# client DTLSv1 AES256-SHA256 +-G +-v 2 +-l AES256-SHA256 + +# server DTLSv1.2 AES256-SHA256 +-G +-v 3 +-l AES256-SHA256 + +# client DTLSv1.2 AES256-SHA256 +-G +-v 3 +-l AES256-SHA256 + +# server DTLSv1 ECDHE-RSA-RC4 +-G +-v 2 +-l ECDHE-RSA-RC4-SHA + +# client DTLSv1 ECDHE-RSA-RC4 +-G +-v 2 +-l ECDHE-RSA-RC4-SHA + +# server DTLSv1.1 ECDHE-RSA-DES3 +-G +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.1 ECDHE-RSA-DES3 +-G +-v 2 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDHE-RSA-AES128 +-G +-v 2 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.1 ECDHE-RSA-AES128 +-G +-v 2 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.1 ECDHE-RSA-AES256 +-G +-v 2 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.1 ECDHE-RSA-AES256 +-G +-v 2 +-l ECDHE-RSA-AES256-SHA + +# server DTLSv1.2 ECDHE-RSA-RC4 +-G +-v 3 +-l ECDHE-RSA-RC4-SHA + +# client DTLSv1.2 ECDHE-RSA-RC4 +-G +-v 3 +-l ECDHE-RSA-RC4-SHA + +# server DTLSv1.2 ECDHE-RSA-DES3 +-G +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# client DTLSv1.2 ECDHE-RSA-DES3 +-G +-v 3 +-l ECDHE-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128 +-G +-v 3 +-l ECDHE-RSA-AES128-SHA + +# client DTLSv1.2 ECDHE-RSA-AES128 +-G +-v 3 +-l ECDHE-RSA-AES128-SHA + +# server DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-G +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-SHA256 +-G +-v 3 +-l ECDHE-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256 +-G +-v 3 +-l ECDHE-RSA-AES256-SHA + +# client DTLSv1.2 ECDHE-RSA-AES256 +-G +-v 3 +-l ECDHE-RSA-AES256-SHA + +# server TLSv1 ECDHE-ECDSA-NULL-SHA +-G +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-G +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + +# server TLSv1.1 ECDHE-ECDSA-NULL-SHA +-G +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-G +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + +# server TLSv1.2 ECDHE-ECDSA-NULL-SHA +-G +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-NULL-SHA +-G +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDHE-EDCSA-RC4 +-G +-v 2 +-l ECDHE-ECDSA-RC4-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-RC4 +-G +-v 2 +-l ECDHE-ECDSA-RC4-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDHE-ECDSA-DES3 +-G +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-DES3 +-G +-v 2 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES128 +-G +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES128 +-G +-v 2 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDHE-ECDSA-AES256 +-G +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDHE-ECDSA-AES256 +-G +-v 2 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-RC4 +-G +-v 3 +-l ECDHE-ECDSA-RC4-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-RC4 +-G +-v 3 +-l ECDHE-ECDSA-RC4-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-DES3 +-G +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-DES3 +-G +-v 3 +-l ECDHE-ECDSA-DES-CBC3-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128 +-G +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128 +-G +-v 3 +-l ECDHE-ECDSA-AES128-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-G +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-SHA256 +-G +-v 3 +-l ECDHE-ECDSA-AES128-SHA256 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256 +-G +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256 +-G +-v 3 +-l ECDHE-ECDSA-AES256-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDH-RSA-RC4 +-G +-v 2 +-l ECDH-RSA-RC4-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-RC4 +-G +-v 2 +-l ECDH-RSA-RC4-SHA + +# server DTLSv1.1 ECDH-RSA-DES3 +-G +-v 2 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-DES3 +-G +-v 2 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.1 ECDH-RSA-AES128 +-G +-v 2 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES128 +-G +-v 2 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.1 ECDH-RSA-AES256 +-G +-v 2 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-RSA-AES256 +-G +-v 2 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.2 ECDH-RSA-RC4 +-G +-v 3 +-l ECDH-RSA-RC4-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-RC4 +-G +-v 3 +-l ECDH-RSA-RC4-SHA + +# server DTLSv1.2 ECDH-RSA-DES3 +-G +-v 3 +-l ECDH-RSA-DES-CBC3-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-DES3 +-G +-v 3 +-l ECDH-RSA-DES-CBC3-SHA + +# server DTLSv1.2 ECDH-RSA-AES128 +-G +-v 3 +-l ECDH-RSA-AES128-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128 +-G +-v 3 +-l ECDH-RSA-AES128-SHA + +# server DTLSv1.2 ECDH-RSA-AES128-SHA256 +-G +-v 3 +-l ECDH-RSA-AES128-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-SHA256 +-G +-v 3 +-l ECDH-RSA-AES128-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256 +-G +-v 3 +-l ECDH-RSA-AES256-SHA +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256 +-G +-v 3 +-l ECDH-RSA-AES256-SHA + +# server DTLSv1.1 ECDH-EDCSA-RC4 +-G +-v 2 +-l ECDH-ECDSA-RC4-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-RC4 +-G +-v 2 +-l ECDH-ECDSA-RC4-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDH-ECDSA-DES3 +-G +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-DES3 +-G +-v 2 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDH-ECDSA-AES128 +-G +-v 2 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES128 +-G +-v 2 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.1 ECDH-ECDSA-AES256 +-G +-v 2 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.1 ECDH-ECDSA-AES256 +-G +-v 2 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-RC4 +-G +-v 3 +-l ECDH-ECDSA-RC4-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-RC4 +-G +-v 3 +-l ECDH-ECDSA-RC4-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDH-ECDSA-DES3 +-G +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-DES3 +-G +-v 3 +-l ECDH-ECDSA-DES-CBC3-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128 +-G +-v 3 +-l ECDH-ECDSA-AES128-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128 +-G +-v 3 +-l ECDH-ECDSA-AES128-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-G +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-SHA256 +-G +-v 3 +-l ECDH-ECDSA-AES128-SHA256 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256 +-G +-v 3 +-l ECDH-ECDSA-AES256-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256 +-G +-v 3 +-l ECDH-ECDSA-AES256-SHA +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-G +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-SHA384 +-G +-v 3 +-l ECDHE-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-G +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-SHA384 +-G +-v 3 +-l ECDHE-ECDSA-AES256-SHA384 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDH-RSA-AES256-SHA384 +-G +-v 3 +-l ECDH-RSA-AES256-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-SHA384 +-G +-v 3 +-l ECDH-RSA-AES256-SHA384 + +# server DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-G +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-SHA384 +-G +-v 3 +-l ECDH-ECDSA-AES256-SHA384 +-A ./certs/server-ecc.pem + +# server TLSv1 ECDHE-PSK-AES128-SHA256 +-s +-G +-v 1 +-l ECDHE-PSK-AES128-SHA256 + +# client TLSv1 ECDHE-PSK-AES128-SHA256 +-s +-G +-v 1 +-l ECDHE-PSK-AES128-SHA256 + +# server TLSv1.1 ECDHE-PSK-AES128-SHA256 +-s +-G +-v 2 +-l ECDHE-PSK-AES128-SHA256 + +# client TLSv1.1 ECDHE-PSK-AES128-SHA256 +-s +-G +-v 2 +-l ECDHE-PSK-AES128-SHA256 + +# server TLSv1.2 ECDHE-PSK-AES128-SHA256 +-s +-G +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# client TLSv1.2 ECDHE-PSK-AES128-SHA256 +-s +-G +-v 3 +-l ECDHE-PSK-AES128-SHA256 + +# server TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-G +-v 1 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-G +-v 1 +-l ECDHE-PSK-NULL-SHA256 + +# server TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-G +-v 2 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-G +-v 2 +-l ECDHE-PSK-NULL-SHA256 + +# server TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-G +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-G +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# server DTLSv1 PSK-AES128 +-s +-G +-v 2 +-l PSK-AES128-CBC-SHA + +# client DTLSv1 PSK-AES128 +-s +-G +-v 2 +-l PSK-AES128-CBC-SHA + +# server DTLSv1 PSK-AES256 +-s +-G +-v 2 +-l PSK-AES256-CBC-SHA + +# client DTLSv1 PSK-AES256 +-s +-G +-v 2 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128 +-s +-G +-v 3 +-l PSK-AES128-CBC-SHA + +# client DTLSv1.2 PSK-AES128 +-s +-G +-v 3 +-l PSK-AES128-CBC-SHA + +# server DTLSv1.2 PSK-AES256 +-s +-G +-v 3 +-l PSK-AES256-CBC-SHA + +# client DTLSv1.2 PSK-AES256 +-s +-G +-v 3 +-l PSK-AES256-CBC-SHA + +# server DTLSv1.2 PSK-AES128-SHA256 +-s +-G +-v 3 +-l PSK-AES128-CBC-SHA256 + +# client DTLSv1.2 PSK-AES128-SHA256 +-s +-G +-v 3 +-l PSK-AES128-CBC-SHA256 + +# server DTLSv1.2 PSK-AES256-SHA384 +-s +-G +-v 3 +-l PSK-AES256-CBC-SHA384 + +# client DTLSv1.2 PSK-AES256-SHA384 +-s +-G +-v 3 +-l PSK-AES256-CBC-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDHE-ECDSA-AES256-GCM-SHA384 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDH-ECDSA-AES128-GCM-SHA256 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-ECDSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDH-ECDSA-AES256-GCM-SHA384 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# client DTLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDHE-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# client DTLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDHE-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES128-GCM-SHA256 +-G +-v 3 +-l ECDH-RSA-AES128-GCM-SHA256 + +# server DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 +-c ./certs/server-ecc-rsa.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDH-RSA-AES256-GCM-SHA384 +-G +-v 3 +-l ECDH-RSA-AES256-GCM-SHA384 + +# server DTLSv1.2 PSK-AES128-GCM-SHA256 +-G +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# client DTLSv1.2 PSK-AES128-GCM-SHA256 +-G +-s +-v 3 +-l PSK-AES128-GCM-SHA256 + +# server DTLSv1.2 PSK-AES256-GCM-SHA384 +-G +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# client DTLSv1.2 PSK-AES256-GCM-SHA384 +-G +-s +-v 3 +-l PSK-AES256-GCM-SHA384 + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-G +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM +-G +-v 3 +-l ECDHE-ECDSA-AES128-CCM +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-G +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES128-CCM-8 +-G +-v 3 +-l ECDHE-ECDSA-AES128-CCM-8 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-G +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-AES256-CCM-8 +-G +-v 3 +-l ECDHE-ECDSA-AES256-CCM-8 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 ADH-AES128-SHA +-G +-a +-v 3 +-l ADH-AES128-SHA + +# client DTLSv1.2 ADH-AES128-SHA +-G +-a +-v 3 +-l ADH-AES128-SHA + +# server DTLSv1.0 ADH-AES128-SHA +-G +-a +-v 2 +-l ADH-AES128-SHA + +# client DTLSv1.0 ADH-AES128-SHA +-G +-a +-v 2 +-l ADH-AES128-SHA + diff --git a/tests/unit.c b/tests/unit.c index 4b64d1082a..dd98465291 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -54,11 +54,6 @@ int unit_test(int argc, char** argv) #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) wolfSSL_Debugging_ON(); #endif -#ifdef HAVE_CAVIUM - ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) - err_sys("Cavium OpenNitroxDevice failed"); -#endif /* HAVE_CAVIUM */ #ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0) @@ -85,10 +80,6 @@ int unit_test(int argc, char** argv) SrpTest(); -#ifdef HAVE_CAVIUM - CspShutdown(CAVIUM_DEV_ID); -#endif - #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) err_sys("Failed to free netRandom context"); diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 6d95d3199d..f27e575a61 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -84,12 +84,6 @@ int testsuite_test(int argc, char** argv) int num = 6; #endif -#ifdef HAVE_CAVIUM - int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) - err_sys("Cavium OpenNitroxDevice failed"); -#endif /* HAVE_CAVIUM */ - #ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0) { err_sys("Whitewood netRandom global config failed"); @@ -204,10 +198,6 @@ int testsuite_test(int argc, char** argv) fdCloseSession(Task_self()); #endif -#ifdef HAVE_CAVIUM - CspShutdown(CAVIUM_DEV_ID); -#endif - #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) err_sys("Failed to free netRandom context"); diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index a510d61d73..c0ea08f0a8 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -32,6 +32,13 @@ /* Macro to disable benchmark */ #ifndef NO_CRYPT_BENCHMARK +#ifdef WOLFSSL_STATIC_MEMORY + #include + static WOLFSSL_HEAP_HINT* HEAP_HINT; +#else + #define HEAP_HINT NULL +#endif /* WOLFSSL_STATIC_MEMORY */ + #include #ifdef FREESCALE_MQX @@ -77,15 +84,18 @@ #endif #include -#ifdef HAVE_CAVIUM - #include "cavium_sysdep.h" - #include "cavium_common.h" - #include "cavium_ioctl.h" -#endif #ifdef HAVE_NTRU #include "libntruencrypt/ntru_crypto.h" #endif #include +#include + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(HAVE_ECC) + static int devId = INVALID_DEVID; +#endif #ifdef HAVE_WNR const char* wnrConfigFile = "wnr-example.conf"; @@ -100,11 +110,39 @@ #define HAVE_GET_CYCLES static INLINE word64 get_intel_cycles(void); static word64 total_cycles; + #define INIT_CYCLE_COUNTER #define BEGIN_INTEL_CYCLES total_cycles = get_intel_cycles(); #define END_INTEL_CYCLES total_cycles = get_intel_cycles() - total_cycles; #define SHOW_INTEL_CYCLES printf(" Cycles per byte = %6.2f", \ (float)total_cycles / (numBlocks*sizeof(plain))); +#elif defined(LINUX_CYCLE_COUNT) + #include + #include + #include + + #define HAVE_GET_CYCLES + static word64 begin_cycles; + static word64 total_cycles; + static int cycles = -1; + static struct perf_event_attr atr; + + #define INIT_CYCLE_COUNTER do { \ + atr.type = PERF_TYPE_HARDWARE; \ + atr.config = PERF_COUNT_HW_CPU_CYCLES; \ + cycles = syscall(__NR_perf_event_open, &atr, 0, -1, -1, 0); \ + } while (0); + + #define BEGIN_INTEL_CYCLES read(cycles, &begin_cycles, sizeof(begin_cycles)); + #define END_INTEL_CYCLES do { \ + read(cycles, &total_cycles, sizeof(total_cycles)); \ + total_cycles = total_cycles - begin_cycles; \ + } while (0); + + #define SHOW_INTEL_CYCLES printf(" Cycles per byte = %6.2f", \ + (float)total_cycles / (numBlocks*sizeof(plain))); + #else + #define INIT_CYCLE_COUNTER #define BEGIN_INTEL_CYCLES #define END_INTEL_CYCLES #define SHOW_INTEL_CYCLES @@ -161,6 +199,9 @@ void bench_ripemd(void); void bench_cmac(void); void bench_rsa(void); +#ifdef WOLFSSL_ASYNC_CRYPT + void bench_rsa_async(void); +#endif void bench_rsaKeyGen(void); void bench_dh(void); #ifdef HAVE_ECC @@ -189,29 +230,6 @@ void bench_rng(void); double current_time(int); -#ifdef HAVE_CAVIUM - -static int OpenNitroxDevice(int dma_mode,int dev_id) -{ - Csp1CoreAssignment core_assign; - Uint32 device; - - if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID)) - return -1; - if (Csp1GetDevType(&device)) - return -1; - if (device != NPX_DEVICE) { - if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT, - (Uint32 *)&core_assign)!= 0) - return -1; - } - CspShutdown(CAVIUM_DEV_ID); - - return CspInitialize(dma_mode, dev_id); -} - -#endif - #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) WOLFSSL_API int wolfSSL_Debugging_ON(); #endif @@ -268,35 +286,49 @@ int benchmark_test(void *args) (void)args; #endif +#ifdef WOLFSSL_STATIC_MEMORY + #ifdef BENCH_EMBEDDED + byte memory[50000]; + #else + byte memory[400000]; + #endif + + if (wc_LoadStaticMemory(&HEAP_HINT, memory, sizeof(memory), + WOLFMEM_GENERAL, 1) != 0) { + printf("unable to load static memory"); + exit(EXIT_FAILURE); + } +#endif + #if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY) InitMemoryTracker(); #endif wolfCrypt_Init(); + INIT_CYCLE_COUNTER - #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) - wolfSSL_Debugging_ON(); - #endif +#if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) + wolfSSL_Debugging_ON(); +#endif (void)plain; (void)cipher; (void)key; (void)iv; - #ifdef HAVE_CAVIUM - int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) { - printf("Cavium OpenNitroxDevice failed\n"); +#ifdef WOLFSSL_ASYNC_CRYPT + if (wolfAsync_DevOpen(&devId) != 0) { + printf("Async device open failed\n"); exit(-1); } - #endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ - #ifdef HAVE_WNR +#ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0) { printf("Whitewood netRandom config init failed\n"); exit(-1); } - #endif /* HAVE_WNR */ +#endif /* HAVE_WNR */ #if defined(HAVE_LOCAL_RNG) { @@ -384,16 +416,18 @@ int benchmark_test(void *args) #ifndef NO_RSA bench_rsa(); + #ifdef WOLFSSL_ASYNC_CRYPT + bench_rsa_async(); + #endif + #ifdef WOLFSSL_KEY_GEN + bench_rsaKeyGen(); + #endif #endif #ifndef NO_DH bench_dh(); #endif -#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) - bench_rsaKeyGen(); -#endif - #ifdef HAVE_NTRU bench_ntru(); bench_ntruKeyGen(); @@ -426,6 +460,10 @@ int benchmark_test(void *args) wc_FreeRng(&rng); #endif +#ifdef WOLFSSL_ASYNC_CRYPT + wolfAsync_DevClose(&devId); +#endif + #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) { printf("Failed to free netRandom context\n"); @@ -452,9 +490,15 @@ static const char blockType[] = "kB"; /* used in printf output */ #else enum BenchmarkBounds { numBlocks = 50, /* how many megs to test (en/de)cryption */ +#ifdef WOLFSSL_ASYNC_CRYPT + ntimes = 1000, + genTimes = 1000, + agreeTimes = 1000 +#else ntimes = 100, genTimes = 100, agreeTimes = 100 +#endif }; static const char blockType[] = "megs"; /* used in printf output */ #endif @@ -526,9 +570,9 @@ void bench_aes(int show) int i; int ret; -#ifdef HAVE_CAVIUM - if (wc_AesInitCavium(&enc, CAVIUM_DEV_ID) != 0) { - printf("aes init cavium failed\n"); +#ifdef WOLFSSL_ASYNC_CRYPT + if ((ret = wc_AesAsyncInit(&enc, devId)) != 0) { + printf("wc_AesAsyncInit failed, ret = %d\n", ret); return; } #endif @@ -559,10 +603,10 @@ void bench_aes(int show) SHOW_INTEL_CYCLES printf("\n"); } -#ifdef HAVE_CAVIUM - wc_AesFreeCavium(&enc); - if (wc_AesInitCavium(&enc, CAVIUM_DEV_ID) != 0) { - printf("aes init cavium failed\n"); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_AesAsyncFree(&enc); + if ((ret = wc_AesAsyncInit(&enc, devId)) != 0) { + printf("wc_AesAsyncInit failed, ret = %d\n", ret); return; } #endif @@ -593,8 +637,8 @@ void bench_aes(int show) SHOW_INTEL_CYCLES printf("\n"); } -#ifdef HAVE_CAVIUM - wc_AesFreeCavium(&enc); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_AesAsyncFree(&enc); #endif } #endif /* HAVE_AES_CBC */ @@ -805,9 +849,9 @@ void bench_des(void) double start, total, persec; int i, ret; -#ifdef HAVE_CAVIUM - if (wc_Des3_InitCavium(&enc, CAVIUM_DEV_ID) != 0) - printf("des3 init cavium failed\n"); +#ifdef WOLFSSL_ASYNC_CRYPT + if (wc_Des3AsyncInit(&enc, devId) != 0) + printf("des3 async init failed\n"); #endif ret = wc_Des3_SetKey(&enc, key, iv, DES_ENCRYPTION); if (ret != 0) { @@ -833,8 +877,8 @@ void bench_des(void) blockType, total, persec); SHOW_INTEL_CYCLES printf("\n"); -#ifdef HAVE_CAVIUM - wc_Des3_FreeCavium(&enc); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_Des3AsyncFree(&enc); #endif } #endif @@ -882,9 +926,9 @@ void bench_arc4(void) double start, total, persec; int i; -#ifdef HAVE_CAVIUM - if (wc_Arc4InitCavium(&enc, CAVIUM_DEV_ID) != 0) - printf("arc4 init cavium failed\n"); +#ifdef WOLFSSL_ASYNC_CRYPT + if (wc_Arc4AsyncInit(&enc, devId) != 0) + printf("arc4 async init failed\n"); #endif wc_Arc4SetKey(&enc, key, 16); @@ -906,8 +950,8 @@ void bench_arc4(void) blockType, total, persec); SHOW_INTEL_CYCLES printf("\n"); -#ifdef HAVE_CAVIUM - wc_Arc4FreeCavium(&enc); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_Arc4AsyncFree(&enc); #endif } #endif @@ -1395,7 +1439,7 @@ void bench_rsa(void) word32 idx = 0; const byte* tmp; - byte message[] = "Everyone gets Friday off."; + const byte message[] = "Everyone gets Friday off."; byte enc[256]; /* for up to 2048 bit */ const int len = (int)strlen((char*)message); double start, total, each, milliEach; @@ -1414,32 +1458,33 @@ void bench_rsa(void) #error "need a cert buffer size" #endif /* USE_CERT_BUFFERS */ - -#ifdef HAVE_CAVIUM - if (wc_RsaInitCavium(&rsaKey, CAVIUM_DEV_ID) != 0) - printf("RSA init cavium failed\n"); -#endif - ret = wc_InitRsaKey(&rsaKey, 0); - if (ret < 0) { - printf("InitRsaKey failed\n"); + if ((ret = wc_InitRsaKey(&rsaKey, HEAP_HINT)) < 0) { + printf("InitRsaKey failed! %d\n", ret); return; } + + /* decode the private key */ ret = wc_RsaPrivateKeyDecode(tmp, &idx, &rsaKey, (word32)bytes); start = current_time(1); - for (i = 0; i < ntimes; i++) - ret = wc_RsaPublicEncrypt(message,len,enc,sizeof(enc), &rsaKey, &rng); + for (i = 0; i < ntimes; i++) { + ret = wc_RsaPublicEncrypt(message, len, enc, sizeof(enc), + &rsaKey, &rng); + if (ret < 0) { + break; + } + } /* for ntimes */ total = current_time(0) - start; each = total / ntimes; /* per second */ milliEach = each * 1000; /* milliseconds */ - printf("RSA %d encryption took %6.3f milliseconds, avg over %d" + printf("RSA %d public %6.3f milliseconds, avg over %d" " iterations\n", rsaKeySz, milliEach, ntimes); if (ret < 0) { - printf("Rsa Public Encrypt failed\n"); + printf("Rsa Public Encrypt failed! %d\n", ret); return; } @@ -1448,24 +1493,231 @@ void bench_rsa(void) #endif start = current_time(1); + /* capture resulting encrypt length */ + idx = ret; + for (i = 0; i < ntimes; i++) { - byte out[256]; /* for up to 2048 bit */ - wc_RsaPrivateDecrypt(enc, (word32)ret, out, sizeof(out), &rsaKey); - } + byte out[256]; /* for up to 2048 bit */ + + ret = wc_RsaPrivateDecrypt(enc, idx, out, sizeof(out), &rsaKey); + if (ret < 0 && ret != WC_PENDING_E) { + break; + } + } /* for ntimes */ total = current_time(0) - start; each = total / ntimes; /* per second */ milliEach = each * 1000; /* milliseconds */ - printf("RSA %d decryption took %6.3f milliseconds, avg over %d" + printf("RSA %d private %6.3f milliseconds, avg over %d" " iterations\n", rsaKeySz, milliEach, ntimes); wc_FreeRsaKey(&rsaKey); -#ifdef HAVE_CAVIUM - wc_RsaFreeCavium(&rsaKey); -#endif } -#endif + + +#ifdef WOLFSSL_ASYNC_CRYPT +void bench_rsa_async(void) +{ + int i; + int ret; + size_t bytes; + word32 idx = 0; + const byte* tmp; + + const byte message[] = "Everyone gets Friday off."; + byte enc[256]; /* for up to 2048 bit */ + const int len = (int)strlen((char*)message); + double start, total, each, milliEach; + + RsaKey rsaKey[WOLF_ASYNC_MAX_PENDING]; + int rsaKeySz = 2048; /* used in printf */ + + WOLF_EVENT events[WOLF_ASYNC_MAX_PENDING]; + WOLF_EVENT_QUEUE eventQueue; + int evtNum, asyncDone, asyncPend; + +#ifdef USE_CERT_BUFFERS_1024 + tmp = rsa_key_der_1024; + bytes = sizeof_rsa_key_der_1024; + rsaKeySz = 1024; +#elif defined(USE_CERT_BUFFERS_2048) + tmp = rsa_key_der_2048; + bytes = sizeof_rsa_key_der_2048; +#else + #error "need a cert buffer size" +#endif /* USE_CERT_BUFFERS */ + + /* init event queue */ + ret = wolfEventQueue_Init(&eventQueue); + if (ret != 0) { + return; + } + + /* clear for done cleanup */ + XMEMSET(&events, 0, sizeof(events)); + XMEMSET(&rsaKey, 0, sizeof(rsaKey)); + + /* init events and keys */ + for (i = 0; i < WOLF_ASYNC_MAX_PENDING; i++) { + /* setup an async context for each key */ + if ((ret = wc_InitRsaKey_ex(&rsaKey[i], HEAP_HINT, devId)) < 0) { + goto done; + } + #ifdef WC_RSA_BLINDING + wc_RsaSetRNG(&rsaKey[i], &rng); + #endif + if ((ret = wolfAsync_EventInit(&events[i], + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &rsaKey[i].asyncDev)) != 0) { + goto done; + } + events[i].pending = 0; /* Reset pending flag */ + + /* decode the private key */ + idx = 0; + if ((ret = wc_RsaPrivateKeyDecode(tmp, &idx, &rsaKey[i], + (word32)bytes)) != 0) { + printf("wc_RsaPrivateKeyDecode failed! %d\n", ret); + goto done; + } + } + + /* begin public async RSA */ + start = current_time(1); + + asyncPend = 0; + for (i = 0; i < ntimes; ) { + + /* while free pending slots in queue, submit RSA operations */ + for (evtNum = 0; evtNum < WOLF_ASYNC_MAX_PENDING; evtNum++) { + if (events[evtNum].done || (events[evtNum].pending == 0 && + (i + asyncPend) < ntimes)) + { + /* check for event error */ + if (events[evtNum].ret != WC_PENDING_E && events[evtNum].ret < 0) { + printf("wc_RsaPublicEncrypt: Async event error: %d\n", events[evtNum].ret); + goto done; + } + + ret = wc_RsaPublicEncrypt(message, len, enc, sizeof(enc), + &rsaKey[evtNum], &rng); + if (ret == WC_PENDING_E) { + ret = wc_RsaAsyncHandle(&rsaKey[evtNum], &eventQueue, + &events[evtNum]); + if (ret != 0) goto done; + asyncPend++; + } + else if (ret >= 0) { + /* operation completed */ + i++; + asyncPend--; + events[evtNum].done = 0; + } + else { + printf("wc_RsaPublicEncrypt failed: %d\n", ret); + goto done; + } + } + } /* for evtNum */ + + /* poll until there are events done */ + if (asyncPend > 0) { + do { + ret = wolfAsync_EventQueuePoll(&eventQueue, NULL, NULL, 0, + WOLF_POLL_FLAG_CHECK_HW, &asyncDone); + if (ret != 0) goto done; + } while (asyncDone == 0); + } + } /* for ntimes */ + + total = current_time(0) - start; + each = total / ntimes; /* per second */ + milliEach = each * 1000; /* milliseconds */ + + printf("RSA %d public async %6.3f milliseconds, avg over %d" + " iterations\n", rsaKeySz, milliEach, ntimes); + + if (ret < 0) { + goto done; + } + + + /* begin private async RSA */ + start = current_time(1); + + /* capture resulting encrypt length */ + idx = sizeof(enc); /* fixed at 2048 bit */ + + asyncPend = 0; + for (i = 0; i < ntimes; ) { + byte out[256]; /* for up to 2048 bit */ + + /* while free pending slots in queue, submit RSA operations */ + for (evtNum = 0; evtNum < WOLF_ASYNC_MAX_PENDING; evtNum++) { + if (events[evtNum].done || (events[evtNum].pending == 0 && + (i + asyncPend) < ntimes)) + { + /* check for event error */ + if (events[evtNum].ret != WC_PENDING_E && events[evtNum].ret < 0) { + printf("wc_RsaPrivateDecrypt: Async event error: %d\n", events[evtNum].ret); + goto done; + } + + ret = wc_RsaPrivateDecrypt(enc, idx, out, sizeof(out), + &rsaKey[evtNum]); + if (ret == WC_PENDING_E) { + ret = wc_RsaAsyncHandle(&rsaKey[evtNum], &eventQueue, + &events[evtNum]); + if (ret != 0) goto done; + asyncPend++; + } + else if (ret >= 0) { + /* operation completed */ + i++; + asyncPend--; + events[evtNum].done = 0; + } + else { + printf("wc_RsaPrivateDecrypt failed: %d\n", ret); + goto done; + } + } + } /* for evtNum */ + + /* poll until there are events done */ + if (asyncPend > 0) { + do { + ret = wolfAsync_EventQueuePoll(&eventQueue, NULL, NULL, 0, + WOLF_POLL_FLAG_CHECK_HW, &asyncDone); + if (ret != 0) goto done; + } while (asyncDone == 0); + } + } /* for ntimes */ + + total = current_time(0) - start; + each = total / ntimes; /* per second */ + milliEach = each * 1000; /* milliseconds */ + + printf("RSA %d private async %6.3f milliseconds, avg over %d" + " iterations\n", rsaKeySz, milliEach, ntimes); + +done: + + if (ret < 0) { + printf("bench_rsa_async failed: %d\n", ret); + } + + /* cleanup */ + for (i = 0; i < WOLF_ASYNC_MAX_PENDING; i++) { + wc_FreeRsaKey(&rsaKey[i]); + } + + /* free event queue */ + wolfEventQueue_Free(&eventQueue); +} +#endif /* WOLFSSL_ASYNC_CRYPT */ + +#endif /* !NO_RSA */ #ifndef NO_DH @@ -1572,7 +1824,7 @@ void bench_rsaKeyGen(void) start = current_time(1); for(i = 0; i < genTimes; i++) { - wc_InitRsaKey(&genKey, 0); + wc_InitRsaKey(&genKey, HEAP_HINT); wc_MakeRsaKey(&genKey, 1024, 65537, &rng); wc_FreeRsaKey(&genKey); } @@ -1588,7 +1840,7 @@ void bench_rsaKeyGen(void) start = current_time(1); for(i = 0; i < genTimes; i++) { - wc_InitRsaKey(&genKey, 0); + wc_InitRsaKey(&genKey, HEAP_HINT); wc_MakeRsaKey(&genKey, 2048, 65537, &rng); wc_FreeRsaKey(&genKey); } @@ -1845,7 +2097,7 @@ void bench_eccKeyGen(void) start = current_time(1); for(i = 0; i < genTimes; i++) { - wc_ecc_init(&genKey); + wc_ecc_init_ex(&genKey, HEAP_HINT, devId); wc_ecc_make_key(&rng, 32, &genKey); wc_ecc_free(&genKey); } @@ -1871,8 +2123,8 @@ void bench_eccKeyAgree(void) byte digest[32]; word32 x = 0; - wc_ecc_init(&genKey); - wc_ecc_init(&genKey2); + wc_ecc_init_ex(&genKey, HEAP_HINT, devId); + wc_ecc_init_ex(&genKey2, HEAP_HINT, devId); ret = wc_ecc_make_key(&rng, 32, &genKey); if (ret != 0) { @@ -1958,8 +2210,8 @@ void bench_eccEncrypt(void) int ret, i; double start, total, each, milliEach; - wc_ecc_init(&userA); - wc_ecc_init(&userB); + wc_ecc_init_ex(&userA, HEAP_HINT, devId); + wc_ecc_init_ex(&userB, HEAP_HINT, devId); wc_ecc_make_key(&rng, 32, &userA); wc_ecc_make_key(&rng, 32, &userB); @@ -2249,7 +2501,7 @@ void bench_ed25519KeySign(void) } #elif defined(WOLFSSL_EMBOS) - + #include "RTOS.h" double current_time(int reset) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index c12cd328b8..f832230f79 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -164,16 +164,15 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, #endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AESCCM */ -#ifdef HAVE_CAVIUM -int wc_AesInitCavium(Aes* aes, int i) +#ifdef WOLFSSL_ASYNC_CRYPT +int wc_AesAsyncInit(Aes* aes, int i) { - return AesInitCavium(aes, i); + return AesAsyncInit(aes, i); } - -void wc_AesFreeCavium(Aes* aes) +void wc_AesAsyncFree(Aes* aes) { - AesFreeCavium(aes); + AesAsyncFree(aes); } #endif #else /* HAVE_FIPS */ @@ -332,22 +331,8 @@ void wc_AesFreeCavium(Aes* aes) #define DEBUG_WOLFSSL #include "wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h" #elif defined(HAVE_CAVIUM) - #include - #include "cavium_common.h" - /* still leave SW crypto available */ #define NEED_AES_TABLES - - static int wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length, - const byte* iv); - #ifdef HAVE_AES_CBC - static int wc_AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in, - word32 length); - #ifdef HAVE_AES_DECRYPT - static int wc_AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, - word32 length); - #endif /* HAVE_AES_DECRYPT */ - #endif /* HAVE_AES_CBC */ #elif defined(WOLFSSL_NRF51_AES) /* Use built-in AES hardware - AES 128 ECB Encrypt Only */ #include "wolfssl/wolfcrypt/port/nrf51.h" @@ -359,7 +344,153 @@ void wc_AesFreeCavium(Aes* aes) #ifdef HAVE_AES_DECRYPT #error nRF51 AES Hardware does not support decrypt #endif /* HAVE_AES_DECRYPT */ +#elif defined(WOLFSSL_ARMASM) + static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + byte* keyPt = (byte*)aes->key; + word32 rounds = aes->rounds; + /* + AESE exor's input with round key + shift rows of exor'ed result + sub bytes for shifted rows + */ + + __asm__ __volatile__ ( + "LD1 {v0.16b}, [%[CtrIn]] \n" + "LD1 {v1.16b-v4.16b}, [%[Key]], #64 \n" + + "AESE v0.16b, v1.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v2.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v3.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v4.16b \n" + "AESMC v0.16b, v0.16b \n" + + "LD1 {v1.16b-v4.16b}, [%[Key]], #64 \n" + "AESE v0.16b, v1.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v2.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v3.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v4.16b \n" + "AESMC v0.16b, v0.16b \n" + + "LD1 {v1.16b-v2.16b}, [%[Key]], #32 \n" + "AESE v0.16b, v1.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v2.16b \n" + + "#subtract rounds done so far and see if should continue\n" + "MOV w12, %w[R] \n" + "SUB w12, w12, #10 \n" + "CBZ w12, final \n" + "LD1 {v1.16b-v2.16b}, [%[Key]], #32 \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v1.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v2.16b \n" + + "SUB w12, w12, #2 \n" + "CBZ w12, final \n" + "LD1 {v1.16b-v2.16b}, [%[Key]], #32 \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v1.16b \n" + "AESMC v0.16b, v0.16b \n" + "AESE v0.16b, v2.16b \n" + + "#Final AddRoundKey then store result \n" + "final: \n" + "LD1 {v1.16b}, [%[Key]], #16 \n" + "EOR v0.16b, v0.16b, v1.16b \n" + "ST1 {v0.16b}, [%[CtrOut]] \n" + + :[CtrOut] "=r" (outBlock), "=r" (keyPt), "=r" (rounds), + "=r" (inBlock) + :"0" (outBlock), [Key] "1" (keyPt), [R] "2" (rounds), + [CtrIn] "3" (inBlock) + : "cc", "memory", "w12" + ); + + return 0; + } + #ifdef HAVE_AES_DECRYPT + static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + byte* keyPt = (byte*)aes->key; + word32 rounds = aes->rounds; + + /* + AESE exor's input with round key + shift rows of exor'ed result + sub bytes for shifted rows + */ + + __asm__ __volatile__ ( + "LD1 {v0.16b}, [%[CtrIn]] \n" + "LD1 {v1.16b-v4.16b}, [%[Key]], #64 \n" + + "AESD v0.16b, v1.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v2.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v3.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v4.16b \n" + "AESIMC v0.16b, v0.16b \n" + + "LD1 {v1.16b-v4.16b}, [%[Key]], #64 \n" + "AESD v0.16b, v1.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v2.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v3.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v4.16b \n" + "AESIMC v0.16b, v0.16b \n" + + "LD1 {v1.16b-v2.16b}, [%[Key]], #32 \n" + "AESD v0.16b, v1.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v2.16b \n" + + "#subtract rounds done so far and see if should continue\n" + "MOV w12, %w[R] \n" + "SUB w12, w12, #10 \n" + "CBZ w12, finalDec \n" + "LD1 {v1.16b-v2.16b}, [%[Key]], #32 \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v1.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v2.16b \n" + + "SUB w12, w12, #2 \n" + "CBZ w12, finalDec \n" + "LD1 {v1.16b-v2.16b}, [%[Key]], #32 \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v1.16b \n" + "AESIMC v0.16b, v0.16b \n" + "AESD v0.16b, v2.16b \n" + + "#Final AddRoundKey then store result \n" + "finalDec: \n" + "LD1 {v1.16b}, [%[Key]], #16 \n" + "EOR v0.16b, v0.16b, v1.16b \n" + "ST1 {v0.4s}, [%[CtrOut]] \n" + + :[CtrOut] "=r" (outBlock), "=r" (keyPt), "=r" (rounds), + "=r" (inBlock) + :"0" (outBlock), [Key] "1" (keyPt), [R] "2" (rounds), + [CtrIn] "3" (inBlock) + : "cc", "memory", "w12" + ); + + return 0; +} + #endif /* HAVE_AES_DECRYPT */ #else /* using wolfCrypt software AES implementation */ @@ -376,7 +507,7 @@ static const word32 rcon[] = { /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; -static const word32 Te[5][256] = { +static const word32 Te[4][256] = { { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, @@ -640,76 +771,10 @@ static const word32 Te[5][256] = { 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}, -{ - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, } }; -static const word32 Td[5][256] = { +static const word32 Td[4][256] = { { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, @@ -974,75 +1039,46 @@ static const word32 Td[5][256] = { 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, -}, -{ - 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, - 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, - 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, - 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, - 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, - 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, - 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, - 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, - 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, - 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, - 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, - 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, - 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, - 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, - 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, - 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, - 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, - 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, - 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, - 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, - 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, - 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, - 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, - 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, - 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, - 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, - 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, - 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, - 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, - 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, - 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, - 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, - 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, - 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, - 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, - 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, - 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, - 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, - 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, - 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, - 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, - 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, - 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, - 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, - 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, - 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, - 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, - 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, - 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, - 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, - 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, - 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, - 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, - 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, - 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, - 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, - 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, - 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, - 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, - 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, - 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, - 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, - 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, - 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, } }; + +static const byte Td4[256] = +{ + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; + #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y)))) @@ -1206,6 +1242,34 @@ static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) ||\ defined(HAVE_AESGCM) + +#ifndef WC_CACHE_LINE_SZ + #if defined(__x86_64__) || defined(_M_X64) || \ + (defined(__ILP32__) && (__ILP32__ >= 1)) + #define WC_CACHE_LINE_SZ 64 + #else + /* default cache line size */ + #define WC_CACHE_LINE_SZ 32 + #endif +#endif + + +/* load 4 Te Tables into cache by cache line stride */ +static INLINE word32 PreFetchTe(void) +{ + word32 x = 0; + int i,j; + + for (i = 0; i < 4; i++) { + /* 256 elements, each one is 4 bytes */ + for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) { + x &= Te[i][j]; + } + } + return x; +} + + static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) { word32 s0, s1, s2, s3; @@ -1280,6 +1344,8 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) s2 ^= rk[2]; s3 ^= rk[3]; + s0 |= PreFetchTe(); + /* * Nr - 1 full rounds: */ @@ -1347,28 +1413,28 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) */ s0 = - (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^ - (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^ - (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^ - (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^ + (Te[2][GETBYTE(t0, 3)] & 0xff000000) ^ + (Te[3][GETBYTE(t1, 2)] & 0x00ff0000) ^ + (Te[0][GETBYTE(t2, 1)] & 0x0000ff00) ^ + (Te[1][GETBYTE(t3, 0)] & 0x000000ff) ^ rk[0]; s1 = - (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^ - (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^ - (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^ - (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^ + (Te[2][GETBYTE(t1, 3)] & 0xff000000) ^ + (Te[3][GETBYTE(t2, 2)] & 0x00ff0000) ^ + (Te[0][GETBYTE(t3, 1)] & 0x0000ff00) ^ + (Te[1][GETBYTE(t0, 0)] & 0x000000ff) ^ rk[1]; s2 = - (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^ - (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^ - (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^ - (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^ + (Te[2][GETBYTE(t2, 3)] & 0xff000000) ^ + (Te[3][GETBYTE(t3, 2)] & 0x00ff0000) ^ + (Te[0][GETBYTE(t0, 1)] & 0x0000ff00) ^ + (Te[1][GETBYTE(t1, 0)] & 0x000000ff) ^ rk[2]; s3 = - (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^ - (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^ - (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^ - (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^ + (Te[2][GETBYTE(t3, 3)] & 0xff000000) ^ + (Te[3][GETBYTE(t0, 2)] & 0x00ff0000) ^ + (Te[0][GETBYTE(t1, 1)] & 0x0000ff00) ^ + (Te[1][GETBYTE(t2, 0)] & 0x000000ff) ^ rk[3]; /* write out */ @@ -1383,11 +1449,42 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) XMEMCPY(outBlock + sizeof(s0), &s1, sizeof(s1)); XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2)); XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); + } #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */ #ifdef HAVE_AES_DECRYPT #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) + +/* load 4 Td Tables into cache by cache line stride */ +static INLINE word32 PreFetchTd(void) +{ + word32 x = 0; + int i,j; + + for (i = 0; i < 4; i++) { + /* 256 elements, each one is 4 bytes */ + for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) { + x &= Td[i][j]; + } + } + return x; +} + + +/* load Td Table4 into cache by cache line stride */ +static INLINE word32 PreFetchTd4(void) +{ + word32 x = 0; + int i; + + for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) { + x &= (word32)Td4[i]; + } + return x; +} + + static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { word32 s0, s1, s2, s3; @@ -1444,6 +1541,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) s2 ^= rk[2]; s3 ^= rk[3]; + s0 |= PreFetchTd(); + /* * Nr - 1 full rounds: */ @@ -1508,29 +1607,32 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) * apply last round and * map cipher state to byte array block: */ + + s0 |= PreFetchTd4(); + s0 = - (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^ - (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^ - (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^ - (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^ + ((word32)Td4[GETBYTE(t0, 3)] << 24) ^ + ((word32)Td4[GETBYTE(t3, 2)] << 16) ^ + ((word32)Td4[GETBYTE(t2, 1)] << 8) ^ + ((word32)Td4[GETBYTE(t1, 0)]) ^ rk[0]; s1 = - (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^ - (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^ - (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^ - (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^ + ((word32)Td4[GETBYTE(t1, 3)] << 24) ^ + ((word32)Td4[GETBYTE(t0, 2)] << 16) ^ + ((word32)Td4[GETBYTE(t3, 1)] << 8) ^ + ((word32)Td4[GETBYTE(t2, 0)]) ^ rk[1]; s2 = - (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^ - (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^ - (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^ - (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^ + ((word32)Td4[GETBYTE(t2, 3)] << 24) ^ + ((word32)Td4[GETBYTE(t1, 2)] << 16) ^ + ((word32)Td4[GETBYTE(t0, 1)] << 8) ^ + ((word32)Td4[GETBYTE(t3, 0)]) ^ rk[2]; s3 = - (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^ - (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^ - (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^ - (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^ + ((word32)Td4[GETBYTE(t3, 3)] << 24) ^ + ((word32)Td4[GETBYTE(t2, 2)] << 16) ^ + ((word32)Td4[GETBYTE(t1, 1)] << 8) ^ + ((word32)Td4[GETBYTE(t0, 0)]) ^ rk[3]; /* write out */ @@ -1548,7 +1650,6 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) } #endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */ - #endif /* NEED_AES_TABLES */ @@ -1693,6 +1794,196 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { return wc_AesSetKey(aes, userKey, keylen, iv, dir); } +#elif defined(WOLFSSL_ARMASM) + static const byte rcon[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,0x1B, 0x36 + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ + }; + + + /* Similar to wolfSSL software implementation of expanding the AES key. + * Changed out the locations of where table look ups where made to + * use hardware instruction. Also altered decryption key to match. */ + int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + word32 temp, *rk = aes->key; + unsigned int i = 0; + + #if defined(AES_MAX_KEY_SIZE) + const word32 max_key_len = (AES_MAX_KEY_SIZE / 8); + #endif + + if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) + return BAD_FUNC_ARG; + + #if defined(AES_MAX_KEY_SIZE) + /* Check key length */ + if (keylen > max_key_len) { + return BAD_FUNC_ARG; + } + #endif + + #ifdef WOLFSSL_AES_COUNTER + aes->left = 0; + #endif /* WOLFSSL_AES_COUNTER */ + + aes->rounds = keylen/4 + 6; + XMEMCPY(rk, userKey, keylen); + + switch(keylen) + { +#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 + case 16: + while (1) + { + temp = rk[3]; + + /* get table value from hardware */ + __asm__ volatile ( + "DUP v1.4s, %w[in] \n" + "MOVI v0.16b, #0 \n" + "AESE v0.16b, v1.16b \n" + "UMOV %w[out], v0.4s[0] \n" + : [out] "=r"(temp) + : [in] "r" (temp) + : "cc", "memory", "v0", "v1" + ); + temp = rotrFixed(temp, 8); + rk[4] = rk[0] ^ temp ^ rcon[i]; + rk[5] = rk[4] ^ rk[1]; + rk[6] = rk[5] ^ rk[2]; + rk[7] = rk[6] ^ rk[3]; + if (++i == 10) + break; + rk += 4; + } + break; +#endif /* 128 */ + +#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 + case 24: + /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */ + while (1) + { + temp = rk[5]; + + /* get table value from hardware */ + __asm__ volatile ( + "DUP v1.4s, %w[in] \n" + "MOVI v0.16b, #0 \n" + "AESE v0.16b, v1.16b \n" + "UMOV %w[out], v0.4s[0] \n" + : [out] "=r"(temp) + : [in] "r" (temp) + : "cc", "memory", "v0", "v1" + ); + temp = rotrFixed(temp, 8); + rk[ 6] = rk[ 0] ^ temp ^ rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) + break; + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + break; +#endif /* 192 */ + +#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 + case 32: + while (1) + { + temp = rk[7]; + + /* get table value from hardware */ + __asm__ volatile ( + "DUP v1.4s, %w[in] \n" + "MOVI v0.16b, #0 \n" + "AESE v0.16b, v1.16b \n" + "UMOV %w[out], v0.4s[0] \n" + : [out] "=r"(temp) + : [in] "r" (temp) + : "cc", "memory", "v0", "v1" + ); + temp = rotrFixed(temp, 8); + rk[8] = rk[0] ^ temp ^ rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) + break; + temp = rk[11]; + + /* get table value from hardware */ + __asm__ volatile ( + "DUP v1.4s, %w[in] \n" + "MOVI v0.16b, #0 \n" + "AESE v0.16b, v1.16b \n" + "UMOV %w[out], v0.4s[0] \n" + : [out] "=r"(temp) + : [in] "r" (temp) + : "cc", "memory", "v0", "v1" + ); + rk[12] = rk[ 4] ^ temp; + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + break; +#endif /* 256 */ + + default: + return BAD_FUNC_ARG; + } + + if (dir == AES_DECRYPTION) + { +#ifdef HAVE_AES_DECRYPT + unsigned int j; + rk = aes->key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the + first and the last: */ + for (i = 1; i < aes->rounds; i++) { + rk += 4; + __asm__ volatile ( + "LD1 {v0.16b}, [%[in]] \n" + "AESIMC v0.16b, v0.16b \n" + "ST1 {v0.16b}, [%[out]]\n" + : [out] "=r" (rk) + : [in] "0" (rk) + : "cc", "memory", "v0" + ); + } +#else + WOLFSSL_MSG("AES Decryption not compiled in"); + return BAD_FUNC_ARG; +#endif /* HAVE_AES_DECRYPT */ + } + + return wc_AesSetIV(aes, iv); + } + + #if defined(WOLFSSL_AES_DIRECT) + int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + return wc_AesSetKey(aes, userKey, keylen, iv, dir); + } + #endif + #else static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir) @@ -1735,10 +2026,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { temp = rk[3]; rk[4] = rk[0] ^ - (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; @@ -1757,10 +2048,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ - (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^ rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; @@ -1780,10 +2071,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ - (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^ rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; @@ -1792,10 +2083,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) break; temp = rk[11]; rk[12] = rk[ 4] ^ - (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 0)] & 0x000000ff); + (Te[2][GETBYTE(temp, 3)] & 0xff000000) ^ + (Te[3][GETBYTE(temp, 2)] & 0x00ff0000) ^ + (Te[0][GETBYTE(temp, 1)] & 0x0000ff00) ^ + (Te[1][GETBYTE(temp, 0)] & 0x000000ff); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; @@ -1827,25 +2118,25 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) for (i = 1; i < aes->rounds; i++) { rk += 4; rk[0] = - Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff]; + Td[0][Te[1][GETBYTE(rk[0], 3)] & 0xff] ^ + Td[1][Te[1][GETBYTE(rk[0], 2)] & 0xff] ^ + Td[2][Te[1][GETBYTE(rk[0], 1)] & 0xff] ^ + Td[3][Te[1][GETBYTE(rk[0], 0)] & 0xff]; rk[1] = - Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff]; + Td[0][Te[1][GETBYTE(rk[1], 3)] & 0xff] ^ + Td[1][Te[1][GETBYTE(rk[1], 2)] & 0xff] ^ + Td[2][Te[1][GETBYTE(rk[1], 1)] & 0xff] ^ + Td[3][Te[1][GETBYTE(rk[1], 0)] & 0xff]; rk[2] = - Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff]; + Td[0][Te[1][GETBYTE(rk[2], 3)] & 0xff] ^ + Td[1][Te[1][GETBYTE(rk[2], 2)] & 0xff] ^ + Td[2][Te[1][GETBYTE(rk[2], 1)] & 0xff] ^ + Td[3][Te[1][GETBYTE(rk[2], 0)] & 0xff]; rk[3] = - Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff]; + Td[0][Te[1][GETBYTE(rk[3], 3)] & 0xff] ^ + Td[1][Te[1][GETBYTE(rk[3], 2)] & 0xff] ^ + Td[2][Te[1][GETBYTE(rk[3], 1)] & 0xff] ^ + Td[3][Te[1][GETBYTE(rk[3], 0)] & 0xff]; } } #endif /* HAVE_AES_DECRYPT */ @@ -1870,9 +2161,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) } #endif - #ifdef HAVE_CAVIUM - if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC) - return wc_AesCaviumSetKey(aes, userKey, keylen, iv); + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES) { + return NitroxAesSetKey(aes, userKey, keylen, iv); + } #endif #ifdef WOLFSSL_AESNI @@ -2490,9 +2782,9 @@ int wc_InitAes_h(Aes* aes, void* h) { word32 blocks = sz / AES_BLOCK_SIZE; - #ifdef HAVE_CAVIUM - if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC) - return wc_AesCaviumCbcEncrypt(aes, out, in, sz); + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES) + return NitroxAesCbcEncrypt(aes, out, in, sz); #endif #ifdef WOLFSSL_AESNI @@ -2554,9 +2846,10 @@ int wc_InitAes_h(Aes* aes, void* h) { word32 blocks = sz / AES_BLOCK_SIZE; - #ifdef HAVE_CAVIUM - if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC) - return wc_AesCaviumCbcDecrypt(aes, out, in, sz); + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES) { + return NitroxAesCbcDecrypt(aes, out, in, sz); + } #endif #ifdef WOLFSSL_AESNI @@ -2872,7 +3165,7 @@ static INLINE void IncrementGcmCounter(byte* inOutCtr) } -#if defined(GCM_SMALL) || defined(GCM_TABLE) +#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(WOLFSSL_ARMASM) static INLINE void FlattenSzInBits(byte* buf, word32 sz) { @@ -2956,6 +3249,20 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) if (ret == 0) { wc_AesEncrypt(aes, iv, aes->H); + #if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + { + word32* pt = (word32*)aes->H; + __asm__ volatile ( + "LD1 {v0.16b}, [%[h]] \n" + "RBIT v0.16b, v0.16b \n" + "ST1 {v0.16b}, [%[out]] \n" + : [out] "=r" (pt) + : [h] "0" (pt) + : "cc", "memory" + ); + return ret; /* no need to generate GCM_TABLE */ + } + #endif #ifdef GCM_TABLE GenerateM0(aes); #endif /* GCM_TABLE */ @@ -3392,8 +3699,118 @@ static int AES_GCM_decrypt(const unsigned char *in, #endif /* WOLFSSL_AESNI */ -#if defined(GCM_SMALL) +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) +/* PMULL and RBIT only with AArch64 */ +/* Use ARM hardware for polynomial multiply */ +static void GMULT(byte* X, byte* Y) +{ + word32* Xpt = (word32*)X; + word32* Ypt = (word32*)Y; + __asm__ volatile ( + "LD1 {v0.16b}, [%[inX]] \n" + "LD1 {v1.16b}, [%[inY]] \n" /* v1 already reflected from set key */ + "RBIT v0.16b, v0.16b \n" + + + /* Algorithm 1 from Intel GCM white paper. + "Carry-Less Multiplication and Its Usage for Computing the GCM Mode" + */ + "PMULL v3.1q, v0.1d, v1.1d \n" /* a0 * b0 = C */ + "PMULL2 v4.1q, v0.2d, v1.2d \n" /* a1 * b1 = D */ + "EXT v5.16b, v1.16b, v1.16b, #8 \n" /* b0b1 -> b1b0 */ + "PMULL v6.1q, v0.1d, v5.1d \n" /* a0 * b1 = E */ + "PMULL2 v5.1q, v0.2d, v5.2d \n" /* a1 * b0 = F */ + + "#Set a register to all 0s using EOR \n" + "EOR v7.16b, v7.16b, v7.16b \n" + "EOR v5.16b, v5.16b, v6.16b \n" /* F ^ E */ + "EXT v6.16b, v7.16b, v5.16b, #8 \n" /* get (F^E)[0] */ + "EOR v3.16b, v3.16b, v6.16b \n" /* low 128 bits in v3 */ + "EXT v6.16b, v5.16b, v7.16b, #8 \n" /* get (F^E)[1] */ + "EOR v4.16b, v4.16b, v6.16b \n" /* high 128 bits in v4 */ + + + /* Based from White Paper "Implementing GCM on ARMv8" + by Conrado P.L. Gouvea and Julio Lopez + reduction on 256bit value using Algorithm 5 */ + "MOVI v8.16b, #0x87 \n" + "USHR v8.2d, v8.2d, #56 \n" + /* v8 is now 0x00000000000000870000000000000087 reflected 0xe1....*/ + "PMULL2 v5.1q, v4.2d, v8.2d \n" + "EXT v6.16b, v5.16b, v7.16b, #8 \n" /* v7 is all 0's */ + "EOR v4.16b, v4.16b, v6.16b \n" + "EXT v6.16b, v7.16b, v5.16b, #8 \n" + "EOR v3.16b, v3.16b, v6.16b \n" + "PMULL v5.1q, v4.1d, v8.1d \n" + "EOR v4.16b, v3.16b, v5.16b \n" + + "RBIT v4.16b, v4.16b \n" + "STR q4, [%[out]] \n" + : [out] "=r" (Xpt), "=r" (Ypt) + : [inX] "0" (Xpt), [inY] "1" (Ypt) + : "cc", "memory", "v3", "v4", "v5", "v6", "v7", "v8" + ); +} + + +/* Currently is a copy from GCM_SMALL wolfSSL version. Duplicated and set + * seperate for future optimizations. */ +static void GHASH(Aes* aes, const byte* a, word32 aSz, + const byte* c, word32 cSz, byte* s, word32 sSz) +{ + byte x[AES_BLOCK_SIZE]; + byte scratch[AES_BLOCK_SIZE]; + word32 blocks, partial; + byte* h = aes->H; + + XMEMSET(x, 0, AES_BLOCK_SIZE); + + /* Hash in A, the Additional Authentication Data */ + if (aSz != 0 && a != NULL) { + blocks = aSz / AES_BLOCK_SIZE; + partial = aSz % AES_BLOCK_SIZE; + while (blocks--) { + xorbuf(x, a, AES_BLOCK_SIZE); + GMULT(x, h); + a += AES_BLOCK_SIZE; + } + if (partial != 0) { + XMEMSET(scratch, 0, AES_BLOCK_SIZE); + XMEMCPY(scratch, a, partial); + xorbuf(x, scratch, AES_BLOCK_SIZE); + GMULT(x, h); + } + } + + /* Hash in C, the Ciphertext */ + if (cSz != 0 && c != NULL) { + blocks = cSz / AES_BLOCK_SIZE; + partial = cSz % AES_BLOCK_SIZE; + while (blocks--) { + xorbuf(x, c, AES_BLOCK_SIZE); + GMULT(x, h); + c += AES_BLOCK_SIZE; + } + if (partial != 0) { + XMEMSET(scratch, 0, AES_BLOCK_SIZE); + XMEMCPY(scratch, c, partial); + xorbuf(x, scratch, AES_BLOCK_SIZE); + GMULT(x, h); + } + } + + /* Hash in the lengths of A and C in bits */ + FlattenSzInBits(&scratch[0], aSz); + FlattenSzInBits(&scratch[8], cSz); + xorbuf(x, scratch, AES_BLOCK_SIZE); + GMULT(x, h); + + /* Copy the result into s. */ + XMEMCPY(s, x, sSz); +} +/* not using ARMASM for multiplication */ +#elif defined(GCM_SMALL) static void GMULT(byte* X, byte* Y) { byte Z[AES_BLOCK_SIZE]; @@ -3909,8 +4326,6 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte *ctr ; byte scratch[AES_BLOCK_SIZE]; - WOLFSSL_ENTER("AesGcmEncrypt"); - #ifdef WOLFSSL_AESNI if (haveAESNI) { AES_GCM_encrypt((void*)in, out, (void*)authIn, (void*)iv, authTag, @@ -3982,8 +4397,6 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte *ctr ; byte scratch[AES_BLOCK_SIZE]; - WOLFSSL_ENTER("AesGcmDecrypt"); - #ifdef WOLFSSL_AESNI if (haveAESNI) { if (AES_GCM_decrypt(in, out, authIn, iv, authTag, @@ -4323,131 +4736,28 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, #endif /* HAVE_AESCCM */ -#ifdef HAVE_CAVIUM - -#include -#include "cavium_common.h" - +#ifdef WOLFSSL_ASYNC_CRYPT + /* Initialize Aes for use with Nitrox device */ -int wc_AesInitCavium(Aes* aes, int devId) +int wc_AesAsyncInit(Aes* aes, int devId) { if (aes == NULL) - return -1; + return BAD_FUNC_ARG; - if (CspAllocContext(CONTEXT_SSL, &aes->contextHandle, devId) != 0) - return -1; - - aes->devId = devId; - aes->magic = WOLFSSL_AES_CAVIUM_MAGIC; - - return 0; + return wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES, devId); } /* Free Aes from use with Nitrox device */ -void wc_AesFreeCavium(Aes* aes) +void wc_AesAsyncFree(Aes* aes) { if (aes == NULL) return; - if (aes->magic != WOLFSSL_AES_CAVIUM_MAGIC) - return; - - CspFreeContext(CONTEXT_SSL, aes->contextHandle, aes->devId); - aes->magic = 0; + wolfAsync_DevCtxFree(&aes->asyncDev); } - -static int wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length, - const byte* iv) -{ - if (aes == NULL) - return -1; - - XMEMCPY(aes->key, key, length); /* key still holds key, iv still in reg */ - if (length == 16) - aes->type = AES_128; - else if (length == 24) - aes->type = AES_192; - else if (length == 32) - aes->type = AES_256; - - return wc_AesSetIV(aes, iv); -} - -#ifdef HAVE_AES_CBC -static int wc_AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in, - word32 length) -{ - wolfssl_word offset = 0; - word32 requestId; - - while (length > WOLFSSL_MAX_16BIT) { - word16 slen = (word16)WOLFSSL_MAX_16BIT; - if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, - aes->type, slen, (byte*)in + offset, out + offset, - (byte*)aes->reg, (byte*)aes->key, &requestId, - aes->devId) != 0) { - WOLFSSL_MSG("Bad Cavium Aes Encrypt"); - return -1; - } - length -= WOLFSSL_MAX_16BIT; - offset += WOLFSSL_MAX_16BIT; - XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - } - if (length) { - word16 slen = (word16)length; - if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, - aes->type, slen, (byte*)in + offset, out + offset, - (byte*)aes->reg, (byte*)aes->key, &requestId, - aes->devId) != 0) { - WOLFSSL_MSG("Bad Cavium Aes Encrypt"); - return -1; - } - XMEMCPY(aes->reg, out + offset+length - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - } - return 0; -} - -#ifdef HAVE_AES_DECRYPT -static int wc_AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, - word32 length) -{ - word32 requestId; - wolfssl_word offset = 0; - - while (length > WOLFSSL_MAX_16BIT) { - word16 slen = (word16)WOLFSSL_MAX_16BIT; - XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, - aes->type, slen, (byte*)in + offset, out + offset, - (byte*)aes->reg, (byte*)aes->key, &requestId, - aes->devId) != 0) { - WOLFSSL_MSG("Bad Cavium Aes Decrypt"); - return -1; - } - length -= WOLFSSL_MAX_16BIT; - offset += WOLFSSL_MAX_16BIT; - XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); - } - if (length) { - word16 slen = (word16)length; - XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, - aes->type, slen, (byte*)in + offset, out + offset, - (byte*)aes->reg, (byte*)aes->key, &requestId, - aes->devId) != 0) { - WOLFSSL_MSG("Bad Cavium Aes Decrypt"); - return -1; - } - XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); - } - return 0; -} -#endif /* HAVE_AES_DECRYPT */ -#endif /* HAVE_AES_CBC */ - -#endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ #endif /* WOLFSSL_TI_CRYPT */ diff --git a/wolfcrypt/src/arc4.c b/wolfcrypt/src/arc4.c index a30d111173..6922089de2 100644 --- a/wolfcrypt/src/arc4.c +++ b/wolfcrypt/src/arc4.c @@ -28,23 +28,19 @@ #ifndef NO_RC4 +#include #include -#ifdef HAVE_CAVIUM - static void wc_Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length); - static void wc_Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in, - word32 length); -#endif - void wc_Arc4SetKey(Arc4* arc4, const byte* key, word32 length) { word32 i; word32 keyIndex = 0, stateIndex = 0; -#ifdef HAVE_CAVIUM - if (arc4->magic == WOLFSSL_ARC4_CAVIUM_MAGIC) - return wc_Arc4CaviumSetKey(arc4, key, length); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V) + if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) { + return NitroxArc4SetKey(arc4, key, length); + } #endif arc4->x = 1; @@ -85,9 +81,10 @@ void wc_Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) word32 x; word32 y; -#ifdef HAVE_CAVIUM - if (arc4->magic == WOLFSSL_ARC4_CAVIUM_MAGIC) - return wc_Arc4CaviumProcess(arc4, out, in, length); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V) + if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) { + return NitroxArc4Process(arc4, out, in, length); + } #endif x = arc4->x; @@ -101,79 +98,28 @@ void wc_Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) } -#ifdef HAVE_CAVIUM - -#include -#include "cavium_common.h" +#ifdef WOLFSSL_ASYNC_CRYPT /* Initialize Arc4 for use with Nitrox device */ -int wc_Arc4InitCavium(Arc4* arc4, int devId) +int wc_Arc4AsyncInit(Arc4* arc4, int devId) { if (arc4 == NULL) - return -1; + return BAD_FUNC_ARG; - if (CspAllocContext(CONTEXT_SSL, &arc4->contextHandle, devId) != 0) - return -1; - - arc4->devId = devId; - arc4->magic = WOLFSSL_ARC4_CAVIUM_MAGIC; - - return 0; + return wolfAsync_DevCtxInit(&arc4->asyncDev, WOLFSSL_ASYNC_MARKER_ARC4, devId); } /* Free Arc4 from use with Nitrox device */ -void wc_Arc4FreeCavium(Arc4* arc4) +void wc_Arc4AsyncFree(Arc4* arc4) { if (arc4 == NULL) return; - if (arc4->magic != WOLFSSL_ARC4_CAVIUM_MAGIC) - return; - - CspFreeContext(CONTEXT_SSL, arc4->contextHandle, arc4->devId); - arc4->magic = 0; + wolfAsync_DevCtxFree(&arc4->asyncDev); } - -static void wc_Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length) -{ - word32 requestId; - - if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->contextHandle, length, - (byte*)key, &requestId, arc4->devId) != 0) { - WOLFSSL_MSG("Bad Cavium Arc4 Init"); - } -} - - -static void wc_Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in, - word32 length) -{ - wolfssl_word offset = 0; - word32 requestId; - - while (length > WOLFSSL_MAX_16BIT) { - word16 slen = (word16)WOLFSSL_MAX_16BIT; - if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE, - slen, (byte*)in + offset, out + offset, &requestId, - arc4->devId) != 0) { - WOLFSSL_MSG("Bad Cavium Arc4 Encrypt"); - } - length -= WOLFSSL_MAX_16BIT; - offset += WOLFSSL_MAX_16BIT; - } - if (length) { - word16 slen = (word16)length; - if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE, - slen, (byte*)in + offset, out + offset, &requestId, - arc4->devId) != 0) { - WOLFSSL_MSG("Bad Cavium Arc4 Encrypt"); - } - } -} - -#endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ #endif /* NO_RC4 */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index cc2a856dcf..d8e22ac341 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -646,7 +646,7 @@ static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version) } #endif /* !NO_ASN_TIME */ -WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, +int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx) { word32 i = *inOutIdx; @@ -676,6 +676,65 @@ WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, return 0; } +#if !defined(NO_RSA) && !defined(HAVE_USER_RSA) +static int GetIntRsa(RsaKey* key, mp_int* mpi, const byte* input, + word32* inOutIdx, word32 maxIdx) +{ + word32 i = *inOutIdx; + byte b = input[i++]; + int length; + + (void)key; + + if (b != ASN_INTEGER) + return ASN_PARSE_E; + + if (GetLength(input, &i, &length, maxIdx) < 0) + return ASN_PARSE_E; + + if (length > 0) { + /* remove leading zero */ + if ( (b = input[i++]) == 0x00) + length--; + else + i--; + } + +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + XMEMSET(mpi, 0, sizeof(mp_int)); + mpi->used = length; + #ifdef USE_FAST_MATH + if (length > (FP_SIZE * (int)sizeof(fp_digit))) { + return MEMORY_E; + } + mpi->dpraw = (byte*)mpi->dp; + #else + mpi->dpraw = (byte*)XMALLOC(length, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + #endif + if (mpi->dpraw == NULL) { + return MEMORY_E; + } + + XMEMCPY(mpi->dpraw, input + i, length); + } + else +#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM */ + { + if (mp_init(mpi) != MP_OKAY) + return MP_INIT_E; + + if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) { + mp_clear(mpi); + return ASN_GETINT_E; + } + } + + *inOutIdx = i + length; + return 0; +} +#endif /* !NO_RSA && !HAVE_USER_RSA */ + /* hashType */ static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2}; @@ -1297,78 +1356,11 @@ WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, #ifndef NO_RSA - -#ifdef HAVE_CAVIUM - -static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input, - word32* inOutIdx, word32 maxIdx, void* heap) -{ - word32 i = *inOutIdx; - byte b = input[i++]; - int length; - - if (b != ASN_INTEGER) - return ASN_PARSE_E; - - if (GetLength(input, &i, &length, maxIdx) < 0) - return ASN_PARSE_E; - - if ( (b = input[i++]) == 0x00) - length--; - else - i--; - - *buffSz = (word16)length; - *buff = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA); - if (*buff == NULL) - return MEMORY_E; - - XMEMCPY(*buff, input + i, *buffSz); - - *inOutIdx = i + length; - return 0; -} - -static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx, - RsaKey* key, word32 inSz) -{ - int version, length; - void* h = key->heap; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetMyVersion(input, inOutIdx, &version) < 0) - return ASN_PARSE_E; - - key->type = RSA_PRIVATE; - - if (GetCaviumInt(&key->c_n, &key->c_nSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_e, &key->c_eSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_d, &key->c_dSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_p, &key->c_pSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_q, &key->c_qSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_u, &key->c_uSz, input, inOutIdx, inSz, h) < 0 ) - return ASN_RSA_KEY_E; - - return 0; -} - - -#endif /* HAVE_CAVIUM */ - #ifndef HAVE_USER_RSA int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, word32 inSz) { - int version, length; - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz); -#endif + int version, length; if (GetSequence(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; @@ -1378,14 +1370,14 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, key->type = RSA_PRIVATE; - if (GetInt(&key->n, input, inOutIdx, inSz) < 0 || - GetInt(&key->e, input, inOutIdx, inSz) < 0 || - GetInt(&key->d, input, inOutIdx, inSz) < 0 || - GetInt(&key->p, input, inOutIdx, inSz) < 0 || - GetInt(&key->q, input, inOutIdx, inSz) < 0 || - GetInt(&key->dP, input, inOutIdx, inSz) < 0 || - GetInt(&key->dQ, input, inOutIdx, inSz) < 0 || - GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E; + if (GetIntRsa(key, &key->n, input, inOutIdx, inSz) < 0 || + GetIntRsa(key, &key->e, input, inOutIdx, inSz) < 0 || + GetIntRsa(key, &key->d, input, inOutIdx, inSz) < 0 || + GetIntRsa(key, &key->p, input, inOutIdx, inSz) < 0 || + GetIntRsa(key, &key->q, input, inOutIdx, inSz) < 0 || + GetIntRsa(key, &key->dP, input, inOutIdx, inSz) < 0 || + GetIntRsa(key, &key->dQ, input, inOutIdx, inSz) < 0 || + GetIntRsa(key, &key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E; return 0; } @@ -3674,11 +3666,22 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, else { XMEMCPY(plain, sig, sigSz); - if ((verifySz = wc_RsaSSL_VerifyInline(plain, sigSz, &out, - pubKey)) < 0) { + ret = 0; + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, pubKey); + #endif + if (ret >= 0) { + ret = wc_RsaSSL_VerifyInline(plain, sigSz, &out, + pubKey); + } + } while (ret == WC_PENDING_E); + + if (ret < 0) { WOLFSSL_MSG("Rsa SSL verify error"); } else { + verifySz = ret; /* make sure we're right justified */ encodedSigSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH); @@ -5071,7 +5074,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } #endif - if (verify && type != CA_TYPE && type != TRUSTED_PEER_TYPE) { + if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) { Signer* ca = NULL; #ifndef NO_SKID if (cert->extAuthKeyIdSet) @@ -5096,23 +5099,26 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) if (ret != 0) return ret; #endif /* HAVE_OCSP */ - /* try to confirm/verify signature */ - if (!ConfirmSignature(cert->source + cert->certBegin, - cert->sigIndex - cert->certBegin, - ca->publicKey, ca->pubKeySize, ca->keyOID, - cert->signature, cert->sigLength, cert->signatureOID, - cert->heap)) { - WOLFSSL_MSG("Confirm signature failed"); - return ASN_SIG_CONFIRM_E; + + if (verify == VERIFY) { + /* try to confirm/verify signature */ + if (!ConfirmSignature(cert->source + cert->certBegin, + cert->sigIndex - cert->certBegin, + ca->publicKey, ca->pubKeySize, ca->keyOID, + cert->signature, cert->sigLength, cert->signatureOID, + cert->heap)) { + WOLFSSL_MSG("Confirm signature failed"); + return ASN_SIG_CONFIRM_E; + } + #ifndef IGNORE_NAME_CONSTRAINTS + /* check that this cert's name is permitted by the signer's + * name constraints */ + if (!ConfirmNameConstraints(ca, cert)) { + WOLFSSL_MSG("Confirm name constraint failed"); + return ASN_NAME_INVALID_E; + } + #endif /* IGNORE_NAME_CONSTRAINTS */ } -#ifndef IGNORE_NAME_CONSTRAINTS - /* check that this cert's name is permitted by the signer's - * name constraints */ - if (!ConfirmNameConstraints(ca, cert)) { - WOLFSSL_MSG("Confirm name constraint failed"); - return ASN_NAME_INVALID_E; - } -#endif /* IGNORE_NAME_CONSTRAINTS */ } else { /* no signer */ @@ -5569,7 +5575,7 @@ static int SetRsaPublicKey(byte* output, RsaKey* key, n[0] = ASN_INTEGER; nSz = SetLength(rawLen, n + 1) + 1; /* int tag */ - if ( (nSz + rawLen) < MAX_RSA_INT_SZ) { + if ( (nSz + rawLen) <= MAX_RSA_INT_SZ) { if (leadingBit) n[nSz] = 0; #ifdef HAVE_USER_RSA @@ -7359,7 +7365,15 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, if (rsaKey) { /* signature */ encSigSz = wc_EncodeSignature(encSig, digest, digestSz, typeH); - ret = wc_RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng); + ret = 0; + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, rsaKey); +#endif + if (ret >= 0) { + ret = wc_RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng); + } + } while (ret == WC_PENDING_E); } #endif diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index bac3e90a76..2f9bd34d0b 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -31,13 +31,6 @@ #include #ifdef HAVE_FIPS -#ifdef HAVE_CAVIUM - static int wc_Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv); - static int wc_Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in, - word32 length); - static int wc_Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in, - word32 length); -#endif int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) { @@ -98,23 +91,24 @@ int wc_Des3_SetIV(Des3* des, const byte* iv) } -#ifdef HAVE_CAVIUM +#ifdef WOLFSSL_ASYNC_CRYPT /* Initialize Des3 for use with Nitrox device */ -int wc_Des3_InitCavium(Des3* des3, int devId) +int wc_Des3AsyncInit(Des3* des3, int devId) { - return Des3_InitCavium(des3, devId); + return Des3AsyncInit(des3, devId); } /* Free Des3 from use with Nitrox device */ -void wc_Des3_FreeCavium(Des3* des3) +void wc_Des3AsyncFree(Des3* des3) { - Des3_FreeCavium(des3); + Des3AsyncFree(des3); } -#endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ + #else /* build without fips */ #if defined(WOLFSSL_TI_CRYPT) @@ -132,17 +126,6 @@ void wc_Des3_FreeCavium(Des3* des3) #endif -#ifdef HAVE_CAVIUM - static int wc_Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv); - static int wc_Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in, - word32 length); - static int wc_Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in, - word32 length); -#endif - - - - #ifdef STM32F2_CRYPTO /* * STM32F2 hardware DES/3DES support through the STM32F2 standard @@ -150,7 +133,7 @@ void wc_Des3_FreeCavium(Des3* des3) * Peripheral Library document (See note in README). */ #include "stm32f2xx.h" - #include "stm32f2xx_cryp.h" + #include "stm32f2xx_cryp.h" int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) { @@ -1292,9 +1275,10 @@ int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) { int ret; -#ifdef HAVE_CAVIUM - if (des->magic == WOLFSSL_3DES_CAVIUM_MAGIC) - return wc_Des3_CaviumSetKey(des, key, iv); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES) { + return NitroxDes3SetKey(des, key, iv); + } #endif ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]); @@ -1433,9 +1417,10 @@ int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) { word32 blocks; -#ifdef HAVE_CAVIUM - if (des->magic == WOLFSSL_3DES_CAVIUM_MAGIC) - return wc_Des3_CaviumCbcEncrypt(des, out, in, sz); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES) { + return NitroxDes3CbcEncrypt(des, out, in, sz); + } #endif blocks = sz / DES_BLOCK_SIZE; @@ -1455,9 +1440,10 @@ int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) { word32 blocks; -#ifdef HAVE_CAVIUM - if (des->magic == WOLFSSL_3DES_CAVIUM_MAGIC) - return wc_Des3_CaviumCbcDecrypt(des, out, in, sz); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES) { + return NitroxDes3CbcDecrypt(des, out, in, sz); + } #endif blocks = sz / DES_BLOCK_SIZE; @@ -1513,122 +1499,29 @@ int wc_Des3_SetIV(Des3* des, const byte* iv) } -#ifdef HAVE_CAVIUM - -#include "cavium_common.h" +#ifdef WOLFSSL_ASYNC_CRYPT /* Initialize Des3 for use with Nitrox device */ -int wc_Des3_InitCavium(Des3* des3, int devId) +int wc_Des3AsyncInit(Des3* des3, int devId) { if (des3 == NULL) - return -1; + return BAD_FUNC_ARG; - if (CspAllocContext(CONTEXT_SSL, &des3->contextHandle, devId) != 0) - return -1; - - des3->devId = devId; - des3->magic = WOLFSSL_3DES_CAVIUM_MAGIC; - - return 0; + return wolfAsync_DevCtxInit(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES, devId); } /* Free Des3 from use with Nitrox device */ -void wc_Des3_FreeCavium(Des3* des3) +void wc_Des3AsyncFree(Des3* des3) { if (des3 == NULL) return; - if (des3->magic != WOLFSSL_3DES_CAVIUM_MAGIC) - return; - - CspFreeContext(CONTEXT_SSL, des3->contextHandle, des3->devId); - des3->magic = 0; + wolfAsync_DevCtxFree(&des3->asyncDev); } +#endif /* WOLFSSL_ASYNC_CRYPT */ -static int wc_Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv) -{ - if (des3 == NULL) - return -1; - - /* key[0] holds key, iv in reg */ - XMEMCPY(des3->key[0], key, DES_BLOCK_SIZE*3); - - return wc_Des3_SetIV(des3, iv); -} - - -static int wc_Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in, - word32 length) -{ - wolfssl_word offset = 0; - word32 requestId; - - while (length > WOLFSSL_MAX_16BIT) { - word16 slen = (word16)WOLFSSL_MAX_16BIT; - if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle, - CAVIUM_NO_UPDATE, slen, (byte*)in + offset, - out + offset, (byte*)des3->reg, (byte*)des3->key[0], - &requestId, des3->devId) != 0) { - WOLFSSL_MSG("Bad Cavium 3DES Cbc Encrypt"); - return -1; - } - length -= WOLFSSL_MAX_16BIT; - offset += WOLFSSL_MAX_16BIT; - XMEMCPY(des3->reg, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE); - } - if (length) { - word16 slen = (word16)length; - - if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle, - CAVIUM_NO_UPDATE, slen, (byte*)in + offset, - out + offset, (byte*)des3->reg, (byte*)des3->key[0], - &requestId, des3->devId) != 0) { - WOLFSSL_MSG("Bad Cavium 3DES Cbc Encrypt"); - return -1; - } - XMEMCPY(des3->reg, out+offset+length - DES_BLOCK_SIZE, DES_BLOCK_SIZE); - } - return 0; -} - -static int wc_Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in, - word32 length) -{ - word32 requestId; - wolfssl_word offset = 0; - - while (length > WOLFSSL_MAX_16BIT) { - word16 slen = (word16)WOLFSSL_MAX_16BIT; - XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE, DES_BLOCK_SIZE); - if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle, - CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset, - (byte*)des3->reg, (byte*)des3->key[0], &requestId, - des3->devId) != 0) { - WOLFSSL_MSG("Bad Cavium 3Des Decrypt"); - return -1; - } - length -= WOLFSSL_MAX_16BIT; - offset += WOLFSSL_MAX_16BIT; - XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE); - } - if (length) { - word16 slen = (word16)length; - XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE,DES_BLOCK_SIZE); - if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle, - CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset, - (byte*)des3->reg, (byte*)des3->key[0], &requestId, - des3->devId) != 0) { - WOLFSSL_MSG("Bad Cavium 3Des Decrypt"); - return -1; - } - XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE); - } - return 0; -} - -#endif /* HAVE_CAVIUM */ #endif /* WOLFSSL_TI_CRYPT */ #endif /* HAVE_FIPS */ #endif /* NO_DES3 */ diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 3f7e88c2a6..19aeb2de04 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -436,7 +436,7 @@ const ecc_set_type ecc_sets[] = { "9487239995A5EE76B55F9C2F098", /* Gx */ "A89CE5AF8724C0A23E0E0FF77500", /* Gy */ ecc_oid_secp112r1, /* oid/oidSz */ - sizeof(ecc_oid_secp112r1) / sizeof(ecc_oid_t), + sizeof(ecc_oid_secp112r1) / sizeof(ecc_oid_t), ECC_SECP112R1_OID, /* oid sum */ 1, /* cofactor */ }, @@ -805,7 +805,7 @@ const ecc_set_type ecc_sets[] = { "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ ecc_oid_brainpoolp256r1, /* oid/oidSz */ - sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t), + sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t), ECC_BRAINPOOLP256R1_OID, /* oid sum */ 1, /* cofactor */ }, @@ -936,7 +936,7 @@ static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id) { - if (keysize <=0 && curve_id <= 0) { + if (keysize <= 0 && curve_id <= 0) { return BAD_FUNC_ARG; } @@ -1037,12 +1037,12 @@ int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, return ecc_projective_dbl_point(P, R, a, modulus, mp); } } - + if (err != MP_OKAY) { goto done; } -/* If use ALT_ECC_SIZE we need to use local stack variable since +/* If use ALT_ECC_SIZE we need to use local stack variable since ecc_point x,y,z is reduced size */ #ifdef ALT_ECC_SIZE /* Use local stack variable */ @@ -1312,7 +1312,7 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, return err; } -/* If use ALT_ECC_SIZE we need to use local stack variable since +/* If use ALT_ECC_SIZE we need to use local stack variable since ecc_point x,y,z is reduced size */ #ifdef ALT_ECC_SIZE /* Use local stack variable */ @@ -1571,7 +1571,7 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { goto done; } - + if (err == MP_OKAY) err = mp_copy(P->x, x); if (err == MP_OKAY) @@ -1871,11 +1871,34 @@ int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, { return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL); } -#endif /* ! FP_ECC */ +#endif /* !FP_ECC */ #undef WINSIZE #else /* ECC_TIMING_RESISTANT */ + +#ifndef WC_NO_CACHE_RESISTANT +#if defined(TFM_TIMING_RESISTANT) && defined(USE_FAST_MATH) + /* let's use the one we already have */ + extern const wolfssl_word wc_off_on_addr[2]; +#else + static const wolfssl_word wc_off_on_addr[2] = + { + #if defined(WC_64BIT_CPU) + W64LIT(0x0000000000000000), + W64LIT(0xffffffffffffffff) + #elif defined(WC_16BIT_CPU) + 0x0000U, + 0xffffU + #else + /* 32 bit */ + 0x00000000U, + 0xffffffffU + #endif + }; +#endif /* TFM_TIMING_RESISTANT && USE_FAST_MATH */ +#endif /* WC_NO_CACHE_RESISTANT */ + /** Perform a point multiplication (timing resistant) k The scalar to multiply by @@ -1979,7 +2002,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, break; } buf = get_digit(k, digidx); - bitcnt = (int) DIGIT_BIT; + bitcnt = (int)DIGIT_BIT; --digidx; } @@ -2013,10 +2036,49 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, if (err == MP_OKAY) err = ecc_projective_add_point(M[0], M[1], M[i^1], a, modulus, mp); +#ifdef WC_NO_CACHE_RESISTANT if (err == MP_OKAY) err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp); +#else + /* instead of using M[i] for double, which leaks key bit to cache + * monitor, use M[2] as temp, make sure address calc is constant, + * keep &M[0] and &M[1] in cache */ + if (err == MP_OKAY) + err = mp_copy((mp_int*) + ( ((wolfssl_word)&M[0]->x & wc_off_on_addr[i^1]) + + ((wolfssl_word)&M[1]->x & wc_off_on_addr[i])), + M[2]->x); + if (err == MP_OKAY) + err = mp_copy((mp_int*) + ( ((wolfssl_word)&M[0]->y & wc_off_on_addr[i^1]) + + ((wolfssl_word)&M[1]->y & wc_off_on_addr[i])), + M[2]->y); + if (err == MP_OKAY) + err = mp_copy((mp_int*) + ( ((wolfssl_word)&M[0]->z & wc_off_on_addr[i^1]) + + ((wolfssl_word)&M[1]->z & wc_off_on_addr[i])), + M[2]->z); + if (err == MP_OKAY) + err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp); + /* copy M[2] back to M[i] */ + if (err == MP_OKAY) + err = mp_copy(M[2]->x, + (mp_int*) + ( ((wolfssl_word)&M[0]->x & wc_off_on_addr[i^1]) + + ((wolfssl_word)&M[1]->x & wc_off_on_addr[i])) ); + if (err == MP_OKAY) + err = mp_copy(M[2]->y, + (mp_int*) + ( ((wolfssl_word)&M[0]->y & wc_off_on_addr[i^1]) + + ((wolfssl_word)&M[1]->y & wc_off_on_addr[i])) ); + if (err == MP_OKAY) + err = mp_copy(M[2]->z, + (mp_int*) + ( ((wolfssl_word)&M[0]->z & wc_off_on_addr[i^1]) + + ((wolfssl_word)&M[1]->z & wc_off_on_addr[i])) ); if (err != MP_OKAY) break; +#endif /* WC_NO_CACHE_RESISTANT */ } /* end for */ } @@ -2223,8 +2285,9 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, int err; if (private_key == NULL || public_key == NULL || out == NULL || - outlen == NULL) + outlen == NULL) { return BAD_FUNC_ARG; + } /* type valid? */ if (private_key->type != ECC_PRIVATEKEY) { @@ -2242,6 +2305,24 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, return ECC_BAD_ARG_E; } +#ifdef WOLFSSL_ASYNC_CRYPT + if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { + #ifdef HAVE_CAVIUM + /* TODO: Not implemented */ + #else + AsyncCryptTestDev* testDev = &private_key->asyncDev.dev; + if (testDev->type == ASYNC_TEST_NONE) { + testDev->type = ASYNC_TEST_ECC_SHARED_SEC; + testDev->eccSharedSec.private_key = private_key; + testDev->eccSharedSec.public_key = public_key; + testDev->eccSharedSec.out = out; + testDev->eccSharedSec.outLen = outlen; + return WC_PENDING_E; + } + #endif + } +#endif + /* make new point */ result = wc_ecc_new_point_h(private_key->heap); if (result == NULL) { @@ -2302,8 +2383,10 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point, mp_int a; int err; - if (private_key == NULL || point == NULL || out == NULL || outlen == NULL) + if (private_key == NULL || point == NULL || out == NULL || + outlen == NULL) { return BAD_FUNC_ARG; + } /* type valid? */ if (private_key->type != ECC_PRIVATEKEY) { @@ -2391,6 +2474,24 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) return err; } +#ifdef WOLFSSL_ASYNC_CRYPT + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { + #ifdef HAVE_CAVIUM + /* TODO: Not implemented */ + #else + AsyncCryptTestDev* testDev = &key->asyncDev.dev; + if (testDev->type == ASYNC_TEST_NONE) { + testDev->type = ASYNC_TEST_ECC_MAKE; + testDev->eccMake.rng = rng; + testDev->eccMake.key = key; + testDev->eccMake.size = keysize; + testDev->eccMake.curve_id = curve_id; + return WC_PENDING_E; + } + #endif + } +#endif + #ifdef WOLFSSL_SMALL_STACK buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buf == NULL) @@ -2567,13 +2668,18 @@ int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF); } -/* Setup dynamic pointers is using normal math for proper freeing */ -int wc_ecc_init(ecc_key* key) + +/* Setup dynamic pointers if using normal math for proper freeing */ +int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) { + int ret = 0; + if (key == NULL) { return BAD_FUNC_ARG; } + (void)devId; + #ifdef ECC_DUMP_OID wc_ecc_dump_oids(); #endif @@ -2590,8 +2696,9 @@ int wc_ecc_init(ecc_key* key) #endif #ifdef ALT_ECC_SIZE - if (mp_init(&key->k) != MP_OKAY) + if (mp_init(&key->k) != MP_OKAY) { return MEMORY_E; + } key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; @@ -2604,26 +2711,26 @@ int wc_ecc_init(ecc_key* key) #ifdef WOLFSSL_HEAP_TEST key->heap = (void*)WOLFSSL_HEAP_TEST; #else - key->heap = NULL; + key->heap = heap; #endif - return MP_OKAY; -} - - -int wc_ecc_init_h(ecc_key* key, void* heap) -{ - int ret; - - if ((ret = wc_ecc_init(key)) != MP_OKAY) { - return ret; +#ifdef WOLFSSL_ASYNC_CRYPT + if (devId != INVALID_DEVID) { + /* handle as async */ + ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC, + devId); } +#endif - key->heap = heap; - - return MP_OKAY; + return ret; } +int wc_ecc_init(ecc_key* key) +{ + return wc_ecc_init_ex(key, NULL, INVALID_DEVID); +} + + #ifdef HAVE_ECC_SIGN #ifndef NO_ASN @@ -2644,16 +2751,40 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, int err; if (in == NULL || out == NULL || outlen == NULL || - key == NULL || rng == NULL) + key == NULL || rng == NULL) { return ECC_BAD_ARG_E; + } + + +#ifdef WOLFSSL_ASYNC_CRYPT + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { + #ifdef HAVE_CAVIUM + /* TODO: Not implemented */ + #else + AsyncCryptTestDev* testDev = &key->asyncDev.dev; + if (testDev->type == ASYNC_TEST_NONE) { + testDev->type = ASYNC_TEST_ECC_SIGN; + testDev->eccSign.in = in; + testDev->eccSign.inSz = inlen; + testDev->eccSign.out = out; + testDev->eccSign.outSz = outlen; + testDev->eccSign.rng = rng; + testDev->eccSign.key = key; + return WC_PENDING_E; + } + #endif + } +#endif if ((err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL)) != MP_OKAY) { return err; } err = wc_ecc_sign_hash_ex(in, inlen, rng, key, &r, &s); - if (err == MP_OKAY) + if (err == MP_OKAY) { + /* encoded with DSA header */ err = StoreECC_DSA_Sig(out, outlen, &r, &s); + } #ifndef USE_FAST_MATH mp_clear(&r); @@ -2780,8 +2911,15 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, */ void wc_ecc_free(ecc_key* key) { - if (key == NULL) + if (key == NULL) { return; + } + +#ifdef WOLFSSL_ASYNC_CRYPT + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + wolfAsync_DevCtxFree(&key->asyncDev); + } +#endif mp_clear(key->pubkey.x); mp_clear(key->pubkey.y); @@ -3048,12 +3186,33 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, mp_int s; int err; - if (sig == NULL || hash == NULL || stat == NULL || key == NULL) + if (sig == NULL || hash == NULL || stat == NULL || key == NULL) { return ECC_BAD_ARG_E; + } /* default to invalid signature */ *stat = 0; +#ifdef WOLFSSL_ASYNC_CRYPT + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { + #ifdef HAVE_CAVIUM + /* TODO: Not implemented */ + #else + AsyncCryptTestDev* testDev = &key->asyncDev.dev; + if (testDev->type == ASYNC_TEST_NONE) { + testDev->type = ASYNC_TEST_ECC_VERIFY; + testDev->eccVerify.in = sig; + testDev->eccVerify.inSz = siglen; + testDev->eccVerify.out = hash; + testDev->eccVerify.outSz = hashlen; + testDev->eccVerify.stat = stat; + testDev->eccVerify.key = key; + return WC_PENDING_E; + } + #endif + } +#endif + /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. * If either of those don't allocate correctly, none of * the rest of this function will execute, and everything @@ -3689,7 +3848,7 @@ static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime, if (inf == NULL) err = MEMORY_E; else { - err = wc_ecc_mulmod_ex(order, &key->pubkey, inf, a, prime, 1, + err = wc_ecc_mulmod_ex(order, &key->pubkey, inf, a, prime, 1, key->heap); if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf)) err = ECC_INF_E; @@ -5680,7 +5839,7 @@ int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) ctx->cliSt = ecCLI_SALT_SET; else { ctx->cliSt = ecCLI_BAD_STATE; - return BAD_ENC_STATE_E; + return BAD_STATE_E; } } else { @@ -5689,7 +5848,7 @@ int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) ctx->srvSt = ecSRV_SALT_SET; else { ctx->srvSt = ecSRV_BAD_STATE; - return BAD_ENC_STATE_E; + return BAD_STATE_E; } } @@ -5871,13 +6030,13 @@ int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, keysLen *= 2; if (ctx->srvSt != ecSRV_RECV_REQ) - return BAD_ENC_STATE_E; + return BAD_STATE_E; ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ } else if (ctx->protocol == REQ_RESP_CLIENT) { if (ctx->cliSt != ecCLI_SALT_SET) - return BAD_ENC_STATE_E; + return BAD_STATE_E; ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */ } @@ -6023,13 +6182,13 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, keysLen *= 2; if (ctx->cliSt != ecCLI_SENT_REQ) - return BAD_ENC_STATE_E; + return BAD_STATE_E; ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ } else if (ctx->protocol == REQ_RESP_SERVER) { if (ctx->srvSt != ecSRV_SALT_SET) - return BAD_ENC_STATE_E; + return BAD_STATE_E; ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */ } @@ -6518,7 +6677,7 @@ int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp) return BAD_FUNC_ARG; } - key->idx = WOLFSSL_CUSTOM_CURVES; + key->idx = ECC_CUSTOM_IDX; key->dp = dp; return 0; @@ -6526,4 +6685,50 @@ int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp) #endif /* WOLFSSL_CUSTOM_CURVES */ +#ifdef WOLFSSL_ASYNC_CRYPT + +int wc_ecc_async_handle(ecc_key* key, WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) +{ + int ret; + + if (key == NULL || queue == NULL || event == NULL) { + return BAD_FUNC_ARG; + } + + /* make sure this ECC context had "wc_EccAsyncInit" called on it */ + if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) { + return ASYNC_INIT_E; + } + + /* setup the event and push to queue */ + ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &key->asyncDev); + if (ret == 0) { + ret = wolfEventQueue_Push(queue, event); + } + + /* check for error (helps with debugging) */ + if (ret != 0) { + WOLFSSL_MSG("wc_EccAsyncHandle failed"); + } + return ret; +} + +int wc_ecc_async_wait(int ret, ecc_key* key) +{ + if (ret == WC_PENDING_E) { + WOLF_EVENT event; + XMEMSET(&event, 0, sizeof(event)); + ret = wolfAsync_EventInit(&event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &key->asyncDev); + if (ret == 0) { + ret = wolfAsync_EventWait(&event); + if (ret == 0 && event.ret >= 0) { + ret = event.ret; + } + } + } + return ret; +} + +#endif /* WOLFSSL_ASYNC_CRYPT */ + #endif /* HAVE_ECC */ diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index b4c617ce88..23a2afef63 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -62,6 +62,15 @@ const char* wc_GetErrorString(int error) case BAD_MUTEX_E : return "Bad mutex, operation failed"; + case WC_TIMEOUT_E: + return "Timeout error"; + + case WC_PENDING_E: + return "wolfCrypt Operation Pending (would block / eagain) error"; + + case WC_NOT_PENDING_E: + return "wolfCrypt operation not pending error"; + case MP_INIT_E : return "mp_init error state"; @@ -227,8 +236,8 @@ const char* wc_GetErrorString(int error) case AES_CCM_AUTH_E: return "AES-CCM Authentication check fail"; - case CAVIUM_INIT_E: - return "Cavium Init type error"; + case ASYNC_INIT_E: + return "Async Init error"; case COMPRESS_INIT_E: return "Compress Init error"; @@ -257,8 +266,8 @@ const char* wc_GetErrorString(int error) case ASN_OCSP_CONFIRM_E : return "ASN OCSP sig error, confirm failure"; - case BAD_ENC_STATE_E: - return "Bad ecc encrypt state operation"; + case BAD_STATE_E: + return "Bad state operation"; case BAD_PADDING_E: return "Bad padding, message wrong length"; @@ -377,9 +386,6 @@ const char* wc_GetErrorString(int error) case HASH_TYPE_E: return "Hash type not enabled/available"; - case WC_PENDING_E: - return "wolfCrypt Operation Pending (would block / eagain) error"; - case WC_KEY_SIZE_E: return "Key size error, either too small or large"; diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 7dd5fd5072..7cda03024d 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -34,42 +34,54 @@ #include -#ifndef NO_ASN +#if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) + +#ifdef NO_ASN +enum Hash_Sum { + MD2h = 646, + MD5h = 649, + SHAh = 88, + SHA256h = 414, + SHA384h = 415, + SHA512h = 416 +}; +#endif + int wc_HashGetOID(enum wc_HashType hash_type) { int oid = HASH_TYPE_E; /* Default to hash type error */ switch(hash_type) { case WC_HASH_TYPE_MD2: -#ifdef WOLFSSL_MD2 + #ifdef WOLFSSL_MD2 oid = MD2h; -#endif + #endif break; case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_MD5: -#ifndef NO_MD5 + #ifndef NO_MD5 oid = MD5h; -#endif + #endif break; case WC_HASH_TYPE_SHA: -#ifndef NO_SHA + #ifndef NO_SHA oid = SHAh; -#endif + #endif break; case WC_HASH_TYPE_SHA256: -#ifndef NO_SHA256 + #ifndef NO_SHA256 oid = SHA256h; -#endif + #endif break; case WC_HASH_TYPE_SHA384: -#if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384) + #if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384) oid = SHA384h; -#endif + #endif break; case WC_HASH_TYPE_SHA512: -#ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SHA512 oid = SHA512h; -#endif + #endif break; /* Not Supported */ @@ -312,6 +324,21 @@ int wc_Sha256Hash(const byte* data, word32 len, byte* hash) #endif /* !defined(WOLFSSL_TI_HASH) */ #if defined(WOLFSSL_SHA512) +int wc_Sha512GetHash(Sha512* sha512, byte* hash) +{ + int ret; + Sha512 save; + + if (sha512 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + save= *sha512; + ret = wc_Sha512Final(sha512, hash); + *sha512 = save; + + return ret; +} + int wc_Sha512Hash(const byte* data, word32 len, byte* hash) { int ret = 0; @@ -345,6 +372,21 @@ int wc_Sha512Hash(const byte* data, word32 len, byte* hash) } #if defined(WOLFSSL_SHA384) +int wc_Sha384GetHash(Sha384* sha384, byte* hash) +{ + int ret; + Sha384 save; + + if (sha384 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + save= *sha384; + ret = wc_Sha384Final(sha384, hash); + *sha384 = save; + + return ret; +} + int wc_Sha384Hash(const byte* data, word32 len, byte* hash) { int ret = 0; diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 23b53b3057..5312b28601 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -50,16 +50,16 @@ int wc_HmacFinal(Hmac* hmac, byte* out) } -#ifdef HAVE_CAVIUM - int wc_HmacInitCavium(Hmac* hmac, int i) +#ifdef WOLFSSL_ASYNC_CRYPT + int wc_HmacAsyncInit(Hmac* hmac, int i) { - return HmacInitCavium(hmac, i); + return HmacAsyncInit(hmac, i); } - void wc_HmacFreeCavium(Hmac* hmac) + void wc_HmacAsyncFree(Hmac* hmac) { - HmacFreeCavium(hmac); + HmacAsyncFree(hmac); } #endif @@ -105,12 +105,48 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, #include -#ifdef HAVE_CAVIUM - static int HmacCaviumFinal(Hmac* hmac, byte* hash); - static int HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length); - static int HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, - word32 length); -#endif +int wc_HmacSizeByType(int type) +{ + if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 + || type == SHA512 || type == BLAKE2B_ID)) { + return BAD_FUNC_ARG; + } + + switch (type) { + #ifndef NO_MD5 + case MD5: + return MD5_DIGEST_SIZE; + #endif + + #ifndef NO_SHA + case SHA: + return SHA_DIGEST_SIZE; + #endif + + #ifndef NO_SHA256 + case SHA256: + return SHA256_DIGEST_SIZE; + #endif + + #ifdef WOLFSSL_SHA384 + case SHA384: + return SHA384_DIGEST_SIZE; + #endif + + #ifdef WOLFSSL_SHA512 + case SHA512: + return SHA512_DIGEST_SIZE; + #endif + + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + return BLAKE2B_OUTBYTES; + #endif + + default: + return BAD_FUNC_ARG; + } +} static int InitHmac(Hmac* hmac, int type) { @@ -175,9 +211,10 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) word32 i, hmac_block_size = 0; int ret; -#ifdef HAVE_CAVIUM - if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) - return HmacCaviumSetKey(hmac, type, key, length); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { + return NitroxHmacSetKey(hmac, type, key, length); + } #endif ret = InitHmac(hmac, type); @@ -391,9 +428,10 @@ int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) { int ret; -#ifdef HAVE_CAVIUM - if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) - return HmacCaviumUpdate(hmac, msg, length); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { + return NitroxHmacUpdate(hmac, msg, length); + } #endif if (!hmac->innerHashKeyed) { @@ -459,9 +497,10 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) { int ret; -#ifdef HAVE_CAVIUM - if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) - return HmacCaviumFinal(hmac, hash); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { + return NitroxHmacFinal(hmac, hash); + } #endif if (!hmac->innerHashKeyed) { @@ -606,129 +645,57 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) } -#ifdef HAVE_CAVIUM +#ifdef WOLFSSL_ASYNC_CRYPT /* Initialize Hmac for use with Nitrox device */ -int wc_HmacInitCavium(Hmac* hmac, int devId) +int wc_HmacAsyncInit(Hmac* hmac, int devId) { + int ret = 0; + if (hmac == NULL) return -1; - if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0) - return -1; + ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC, devId); + if (ret != 0) { + return ret; + } +#ifdef HAVE_CAVIUM hmac->keyLen = 0; hmac->dataLen = 0; hmac->type = 0; - hmac->devId = devId; - hmac->magic = WOLFSSL_HMAC_CAVIUM_MAGIC; hmac->data = NULL; /* buffered input data */ hmac->innerHashKeyed = 0; +#endif /* HAVE_CAVIUM */ /* default to NULL heap hint or test value */ #ifdef WOLFSSL_HEAP_TEST hmac->heap = (void)WOLFSSL_HEAP_TEST; #else hmac->heap = NULL; -#endif +#endif /* WOLFSSL_HEAP_TEST */ return 0; } /* Free Hmac from use with Nitrox device */ -void wc_HmacFreeCavium(Hmac* hmac) +void wc_HmacAsyncFree(Hmac* hmac) { if (hmac == NULL) return; - CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId); - hmac->magic = 0; - XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); + wolfAsync_DevCtxFree(&hmac->asyncDev); + +#ifdef HAVE_CAVIUM + XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_ASYNC_TMP); hmac->data = NULL; +#endif } +#endif /* WOLFSSL_ASYNC_CRYPT */ -static int HmacCaviumFinal(Hmac* hmac, byte* hash) -{ - word32 requestId; - - if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen, - (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId, - hmac->devId) != 0) { - WOLFSSL_MSG("Cavium Hmac failed"); - return -1; - } - hmac->innerHashKeyed = 0; /* tell update to start over if used again */ - - return 0; -} - - -static int HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length) -{ - word16 add = (word16)length; - word32 total; - byte* tmp; - - if (length > WOLFSSL_MAX_16BIT) { - WOLFSSL_MSG("Too big msg for cavium hmac"); - return -1; - } - - if (hmac->innerHashKeyed == 0) { /* starting new */ - hmac->dataLen = 0; - hmac->innerHashKeyed = 1; - } - - total = add + hmac->dataLen; - if (total > WOLFSSL_MAX_16BIT) { - WOLFSSL_MSG("Too big msg for cavium hmac"); - return -1; - } - - tmp = XMALLOC(hmac->dataLen + add, hmac->heap ,DYNAMIC_TYPE_CAVIUM_TMP); - if (tmp == NULL) { - WOLFSSL_MSG("Out of memory for cavium update"); - return -1; - } - if (hmac->dataLen) - XMEMCPY(tmp, hmac->data, hmac->dataLen); - XMEMCPY(tmp + hmac->dataLen, msg, add); - - hmac->dataLen += add; - XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_CAVIUM_TMP); - hmac->data = tmp; - - return 0; -} - - -static int HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, - word32 length) -{ - hmac->macType = (byte)type; - if (type == MD5) - hmac->type = MD5_TYPE; - else if (type == SHA) - hmac->type = SHA1_TYPE; - else if (type == SHA256) - hmac->type = SHA256_TYPE; - else { - WOLFSSL_MSG("unsupported cavium hmac type"); - } - - hmac->innerHashKeyed = 0; /* should we key Startup flag */ - - hmac->keyLen = (word16)length; - /* store key in ipad */ - XMEMCPY(hmac->ipad, key, length); - - return 0; -} - -#endif /* HAVE_CAVIUM */ int wolfSSL_GetHmacMaxSize(void) { @@ -748,49 +715,6 @@ int wolfSSL_GetHmacMaxSize(void) #endif /* WOLFSSL_HAVE_MIN */ -static INLINE int GetHashSizeByType(int type) -{ - if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 - || type == SHA512 || type == BLAKE2B_ID)) - return BAD_FUNC_ARG; - - switch (type) { - #ifndef NO_MD5 - case MD5: - return MD5_DIGEST_SIZE; - #endif - - #ifndef NO_SHA - case SHA: - return SHA_DIGEST_SIZE; - #endif - - #ifndef NO_SHA256 - case SHA256: - return SHA256_DIGEST_SIZE; - #endif - - #ifdef WOLFSSL_SHA384 - case SHA384: - return SHA384_DIGEST_SIZE; - #endif - - #ifdef WOLFSSL_SHA512 - case SHA512: - return SHA512_DIGEST_SIZE; - #endif - - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - return BLAKE2B_OUTBYTES; - #endif - - default: - return BAD_FUNC_ARG; - } -} - - /* HMAC-KDF with hash type, optional salt and info, return 0 on success */ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, const byte* salt, word32 saltSz, @@ -806,7 +730,7 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, byte prk[MAX_DIGEST_SIZE]; #endif const byte* localSalt; /* either points to user input or tmp */ - int hashSz = GetHashSizeByType(type); + int hashSz = wc_HmacSizeByType(type); word32 outIdx = 0; byte n = 0x1; int ret; @@ -815,13 +739,13 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK - tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, myHmac.heap, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return MEMORY_E; - prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, myHmac.heap, DYNAMIC_TYPE_TMP_BUFFER); if (prk == NULL) { - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, myHmac.heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #endif @@ -873,8 +797,8 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, } #ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, hmac->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(prk, hmac->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 28707ce211..b1fae4d3e2 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -44,6 +44,11 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/ti/ti-hash.c \ wolfcrypt/src/port/ti/ti-ccm.c \ wolfcrypt/src/port/pic32/pic32mz-hash.c \ - wolfcrypt/src/port/nrf51.c + wolfcrypt/src/port/nrf51.c \ + wolfcrypt/src/port/arm/armv8-sha256.c +if BUILD_CAVIUM +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c +EXTRA_DIST += wolfcrypt/src/port/cavium/README.md +endif diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 1f7efe1ee3..f9e24b5bd3 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -196,6 +196,92 @@ static int create_memory_buckets(byte* buffer, word32 bufSz, return ret; } +int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap) +{ + word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; + word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; + + if (heap == NULL) { + return BAD_FUNC_ARG; + } + + XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP)); + + XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz)); + XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist)); + + if (InitMutex(&(heap->memory_mutex)) != 0) { + WOLFSSL_MSG("Error creating heap memory mutex"); + return BAD_MUTEX_E; + } + + return 0; +} + +int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, + unsigned char* buf, unsigned int sz, int flag, int max) +{ + int ret; + WOLFSSL_HEAP* heap; + WOLFSSL_HEAP_HINT* hint; + word32 idx = 0; + + if (pHint == NULL || buf == NULL) { + return BAD_FUNC_ARG; + } + + if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) { + return BUFFER_E; /* not enough memory for structures */ + } + + /* check if hint has already been assigned */ + if (*pHint == NULL) { + heap = (WOLFSSL_HEAP*)buf; + idx += sizeof(WOLFSSL_HEAP); + hint = (WOLFSSL_HEAP_HINT*)(buf + idx); + idx += sizeof(WOLFSSL_HEAP_HINT); + + ret = wolfSSL_init_memory_heap(heap); + if (ret != 0) { + return ret; + } + + XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT)); + hint->memory = heap; + } + else { + #ifdef WOLFSSL_HEAP_TEST + /* do not load in memory if test has been set */ + if (heap == (void*)WOLFSSL_HEAP_TEST) { + return 0; + } + #endif + + hint = (WOLFSSL_HEAP_HINT*)(*pHint); + heap = hint->memory; + } + + ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap); + if (ret != 1) { + WOLFSSL_MSG("Error partitioning memory"); + return -1; + } + + /* determine what max applies too */ + if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) { + heap->maxIO = max; + } + else { /* general memory used in handshakes */ + heap->maxHa = max; + } + + heap->flag |= flag; + *pHint = hint; + + (void)max; + + return 0; +} int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag, WOLFSSL_HEAP* heap) @@ -219,6 +305,10 @@ int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag, ava--; } +#ifdef WOLFSSL_DEBUG_MEMORY + printf("Allocated %d bytes for static memory @ %p\n", ava, pt); +#endif + /* devide into chunks of memory and add them to available list */ while (ava >= (heap->sizeList[0] + padSz + memSz)) { int i; @@ -392,7 +482,11 @@ int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats) } +#ifdef WOLFSSL_DEBUG_MEMORY +void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line) +#else void* wolfSSL_Malloc(size_t size, void* heap, int type) +#endif { void* res = 0; wc_Memory* pt = NULL; @@ -473,6 +567,10 @@ void* wolfSSL_Malloc(size_t size, void* heap, int type) mem->alloc += 1; res = pt->buffer; + #ifdef WOLFSSL_DEBUG_MEMORY + printf("Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); + #endif + /* keep track of connection statistics if flag is set */ if (mem->flag & WOLFMEM_TRACK_STATS) { WOLFSSL_MEM_CONN_STATS* stats = hint->stats; @@ -512,7 +610,11 @@ void* wolfSSL_Malloc(size_t size, void* heap, int type) } +#ifdef WOLFSSL_DEBUG_MEMORY +void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line) +#else void wolfSSL_Free(void *ptr, void* heap, int type) +#endif { int i; wc_Memory* pt; @@ -579,6 +681,10 @@ void wolfSSL_Free(void *ptr, void* heap, int type) mem->inUse -= pt->sz; mem->frAlc += 1; + #ifdef WOLFSSL_DEBUG_MEMORY + printf("Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); + #endif + /* keep track of connection statistics if flag is set */ if (mem->flag & WOLFMEM_TRACK_STATS) { WOLFSSL_MEM_CONN_STATS* stats = hint->stats; @@ -606,8 +712,11 @@ void wolfSSL_Free(void *ptr, void* heap, int type) (void)type; } - +#ifdef WOLFSSL_DEBUG_MEMORY +void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line) +#else void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type) +#endif { void* res = 0; wc_Memory* pt = NULL; @@ -678,7 +787,11 @@ void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type) /* free memory that was previously being used */ UnLockMutex(&(mem->memory_mutex)); - wolfSSL_Free(ptr, heap, type); + wolfSSL_Free(ptr, heap, type + #ifdef WOLFSSL_DEBUG_MEMORY + , func, line + #endif + ); if (LockMutex(&(mem->memory_mutex)) != 0) { WOLFSSL_MSG("Bad memory_mutex lock"); return NULL; @@ -719,7 +832,7 @@ void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type) /* allow simple per thread in and out pools */ -/* use 17k size sense max record size is 16k plus overhead */ +/* use 17k size since max record size is 16k plus overhead */ static THREAD_LS_T byte pool_in[17*1024]; static THREAD_LS_T byte pool_out[17*1024]; @@ -766,9 +879,7 @@ void* XREALLOC(void *p, size_t n, void* heap, int type) return realloc(p, n); } - -/* unit api calls, let's make sure visible with WOLFSSL_API */ -WOLFSSL_API void XFREE(void *p, void* heap, int type) +void XFREE(void *p, void* heap, int type) { (void)heap; diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c new file mode 100644 index 0000000000..8813d82df5 --- /dev/null +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -0,0 +1,666 @@ +/* armv8-sha256.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if !defined(NO_SHA256) && defined(WOLFSSL_ARMASM) +#include +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#ifndef WOLFSSL_HAVE_MIN +#define WOLFSSL_HAVE_MIN + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* WOLFSSL_HAVE_MIN */ + +#if !defined (ALIGN32) + #if defined (__GNUC__) + #define ALIGN32 __attribute__ ( (aligned (32))) + #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) + #define ALIGN32 __declspec (align (32)) + #else + #define ALIGN32 + #endif +#endif + +static const ALIGN32 word32 K[64] = { + 0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL, + 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L, + 0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L, + 0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL, + 0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L, + 0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L, + 0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL, + 0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L, + 0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L, + 0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L, + 0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL, + 0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L, + 0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L +}; + +int wc_InitSha256(Sha256* sha256) +{ + int ret = 0; + + sha256->digest[0] = 0x6A09E667L; + sha256->digest[1] = 0xBB67AE85L; + sha256->digest[2] = 0x3C6EF372L; + sha256->digest[3] = 0xA54FF53AL; + sha256->digest[4] = 0x510E527FL; + sha256->digest[5] = 0x9B05688CL; + sha256->digest[6] = 0x1F83D9ABL; + sha256->digest[7] = 0x5BE0CD19L; + + sha256->buffLen = 0; + sha256->loLen = 0; + sha256->hiLen = 0; + + return ret; +} + + +static INLINE void AddLength(Sha256* sha256, word32 len) +{ + word32 tmp = sha256->loLen; + if ( (sha256->loLen += len) < tmp) + sha256->hiLen++; /* carry low to high */ +} + + +/* ARMv8 hardware accleration */ +int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) +{ + word32 add; + word32 numBlocks; + + if (sha256 == NULL || (data == NULL && len != 0)) { + return BAD_FUNC_ARG; + } + + /* fill leftover buffer with data */ + add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); + XMEMCPY((byte*)(sha256->buffer) + sha256->buffLen, data, add); + sha256->buffLen += add; + data += add; + len -= add; + + /* number of blocks in a row to complete */ + numBlocks = (len + sha256->buffLen)/SHA256_BLOCK_SIZE; + + if (numBlocks > 0) { + /* get leftover amount after blocks */ + add = (len + sha256->buffLen) - numBlocks * SHA256_BLOCK_SIZE; + __asm__ volatile ( + "#load leftover data\n" + "LD1 {v0.2d-v3.2d}, %[buffer] \n" + + "#load current digest\n" + "LD1 {v12.2d-v13.2d}, %[digest] \n" + "MOV w8, %w[blocks] \n" + "REV32 v0.16b, v0.16b \n" + "REV32 v1.16b, v1.16b \n" + "REV32 v2.16b, v2.16b \n" + "REV32 v3.16b, v3.16b \n" + + "#load K values in \n" + "LD1 {v16.4s-v19.4s}, [%[k]], #64 \n" + "LD1 {v20.4s-v23.4s}, [%[k]], #64 \n" + "MOV v14.16b, v12.16b \n" /* store digest for add at the end */ + "MOV v15.16b, v13.16b \n" + "LD1 {v24.4s-v27.4s}, [%[k]], #64 \n" + "LD1 {v28.4s-v31.4s}, [%[k]], #64 \n" + + /* begining of SHA256 block operation */ + "sha256Start:\n" + "MOV v4.16b, v0.16b \n" + "ADD v0.4s, v0.4s, v16.4s \n" + "MOV v11.16b, v12.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "ADD v0.4s, v1.4s, v17.4s \n" + "MOV v11.16b, v12.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "ADD v0.4s, v2.4s, v18.4s \n" + "MOV v11.16b, v12.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v4.4s, v1.4s \n" + "SHA256SU1 v4.4s, v2.4s, v3.4s \n" + "ADD v0.4s, v3.4s, v19.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v5.16b, v1.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v5.4s, v2.4s \n" + "SHA256SU1 v5.4s, v3.4s, v4.4s \n" + "ADD v0.4s, v4.4s, v20.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v6.16b, v2.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v6.4s, v3.4s \n" + "SHA256SU1 v6.4s, v4.4s, v5.4s \n" + "ADD v0.4s, v5.4s, v21.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v7.16b, v3.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v7.4s, v4.4s \n" + "SHA256SU1 v7.4s, v5.4s, v6.4s \n" + "ADD v0.4s, v6.4s, v22.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v8.16b, v4.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v8.4s, v5.4s \n" + "SHA256SU1 v8.4s, v6.4s, v7.4s \n" + "ADD v0.4s, v7.4s, v23.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v9.16b, v5.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v9.4s, v6.4s \n" + "SHA256SU1 v9.4s, v7.4s, v8.4s \n" + "ADD v0.4s, v8.4s, v24.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v10.16b, v6.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v10.4s, v7.4s \n" + "SHA256SU1 v10.4s, v8.4s, v9.4s \n" + "ADD v0.4s, v9.4s, v25.4s \n" + "MOV v11.16b, v12.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "ADD v0.4s, v10.4s, v26.4s \n" + "MOV v11.16b, v12.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + /* Re-use of registers is needed in order to not overwrite + * previous digest value. */ + "#move to lower register and handle last rounds 11-15 \n" + "MOV v4.16b, v7.16b \n" + "MOV v1.16b, v8.16b \n" + "MOV v2.16b, v9.16b \n" + "MOV v3.16b, v10.16b \n" + "MOV v5.16b, v8.16b \n" + + "SHA256SU0 v4.4s, v1.4s \n" /* 4 -> 11 */ + "SHA256SU1 v4.4s, v2.4s, v3.4s \n" + "SHA256SU0 v5.4s, v2.4s \n" + "SHA256SU1 v5.4s, v3.4s, v4.4s \n" + "ADD v0.4s, v4.4s, v27.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v6.16b, v2.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v6.4s, v3.4s \n" + "SHA256SU1 v6.4s, v4.4s, v5.4s \n" + "ADD v0.4s, v5.4s, v28.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v7.16b, v3.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v7.4s, v4.4s \n" + "SHA256SU1 v7.4s, v5.4s, v6.4s \n" + "ADD v0.4s, v6.4s, v29.4s \n" + "MOV v11.16b, v12.16b \n" + "MOV v8.16b, v4.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "SHA256SU0 v8.4s, v5.4s \n" + "SHA256SU1 v8.4s, v6.4s, v7.4s \n" + "ADD v0.4s, v7.4s, v30.4s \n" + "MOV v11.16b, v12.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "ADD v0.4s, v8.4s, v31.4s \n" + "MOV v11.16b, v12.16b \n" + "SHA256H q12, q13, v0.4s \n" + "SHA256H2 q13, q11, v0.4s \n" + + "#Add working vars back into digest state \n" + "ADD v12.4s, v12.4s, v14.4s \n" + "ADD v13.4s, v13.4s, v15.4s \n" + + "#check if more blocks should be done\n" + "SUB w8, w8, #1 \n" + "CBZ w8, sha256End \n" + + "#load in message and schedual updates \n" + "LD1 {v0.2d-v3.2d}, [%[dataIn]], #64 \n" + "MOV v14.16b, v12.16b \n" + "MOV v15.16b, v13.16b \n" + "REV32 v0.16b, v0.16b \n" + "REV32 v1.16b, v1.16b \n" + "REV32 v2.16b, v2.16b \n" + "REV32 v3.16b, v3.16b \n" + "B sha256Start \n" /* do another block */ + + "sha256End:\n" + "STP q12, q13, %[out] \n" + + : [out] "=m" (sha256->digest), "=m" (sha256->buffer), "=r" (numBlocks), + "=r" (data) + : [k] "r" (K), [digest] "m" (sha256->digest), [buffer] "m" (sha256->buffer), + [blocks] "2" (numBlocks), [dataIn] "3" (data) + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", + "v15" + ); + + AddLength(sha256, SHA256_BLOCK_SIZE * numBlocks); + + /* copy over any remaining data leftover */ + XMEMCPY(sha256->buffer, data, add); + sha256->buffLen = add; + } + + return 0; +} + + +int wc_Sha256Final(Sha256* sha256, byte* hash) +{ + byte* local; + + if (sha256 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + local = (byte*)sha256->buffer; + AddLength(sha256, sha256->buffLen); /* before adding pads */ + + local[sha256->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (sha256->buffLen > SHA256_PAD_SIZE) { + + XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); + sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; + __asm__ volatile ( + "LD1 {v4.2d-v7.2d}, %[buffer] \n" + "MOV v0.16b, v4.16b \n" + "MOV v1.16b, v5.16b \n" + "REV32 v0.16b, v0.16b \n" + "REV32 v1.16b, v1.16b \n" + "MOV v2.16b, v6.16b \n" + "MOV v3.16b, v7.16b \n" + "REV32 v2.16b, v2.16b \n" + "REV32 v3.16b, v3.16b \n" + "MOV v4.16b, v0.16b \n" + "MOV v5.16b, v1.16b \n" + "LD1 {v20.2d-v21.2d}, %[digest] \n" + + "#SHA256 operation on updated message \n" + "MOV v16.16b, v20.16b \n" + "MOV v17.16b, v21.16b \n" + + "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "SHA256SU0 v4.4s, v1.4s \n" + "SHA256SU1 v4.4s, v2.4s, v3.4s \n" + "ADD v0.4s, v0.4s, v22.4s \n" + "MOV v6.16b, v2.16b \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v0.4s \n" + "SHA256H2 q17, q18, v0.4s \n" + + "SHA256SU0 v5.4s, v2.4s \n" + "SHA256SU1 v5.4s, v3.4s, v4.4s \n" + "ADD v1.4s, v1.4s, v23.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v7.16b, v3.16b \n" + "SHA256H q16, q17, v1.4s \n" + "SHA256H2 q17, q18, v1.4s \n" + + "SHA256SU0 v6.4s, v3.4s \n" + "SHA256SU1 v6.4s, v4.4s, v5.4s \n" + "ADD v2.4s, v2.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v8.16b, v4.16b \n" + "SHA256H q16, q17, v2.4s \n" + "SHA256H2 q17, q18, v2.4s \n" + + "SHA256SU0 v7.4s, v4.4s \n" + "SHA256SU1 v7.4s, v5.4s, v6.4s \n" + "ADD v3.4s, v3.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v9.16b, v5.16b \n" + "SHA256H q16, q17, v3.4s \n" + "SHA256H2 q17, q18, v3.4s \n" + + "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "SHA256SU0 v8.4s, v5.4s \n" + "SHA256SU1 v8.4s, v6.4s, v7.4s \n" + "ADD v4.4s, v4.4s, v22.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v10.16b, v6.16b \n" + "SHA256H q16, q17, v4.4s \n" + "SHA256H2 q17, q18, v4.4s \n" + + "SHA256SU0 v9.4s, v6.4s \n" + "SHA256SU1 v9.4s, v7.4s, v8.4s \n" + "ADD v5.4s, v5.4s, v23.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v11.16b, v7.16b \n" + "SHA256H q16, q17, v5.4s \n" + "SHA256H2 q17, q18, v5.4s \n" + + "SHA256SU0 v10.4s, v7.4s \n" + "SHA256SU1 v10.4s, v8.4s, v9.4s \n" + "ADD v6.4s, v6.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v12.16b, v8.16b \n" + "SHA256H q16, q17, v6.4s \n" + "SHA256H2 q17, q18, v6.4s \n" + + "SHA256SU0 v11.4s, v8.4s \n" + "SHA256SU1 v11.4s, v9.4s, v10.4s \n" + "ADD v7.4s, v7.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v13.16b, v9.16b \n" + "SHA256H q16, q17, v7.4s \n" + "SHA256H2 q17, q18, v7.4s \n" + + "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "SHA256SU0 v12.4s, v9.4s \n" + "SHA256SU1 v12.4s, v10.4s, v11.4s \n" + "ADD v8.4s, v8.4s, v22.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v14.16b, v10.16b \n" + "SHA256H q16, q17, v8.4s \n" + "SHA256H2 q17, q18, v8.4s \n" + + "SHA256SU0 v13.4s, v10.4s \n" + "SHA256SU1 v13.4s, v11.4s, v12.4s \n" + "ADD v9.4s, v9.4s, v23.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v15.16b, v11.16b \n" + "SHA256H q16, q17, v9.4s \n" + "SHA256H2 q17, q18, v9.4s \n" + + "SHA256SU0 v14.4s, v11.4s \n" + "SHA256SU1 v14.4s, v12.4s, v13.4s \n" + "ADD v10.4s, v10.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v10.4s \n" + "SHA256H2 q17, q18, v10.4s \n" + + "SHA256SU0 v15.4s, v12.4s \n" + "SHA256SU1 v15.4s, v13.4s, v14.4s \n" + + "ADD v11.4s, v11.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v11.4s \n" + "SHA256H2 q17, q18, v11.4s \n" + + "LD1 {v22.16b-v25.16b}, [%[k]] \n" + "ADD v12.4s, v12.4s, v22.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v12.4s \n" + "SHA256H2 q17, q18, v12.4s \n" + + "ADD v13.4s, v13.4s, v23.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v13.4s \n" + "SHA256H2 q17, q18, v13.4s \n" + + "ADD v14.4s, v14.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v14.4s \n" + "SHA256H2 q17, q18, v14.4s \n" + + "ADD v15.4s, v15.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v15.4s \n" + "SHA256H2 q17, q18, v15.4s \n" + + "#Add working vars back into digest state \n" + "ADD v16.4s, v16.4s, v20.4s \n" + "ADD v17.4s, v17.4s, v21.4s \n" + "STP q16, q17, %[out] \n" + : [out] "=m" (sha256->digest) + : [k] "r" (K), [digest] "m" (sha256->digest), + [buffer] "m" (sha256->buffer) + : "cc", "memory", "v0", "v1", "v2", "v3", "v8", "v9", "v10", "v11" + , "v12", "v13", "v14", "v15", "v16", "v17", "v18" + ); + + sha256->buffLen = 0; + } + XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen); + + /* put lengths in bits */ + sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) + + (sha256->hiLen << 3); + sha256->loLen = sha256->loLen << 3; + + /* store lengths */ + #if defined(LITTLE_ENDIAN_ORDER) + __asm__ volatile ( + "LD1 {v0.2d-v3.2d}, %[in] \n" + "REV32 v0.16b, v0.16b \n" + "REV32 v1.16b, v1.16b \n" + "REV32 v2.16b, v2.16b \n" + "REV32 v3.16b, v3.16b \n" + "ST1 {v0.2d-v3.2d}, %[out] \n" + : [out] "=m" (sha256->buffer) + : [in] "m" (sha256->buffer) + : "cc", "memory" + ); + #endif + /* ! length ordering dependent on digest endian type ! */ + XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32)); + XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, + sizeof(word32)); + + __asm__ volatile ( + "#load in message and schedual updates \n" + "LD1 {v4.2d-v7.2d}, %[buffer] \n" + "MOV v0.16b, v4.16b \n" + "MOV v1.16b, v5.16b \n" + "MOV v2.16b, v6.16b \n" + "MOV v3.16b, v7.16b \n" + "LD1 {v20.2d-v21.2d}, %[digest] \n" + + "MOV v16.16b, v20.16b \n" + "MOV v17.16b, v21.16b \n" + "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "SHA256SU0 v4.4s, v1.4s \n" + "SHA256SU1 v4.4s, v2.4s, v3.4s \n" + "ADD v0.4s, v0.4s, v22.4s \n" + "MOV v6.16b, v2.16b \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v0.4s \n" + "SHA256H2 q17, q18, v0.4s \n" + + "SHA256SU0 v5.4s, v2.4s \n" + "SHA256SU1 v5.4s, v3.4s, v4.4s \n" + "ADD v1.4s, v1.4s, v23.4s \n" + "MOV v7.16b, v3.16b \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v1.4s \n" + "SHA256H2 q17, q18, v1.4s \n" + + "SHA256SU0 v6.4s, v3.4s \n" + "SHA256SU1 v6.4s, v4.4s, v5.4s \n" + "ADD v2.4s, v2.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v8.16b, v4.16b \n" + "SHA256H q16, q17, v2.4s \n" + "SHA256H2 q17, q18, v2.4s \n" + + "SHA256SU0 v7.4s, v4.4s \n" + "SHA256SU1 v7.4s, v5.4s, v6.4s \n" + "ADD v3.4s, v3.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v9.16b, v5.16b \n" + "SHA256H q16, q17, v3.4s \n" + "SHA256H2 q17, q18, v3.4s \n" + + "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "SHA256SU0 v8.4s, v5.4s \n" + "SHA256SU1 v8.4s, v6.4s, v7.4s \n" + "ADD v4.4s, v4.4s, v22.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v10.16b, v6.16b \n" + "SHA256H q16, q17, v4.4s \n" + "SHA256H2 q17, q18, v4.4s \n" + + "SHA256SU0 v9.4s, v6.4s \n" + "SHA256SU1 v9.4s, v7.4s, v8.4s \n" + "ADD v5.4s, v5.4s, v23.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v11.16b, v7.16b \n" + "SHA256H q16, q17, v5.4s \n" + "SHA256H2 q17, q18, v5.4s \n" + + "SHA256SU0 v10.4s, v7.4s \n" + "SHA256SU1 v10.4s, v8.4s, v9.4s \n" + "ADD v6.4s, v6.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v12.16b, v8.16b \n" + "SHA256H q16, q17, v6.4s \n" + "SHA256H2 q17, q18, v6.4s \n" + + "SHA256SU0 v11.4s, v8.4s \n" + "SHA256SU1 v11.4s, v9.4s, v10.4s \n" + "ADD v7.4s, v7.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v13.16b, v9.16b \n" + "SHA256H q16, q17, v7.4s \n" + "SHA256H2 q17, q18, v7.4s \n" + + "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "SHA256SU0 v12.4s, v9.4s \n" + "SHA256SU1 v12.4s, v10.4s, v11.4s \n" + "ADD v8.4s, v8.4s, v22.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v14.16b, v10.16b \n" + "SHA256H q16, q17, v8.4s \n" + "SHA256H2 q17, q18, v8.4s \n" + + "SHA256SU0 v13.4s, v10.4s \n" + "SHA256SU1 v13.4s, v11.4s, v12.4s \n" + "ADD v9.4s, v9.4s, v23.4s \n" + "MOV v18.16b, v16.16b \n" + "MOV v15.16b, v11.16b \n" + "SHA256H q16, q17, v9.4s \n" + "SHA256H2 q17, q18, v9.4s \n" + + "SHA256SU0 v14.4s, v11.4s \n" + "SHA256SU1 v14.4s, v12.4s, v13.4s \n" + "ADD v10.4s, v10.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v10.4s \n" + "SHA256H2 q17, q18, v10.4s \n" + + "SHA256SU0 v15.4s, v12.4s \n" + "SHA256SU1 v15.4s, v13.4s, v14.4s \n" + "ADD v11.4s, v11.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v11.4s \n" + "SHA256H2 q17, q18, v11.4s \n" + + "LD1 {v22.16b-v25.16b}, [%[k]] \n" + "ADD v12.4s, v12.4s, v22.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v12.4s \n" + "SHA256H2 q17, q18, v12.4s \n" + + "ADD v13.4s, v13.4s, v23.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v13.4s \n" + "SHA256H2 q17, q18, v13.4s \n" + + "ADD v14.4s, v14.4s, v24.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v14.4s \n" + "SHA256H2 q17, q18, v14.4s \n" + + "ADD v15.4s, v15.4s, v25.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v15.4s \n" + "SHA256H2 q17, q18, v15.4s \n" + + "#Add working vars back into digest state \n" + "ADD v16.4s, v16.4s, v20.4s \n" + "ADD v17.4s, v17.4s, v21.4s \n" + + "#Store value as hash output \n" + #if defined(LITTLE_ENDIAN_ORDER) + "REV32 v16.16b, v16.16b \n" + #endif + "ST1 {v16.16b}, [%[hashOut]], #16 \n" + #if defined(LITTLE_ENDIAN_ORDER) + "REV32 v17.16b, v17.16b \n" + #endif + "ST1 {v17.16b}, [%[hashOut]] \n" + : [hashOut] "=r" (hash) + : [k] "r" (K), [digest] "m" (sha256->digest), + [buffer] "m" (sha256->buffer), + "0" (hash) + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", + "v15", "v16", "v17", "v18" + ); + + return wc_InitSha256(sha256); /* reset state */ +} + +#endif /* NO_SHA256 and WOLFSSL_ARMASM */ + diff --git a/wolfcrypt/src/port/cavium/README.md b/wolfcrypt/src/port/cavium/README.md new file mode 100644 index 0000000000..982a938b98 --- /dev/null +++ b/wolfcrypt/src/port/cavium/README.md @@ -0,0 +1,32 @@ +# Cavium Nitrox V Support + +## Directory Structure: +`/` + `/CNN55XX-SDK` + `/wolfssl` + +## Cavium Driver + +Tested again `CNN55XX-Driver-Linux-KVM-XEN-PF-SDK-0.2-04.tar` +From inside `CNN55XX-SDK`: +1. `make` + Note: To resolve warnings in `CNN55XX-SDK/include/vf_defs.h`: + a. Changed `vf_config_mode_str` to return `const char*` and modify `vf_mode_str` to be `const char*`. + b. In `vf_config_mode_to_num_vfs` above `default:` add `case PF:`. + +2. `sudo make load` + +## wolfSSL + +Currently the AES and DES3 benchmark tests causes the kernel to crash, so they are disabled for now, even though the wolfCrypt tests pass for those. + +From inside `wolfssl`: +1. `./configure --with-cavium-v=../CNN55XX-SDK --enable-asynccrypt --enable-aesni --enable-intelasm --disable-aes --disable-aesgcm --disable-des3` +2. `make` + +## Usage + +Note: Must run applications with sudo to access device. + +`sudo ./wolfcrypt/benchmark/benchmark` +`sudo ./wolfcrypt/test/testwolfcrypt` diff --git a/wolfcrypt/src/port/cavium/cavium_nitrox.c b/wolfcrypt/src/port/cavium/cavium_nitrox.c new file mode 100644 index 0000000000..1acc496442 --- /dev/null +++ b/wolfcrypt/src/port/cavium/cavium_nitrox.c @@ -0,0 +1,778 @@ +/* cavium-nitrox.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef HAVE_CAVIUM + +#include +#include +#include +#include +#ifndef NO_RSA + #include +#endif +#ifndef NO_AES + #include +#endif + +#include +#include /* For ntohs */ + +static CspHandle mLastDevHandle = INVALID_DEVID; + +int NitroxTranslateResponseCode(int ret) +{ + switch (ret) { + case EAGAIN: + case ERR_REQ_PENDING: + ret = WC_PENDING_E; + break; + case ERR_REQ_TIMEOUT: + ret = WC_TIMEOUT_E; + break; + case 0: + /* leave as-is */ + break; + default: + printf("NitroxTranslateResponseCode Unknown ret=%x\n", ret); + ret = ASYNC_INIT_E; + } + return ret; +} + + +CspHandle NitroxGetDeviceHandle(void) +{ + return mLastDevHandle; +} + +CspHandle NitroxOpenDevice(int dma_mode, int dev_id) +{ + mLastDevHandle = INVALID_DEVID; + +#ifdef HAVE_CAVIUM_V + (void)dma_mode; + + if (CspInitialize(dev_id, &mLastDevHandle)) { + return -1; + } + +#else + Csp1CoreAssignment core_assign; + Uint32 device; + + if (CspInitialize(CAVIUM_DIRECT, CAVIUM_DEV_ID)) { + return -1; + } + if (Csp1GetDevType(&device)) { + return -1; + } + if (device != NPX_DEVICE) { + if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT, + (Uint32 *)&core_assign)!= 0) { + return -1; + } + } + CspShutdown(CAVIUM_DEV_ID); + + mLastDevHandle = CspInitialize(dma_mode, dev_id); + if (mLastDevHandle == 0) { + mLastDevHandle = dev_id; + } + +#endif /* HAVE_CAVIUM_V */ + + return mLastDevHandle; +} + + +int NitroxAllocContext(CaviumNitroxDev* nitrox, CspHandle devId, + ContextType type) +{ + int ret; + + if (nitrox == NULL) { + return -1; + } + + /* If invalid handle provided, use last open one */ + if (devId == INVALID_DEVID) { + devId = NitroxGetDeviceHandle(); + } + +#ifdef HAVE_CAVIUM_V + ret = CspAllocContext(devId, type, &nitrox->contextHandle); +#else + ret = CspAllocContext(type, &nitrox->contextHandle, devId); +#endif + if (ret != 0) { + return -1; + } + + nitrox->type = type; + nitrox->devId = devId; + + return 0; +} + +void NitroxFreeContext(CaviumNitroxDev* nitrox) +{ + if (nitrox == NULL) { + return; + } + +#ifdef HAVE_CAVIUM_V + CspFreeContext(nitrox->devId, nitrox->type, nitrox->contextHandle); +#else + CspFreeContext(nitrox->type, nitrox->contextHandle, nitrox->devId); +#endif +} + +void NitroxCloseDevice(CspHandle devId) +{ + if (devId >= 0) { + CspShutdown(devId); + } +} + +#if defined(WOLFSSL_ASYNC_CRYPT) + +int NitroxCheckRequest(CspHandle devId, CavReqId reqId) +{ + int ret = CspCheckForCompletion(devId, reqId); + return NitroxTranslateResponseCode(ret); +} + +int NitroxCheckRequests(CspHandle devId, CspMultiRequestStatusBuffer* req_stat_buf) +{ + int ret = CspGetAllResults(req_stat_buf, devId); + return NitroxTranslateResponseCode(ret); +} + + +#ifndef NO_RSA + +int NitroxRsaExptMod(const byte* in, word32 inLen, + byte* exponent, word32 expLen, + byte* modulus, word32 modLen, + byte* out, word32* outLen, RsaKey* key) +{ + int ret; + + if (key == NULL || in == NULL || inLen == 0 || exponent == NULL || + modulus == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + + (void)outLen; + +#ifdef HAVE_CAVIUM_V + ret = CspMe(key->asyncDev.dev.devId, CAVIUM_REQ_MODE, CAVIUM_SSL_GRP, + CAVIUM_DPORT, modLen, expLen, inLen, + modulus, exponent, (Uint8*)in, out, + &key->asyncDev.dev.reqId); + #if 0 + /* TODO: Try MeCRT */ + ret = CspMeCRT(); + #endif +#else + /* Not implemented/supported */ + ret = NOT_COMPILED_IN; +#endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + return ret; +} + +int NitroxRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) +{ + word32 ret; + + if (key == NULL || in == NULL || out == NULL || outLen < (word32)key->n.used) { + return BAD_FUNC_ARG; + } + +#ifdef HAVE_CAVIUM_V + ret = CspPkcs1v15Enc(key->asyncDev.dev.devId, CAVIUM_REQ_MODE, CAVIUM_SSL_GRP, CAVIUM_DPORT, + BT2, key->n.used, key->e.used, + (word16)inLen, key->n.dpraw, key->e.dpraw, (byte*)in, out, + &key->asyncDev.dev.reqId); +#else + ret = CspPkcs1v15Enc(CAVIUM_REQ_MODE, BT2, key->n.used, key->e.used, + (word16)inLen, key->n.dpraw, key->e.dpraw, (byte*)in, out, + &key->asyncDev.dev.reqId, key->asyncDev.dev.devId); +#endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + return key->n.used; +} + + +static INLINE void ato16(const byte* c, word16* u16) +{ + *u16 = (c[0] << 8) | (c[1]); +} + +int NitroxRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) +{ + word32 ret; + word16 outSz = (word16)outLen; + + if (key == NULL || in == NULL || out == NULL || + inLen != (word32)key->n.used) { + return BAD_FUNC_ARG; + } + +#ifdef HAVE_CAVIUM_V + ret = CspPkcs1v15CrtDec(key->asyncDev.dev.devId, CAVIUM_REQ_MODE, CAVIUM_SSL_GRP, CAVIUM_DPORT, + BT2, key->n.used, key->q.dpraw, + key->dQ.dpraw, key->p.dpraw, key->dP.dpraw, key->u.dpraw, + (byte*)in, &outSz, out, &key->asyncDev.dev.reqId); +#else + ret = CspPkcs1v15CrtDec(CAVIUM_REQ_MODE, BT2, key->n.used, key->q.dpraw, + key->dQ.dpraw, key->p.dpraw, key->dP.dpraw, key->u.dpraw, + (byte*)in, &outSz, out, &key->asyncDev.dev.reqId, + key->asyncDev.dev.devId); +#endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + ato16((const byte*)&outSz, &outSz); + + return outSz; +} + + +int NitroxRsaSSL_Sign(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) +{ + word32 ret; + + if (key == NULL || in == NULL || out == NULL || inLen == 0 || outLen < + (word32)key->n.used) { + return BAD_FUNC_ARG; + } + +#ifdef HAVE_CAVIUM_V + ret = CspPkcs1v15CrtEnc(key->asyncDev.dev.devId, CAVIUM_REQ_MODE, CAVIUM_SSL_GRP, CAVIUM_DPORT, + BT1, key->n.used, (word16)inLen, + key->q.dpraw, key->dQ.dpraw, key->p.dpraw, key->dP.dpraw, key->u.dpraw, + (byte*)in, out, &key->asyncDev.dev.reqId); +#else + ret = CspPkcs1v15CrtEnc(CAVIUM_REQ_MODE, BT1, key->n.used, (word16)inLen, + key->q.dpraw, key->dQ.dpraw, key->p.dpraw, key->dP.dpraw, key->u.dpraw, + (byte*)in, out, &key->asyncDev.dev.reqId, key->asyncDev.dev.devId); +#endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + return key->n.used; +} + + +int NitroxRsaSSL_Verify(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) +{ + word32 ret; + word16 outSz = (word16)outLen; + + if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->n.used) { + return BAD_FUNC_ARG; + } + +#ifdef HAVE_CAVIUM_V + ret = CspPkcs1v15Dec(key->asyncDev.dev.devId, CAVIUM_REQ_MODE, CAVIUM_SSL_GRP, CAVIUM_DPORT, + BT1, key->n.used, key->e.used, + key->n.dpraw, key->e.dpraw, (byte*)in, &outSz, out, + &key->asyncDev.dev.reqId); +#else + ret = CspPkcs1v15Dec(CAVIUM_REQ_MODE, BT1, key->n.used, key->e.used, + key->n.dpraw, key->e.dpraw, (byte*)in, &outSz, out, + &key->asyncDev.dev.reqId, key->asyncDev.dev.devId); +#endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + outSz = ntohs(outSz); + + return outSz; +} +#endif /* !NO_RSA */ + + +#ifndef NO_AES +int NitroxAesSetKey(Aes* aes, const byte* key, word32 length, const byte* iv) +{ + if (aes == NULL) + return BAD_FUNC_ARG; + + XMEMCPY(aes->key, key, length); /* key still holds key, iv still in reg */ + if (length == 16) + aes->type = AES_128_BIT; + else if (length == 24) + aes->type = AES_192_BIT; + else if (length == 32) + aes->type = AES_256_BIT; + + return wc_AesSetIV(aes, iv); +} + +#ifdef HAVE_AES_CBC +int NitroxAesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 length) +{ + int ret; + wolfssl_word offset = 0; + + while (length > WOLFSSL_MAX_16BIT) { + word16 slen = (word16)WOLFSSL_MAX_16BIT; + #ifdef HAVE_CAVIUM_V + ret = CspEncryptAes(aes->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, aes->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, AES_CBC, aes->type, (byte*)aes->key, + (byte*)aes->reg, 0, NULL, slen, (byte*)in + offset, + out + offset, &aes->asyncDev.dev.reqId); + #else + ret = CspEncryptAes(CAVIUM_BLOCKING, aes->asyncDev.dev.contextHandle, CAVIUM_NO_UPDATE, + aes->type, slen, (byte*)in + offset, out + offset, + (byte*)aes->reg, (byte*)aes->key, &aes->asyncDev.dev.reqId, + aes->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + length -= WOLFSSL_MAX_16BIT; + offset += WOLFSSL_MAX_16BIT; + XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + if (length) { + word16 slen = (word16)length; + #ifdef HAVE_CAVIUM_V + ret = CspEncryptAes(aes->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, aes->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, AES_CBC, aes->type, (byte*)aes->key, + (byte*)aes->reg, 0, NULL, slen, (byte*)in + offset, + out + offset, &aes->asyncDev.dev.reqId); + #else + ret = CspEncryptAes(CAVIUM_BLOCKING, aes->asyncDev.dev.contextHandle, CAVIUM_NO_UPDATE, + aes->type, slen, (byte*)in + offset, out + offset, + (byte*)aes->reg, (byte*)aes->key, &aes->asyncDev.dev.reqId, + aes->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + XMEMCPY(aes->reg, out + offset+length - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + return 0; +} + +#ifdef HAVE_AES_DECRYPT +int NitroxAesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 length) +{ + wolfssl_word offset = 0; + int ret; + + while (length > WOLFSSL_MAX_16BIT) { + word16 slen = (word16)WOLFSSL_MAX_16BIT; + XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + #ifdef HAVE_CAVIUM_V + ret = CspDecryptAes(aes->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, aes->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, AES_CBC, aes->type, (byte*)aes->key, (byte*)aes->reg, + 0, NULL, slen, (byte*)in + offset, out + offset, &aes->asyncDev.dev.reqId); + #else + ret = CspDecryptAes(CAVIUM_BLOCKING, aes->asyncDev.dev.contextHandle, CAVIUM_NO_UPDATE, + aes->type, slen, (byte*)in + offset, out + offset, + (byte*)aes->reg, (byte*)aes->key, &aes->asyncDev.dev.reqId, + aes->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + length -= WOLFSSL_MAX_16BIT; + offset += WOLFSSL_MAX_16BIT; + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + } + if (length) { + word16 slen = (word16)length; + XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + #ifdef HAVE_CAVIUM_V + ret = CspDecryptAes(aes->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, aes->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, AES_CBC, aes->type, (byte*)aes->key, (byte*)aes->reg, + 0, NULL, slen, (byte*)in + offset, out + offset, &aes->asyncDev.dev.reqId); + #else + ret = CspDecryptAes(CAVIUM_BLOCKING, aes->asyncDev.dev.contextHandle, CAVIUM_NO_UPDATE, + aes->type, slen, (byte*)in + offset, out + offset, + (byte*)aes->reg, (byte*)aes->key, &aes->asyncDev.dev.reqId, + aes->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + } + return 0; +} +#endif /* HAVE_AES_DECRYPT */ +#endif /* HAVE_AES_CBC */ +#endif /* !NO_AES */ + + +#if !defined(NO_ARC4) && !defined(HAVE_CAVIUM_V) +void NitroxArc4SetKey(Arc4* arc4, const byte* key, word32 length) +{ + if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->asyncDev.dev.contextHandle, length, + (byte*)key, &arc4->asyncDev.dev.reqId, arc4->devId) != 0) { + WOLFSSL_MSG("Bad Cavium Arc4 Init"); + } +} + +void NitroxArc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) +{ + int ret; + wolfssl_word offset = 0; + + while (length > WOLFSSL_MAX_16BIT) { + word16 slen = (word16)WOLFSSL_MAX_16BIT; + ret = CspEncryptRc4(CAVIUM_BLOCKING, arc4->asyncDev.dev.contextHandle, + CAVIUM_UPDATE, slen, (byte*)in + offset, out + offset, + &arc4->asyncDev.dev.reqId, arc4->devId); + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + length -= WOLFSSL_MAX_16BIT; + offset += WOLFSSL_MAX_16BIT; + } + if (length) { + word16 slen = (word16)length; + ret = CspEncryptRc4(CAVIUM_BLOCKING, arc4->asyncDev.dev.contextHandle, + CAVIUM_UPDATE, slen, (byte*)in + offset, out + offset, + &arc4->asyncDev.dev.reqId, arc4->devId); + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + } +} +#endif /* !NO_ARC4 && !HAVE_CAVIUM_V */ + + +#ifndef NO_DES3 +int NitroxDes3SetKey(Des3* des3, const byte* key, const byte* iv) +{ + if (des3 == NULL) + return BAD_FUNC_ARG; + + /* key[0] holds key, iv in reg */ + XMEMCPY(des3->key[0], key, DES_BLOCK_SIZE*3); + + return wc_Des3_SetIV(des3, iv); +} + +int NitroxDes3CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 length) +{ + wolfssl_word offset = 0; + int ret; + + while (length > WOLFSSL_MAX_16BIT) { + word16 slen = (word16)WOLFSSL_MAX_16BIT; + #ifdef HAVE_CAVIUM_V + ret = CspEncrypt3Des(des3->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, des3->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, DES3_CBC, (byte*)des3->key[0], + (byte*)des3->reg, slen, (byte*)in + offset, + out + offset, &des3->asyncDev.dev.reqId); + #else + ret = CspEncrypt3Des(CAVIUM_BLOCKING, des3->asyncDev.dev.contextHandle, + CAVIUM_NO_UPDATE, slen, (byte*)in + offset, + out + offset, (byte*)des3->reg, (byte*)des3->key[0], + &des3->asyncDev.dev.reqId, des3->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + length -= WOLFSSL_MAX_16BIT; + offset += WOLFSSL_MAX_16BIT; + XMEMCPY(des3->reg, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + } + if (length) { + word16 slen = (word16)length; + #ifdef HAVE_CAVIUM_V + ret = CspEncrypt3Des(des3->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, des3->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, DES3_CBC, (byte*)des3->key[0], (byte*)des3->reg, + slen, (byte*)in + offset, out + offset, + &des3->asyncDev.dev.reqId); + #else + ret = CspEncrypt3Des(CAVIUM_BLOCKING, des3->asyncDev.dev.contextHandle, + CAVIUM_NO_UPDATE, slen, (byte*)in + offset, + out + offset, (byte*)des3->reg, (byte*)des3->key[0], + &des3->asyncDev.dev.reqId, des3->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + XMEMCPY(des3->reg, out+offset+length - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + } + return 0; +} + +int NitroxDes3CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 length) +{ + wolfssl_word offset = 0; + int ret; + + while (length > WOLFSSL_MAX_16BIT) { + word16 slen = (word16)WOLFSSL_MAX_16BIT; + XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + #ifdef HAVE_CAVIUM_V + ret = CspDecrypt3Des(des3->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, des3->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, DES3_CBC, (byte*)des3->key[0], (byte*)des3->reg, + slen, (byte*)in + offset, out + offset, + &des3->asyncDev.dev.reqId); + #else + ret = CspDecrypt3Des(CAVIUM_BLOCKING, des3->asyncDev.dev.contextHandle, + CAVIUM_NO_UPDATE, slen, (byte*)in + offset, out + offset, + (byte*)des3->reg, (byte*)des3->key[0], &des3->asyncDev.dev.reqId, + des3->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + length -= WOLFSSL_MAX_16BIT; + offset += WOLFSSL_MAX_16BIT; + XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE); + } + if (length) { + word16 slen = (word16)length; + XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE,DES_BLOCK_SIZE); + #ifdef HAVE_CAVIUM_V + ret = CspDecrypt3Des(des3->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, des3->asyncDev.dev.contextHandle, + FROM_DPTR, FROM_CTX, DES3_CBC, (byte*)des3->key[0], (byte*)des3->reg, + slen, (byte*)in + offset, out + offset, + &des3->asyncDev.dev.reqId); + #else + ret = CspDecrypt3Des(CAVIUM_BLOCKING, des3->asyncDev.dev.contextHandle, + CAVIUM_NO_UPDATE, slen, (byte*)in + offset, out + offset, + (byte*)des3->reg, (byte*)des3->key[0], &des3->asyncDev.dev.reqId, + des3->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE); + } + return 0; +} +#endif /* !NO_DES3 */ + + +#ifndef NO_HMAC +int NitroxHmacFinal(Hmac* hmac, byte* hash) +{ + int ret = -1; + +#ifdef HAVE_CAVIUM_V + word16 hashLen = wc_HmacSizeByType(hmac->macType); + ret = CspHmac(hmac->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, hmac->type, hmac->keyLen, + (byte*)hmac->ipad, hmac->dataLen, hmac->data, hashLen, + hash, &hmac->asyncDev.dev.reqId); +#else + ret = CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen, + (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, + &hmac->asyncDev.dev.reqId, hmac->asyncDev.dev.devId); +#endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + hmac->innerHashKeyed = 0; /* tell update to start over if used again */ + + return 0; +} + +int NitroxHmacUpdate(Hmac* hmac, const byte* msg, word32 length) +{ + word16 add = (word16)length; + word32 total; + byte* tmp; + + if (length > WOLFSSL_MAX_16BIT) { + WOLFSSL_MSG("Too big msg for cavium hmac"); + return -1; + } + + if (hmac->innerHashKeyed == 0) { /* starting new */ + hmac->dataLen = 0; + hmac->innerHashKeyed = 1; + } + + total = add + hmac->dataLen; + if (total > WOLFSSL_MAX_16BIT) { + WOLFSSL_MSG("Too big msg for cavium hmac"); + return -1; + } + + tmp = XMALLOC(hmac->dataLen + add, NULL, DYNAMIC_TYPE_ASYNC_TMP); + if (tmp == NULL) { + WOLFSSL_MSG("Out of memory for cavium update"); + return -1; + } + if (hmac->dataLen) + XMEMCPY(tmp, hmac->data, hmac->dataLen); + XMEMCPY(tmp + hmac->dataLen, msg, add); + + hmac->dataLen += add; + XFREE(hmac->data, NULL, DYNAMIC_TYPE_ASYNC_TMP); + hmac->data = tmp; + + return 0; +} + +int NitroxHmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) +{ + hmac->macType = (byte)type; + + /* Determine Cavium HashType */ + switch(type) { + #ifndef NO_MD5 + case MD5: + hmac->type = MD5_TYPE; + break; + #endif + #ifndef NO_SHA + case SHA: + hmac->type = SHA1_TYPE; + break; + #endif + #ifndef NO_SHA256 + case SHA256: + #ifdef HAVE_CAVIUM_V + hmac->type = SHA2_SHA256; + #else + hmac->type = SHA256_TYPE; + #endif + break; + #endif + #ifdef HAVE_CAVIUM_V + #ifndef WOLFSSL_SHA512 + case SHA512: + hmac->type = SHA2_SHA512; + break; + #endif + #ifndef WOLFSSL_SHA384 + case SHA384: + hmac->type = SHA2_SHA384; + break; + #endif + #endif /* HAVE_CAVIUM_V */ + default: + WOLFSSL_MSG("unsupported cavium hmac type"); + break; + } + + hmac->innerHashKeyed = 0; /* should we key Startup flag */ + + hmac->keyLen = (word16)length; + /* store key in ipad */ + XMEMCPY(hmac->ipad, key, length); + + return 0; +} +#endif /* !NO_HMAC */ + + +#if !defined(HAVE_HASHDRBG) && !defined(NO_RC4) +void NitroxRngGenerateBlock(WC_RNG* rng, byte* output, word32 sz) +{ + wolfssl_word offset = 0; + word32 requestId; + + while (sz > WOLFSSL_MAX_16BIT) { + word16 slen = (word16)WOLFSSL_MAX_16BIT; + #ifdef HAVE_CAVIUM_V + ret = CspTrueRandom(rng->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, slen, output + offset, &requestId); + #else + ret = CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, + rng->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + sz -= WOLFSSL_MAX_16BIT; + offset += WOLFSSL_MAX_16BIT; + } + if (sz) { + word16 slen = (word16)sz; + #ifdef HAVE_CAVIUM_V + ret = CspTrueRandom(rng->asyncDev.dev.devId, CAVIUM_BLOCKING, DMA_DIRECT_DIRECT, + CAVIUM_SSL_GRP, CAVIUM_DPORT, slen, output + offset, &requestId); + #else + ret = CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, + rng->asyncDev.dev.devId); + #endif + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + } +} +#endif /* !defined(HAVE_HASHDRBG) && !defined(NO_RC4) */ + + +#endif /* WOLFSSL_ASYNC_CRYPT */ + +#endif /* HAVE_CAVIUM */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 4e533cf936..75ba61a8f2 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -47,14 +47,6 @@ int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz) return GenerateSeed(os, seed, sz); } -#ifdef HAVE_CAVIUM - int wc_InitRngCavium(WC_RNG* rng, int i) - { - return InitRngCavium(rng, i); - } -#endif - - int wc_InitRng(WC_RNG* rng) { return InitRng_fips(rng); @@ -178,6 +170,7 @@ int wc_FreeRng(WC_RNG* rng) #define IS_INTEL_RDSEED (cpuid_flags&CPUID_RDSEED) #endif + #if defined(HAVE_HASHDRBG) || defined(NO_RC4) /* Start NIST DRBG code */ @@ -811,12 +804,13 @@ int wc_InitRng(WC_RNG* rng) #endif #ifdef HAVE_INTEL_RDGEN - wc_InitRng_IntelRD() ; - if(IS_INTEL_RDRAND)return 0 ; + wc_InitRng_IntelRD(); + if(IS_INTEL_RDRAND) return 0; #endif -#ifdef HAVE_CAVIUM - if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC) - return 0; + +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + ret = wolfAsync_DevCtxInit(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG, INVALID_DEVID); + if (ret != 0) return ret; #endif #ifdef WOLFSSL_SMALL_STACK @@ -847,10 +841,6 @@ int wc_InitRng(WC_RNG* rng) return ret; } -#ifdef HAVE_CAVIUM - static void CaviumRNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz); -#endif - /* place a generated block in output */ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) { @@ -858,9 +848,10 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) if(IS_INTEL_RDRAND) return wc_GenerateRand_IntelRD(NULL, output, sz) ; #endif -#ifdef HAVE_CAVIUM - if (rng->magic == WOLFSSL_RNG_CAVIUM_MAGIC) - return CaviumRNG_GenerateBlock(rng, output, sz); +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RNG) { + return NitroxRngGenerateBlock(rng, output, sz); + } #endif XMEMSET(output, 0, sz); wc_Arc4Process(&rng->cipher, output, output, sz); @@ -878,53 +869,14 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) int wc_FreeRng(WC_RNG* rng) { (void)rng; - return 0; -} - -#ifdef HAVE_CAVIUM - -#include -#include "cavium_common.h" - -/* Initialize RNG for use with Nitrox device */ -int wc_InitRngCavium(WC_RNG* rng, int devId) -{ - if (rng == NULL) - return -1; - - rng->devId = devId; - rng->magic = WOLFSSL_RNG_CAVIUM_MAGIC; +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + wolfAsync_DevCtxFree(&rng->asyncDev); +#endif return 0; } - -static void CaviumRNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) -{ - wolfssl_word offset = 0; - word32 requestId; - - while (sz > WOLFSSL_MAX_16BIT) { - word16 slen = (word16)WOLFSSL_MAX_16BIT; - if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, - rng->devId) != 0) { - WOLFSSL_MSG("Cavium RNG failed"); - } - sz -= WOLFSSL_MAX_16BIT; - offset += WOLFSSL_MAX_16BIT; - } - if (sz) { - word16 slen = (word16)sz; - if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, - rng->devId) != 0) { - WOLFSSL_MSG("Cavium RNG failed"); - } - } -} - -#endif /* HAVE_CAVIUM */ - #endif /* HAVE_HASHDRBG || NO_RC4 */ @@ -1127,7 +1079,7 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) return 0; } -#else +#else /* HAVE_HASHDRBG || NO_RC4 */ /* return 0 on success */ static INLINE int IntelRDrand32(unsigned int *rnd) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index e34e17c85a..f960b67ec9 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -32,18 +32,34 @@ /* Possible RSA enable options: - * NO_RSA: Overall control of RSA default: off - * WC_RSA_BLINDING: Uses Blinding w/ Private Ops slower by ~20% default: off + * NO_RSA: Overall control of RSA default: on (not defined) + * WC_RSA_BLINDING: Uses Blinding w/ Private Ops default: off + Note: slower by ~20% * WOLFSSL_KEY_GEN: Allows Private Key Generation default: off * RSA_LOW_MEM: NON CRT Private Operations, less memory default: off + * WC_NO_RSA_OAEP: Disables RSA OAEP padding default: on (not defined) + */ +/* +RSA Key Size Configuration: + * FP_MAX_BITS: With USE_FAST_MATH only default: 4096 + If USE_FAST_MATH then use this to override default. + Value is key size * 2. Example: RSA 3072 = 6144 +*/ + + #ifdef HAVE_FIPS int wc_InitRsaKey(RsaKey* key, void* ptr) { return InitRsaKey_fips(key, ptr); } +int wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId) +{ + (void)devId; + return InitRsaKey_fips(key, ptr); +} int wc_FreeRsaKey(RsaKey* key) { @@ -112,25 +128,13 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, #endif -#ifdef HAVE_CAVIUM - int wc_RsaInitCavium(RsaKey* key, int i) - { - return RsaInitCavium(key, i); - } - - - void wc_RsaFreeCavium(RsaKey* key) - { - RsaFreeCavium(key); - } -#endif - /* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c * wc_RsaPrivateKeyDecode * wc_RsaPublicKeyDecode */ #else /* else build without fips */ + #include #include #include @@ -141,91 +145,132 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, #include #endif -#ifdef HAVE_CAVIUM - static int InitCaviumRsaKey(RsaKey* key, void* heap); - static int FreeCaviumRsaKey(RsaKey* key); - static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key); - static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key); - static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key); - static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key); -#endif +#define ERROR_OUT(x) { ret = (x); goto done;} + + +#ifdef WOLFSSL_ASYNC_CRYPT + static int InitAsyncRsaKey(RsaKey* key); + static int FreeAsyncRsaKey(RsaKey* key); +#endif /* WOLFSSL_ASYNC_CRYPT */ enum { - RSA_PUBLIC_ENCRYPT = 0, - RSA_PUBLIC_DECRYPT = 1, - RSA_PRIVATE_ENCRYPT = 2, - RSA_PRIVATE_DECRYPT = 3, + RSA_STATE_NONE = 0, - RSA_BLOCK_TYPE_1 = 1, - RSA_BLOCK_TYPE_2 = 2, + RSA_STATE_ENCRYPT_PAD, + RSA_STATE_ENCRYPT_EXPTMOD, + RSA_STATE_ENCRYPT_RES, - RSA_MIN_SIZE = 512, - RSA_MAX_SIZE = 4096, - - RSA_MIN_PAD_SZ = 11 /* separator + 0 + pad value + 8 pads */ + RSA_STATE_DECRYPT_EXPTMOD, + RSA_STATE_DECRYPT_UNPAD, + RSA_STATE_DECRYPT_RES, }; +static void wc_RsaCleanup(RsaKey* key) +{ + if (key && key->tmp) { + /* make sure any allocated memory is free'd */ + if (key->tmpIsAlloc) { + if (key->type == RSA_PRIVATE_DECRYPT || + key->type == RSA_PRIVATE_ENCRYPT) { + ForceZero(key->tmp, key->tmpLen); + } + XFREE(key->tmp, key->heap, DYNAMIC_TYPE_RSA); + key->tmpIsAlloc = 0; + } + key->tmp = NULL; + key->tmpLen = 0; + } +} + +int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) +{ + int ret = 0; + + if (key == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + + key->type = RSA_TYPE_UNKNOWN; + key->state = RSA_STATE_NONE; + key->heap = heap; + key->tmp = NULL; + key->tmpLen = 0; + key->tmpIsAlloc = 0; +#ifdef WC_RSA_BLINDING + key->rng = NULL; +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + if (devId != INVALID_DEVID) { + /* handle as async */ + ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA, + devId); + if (ret == 0) { + ret = InitAsyncRsaKey(key); + } + } + else +#endif + { + /* For normal math defer the memory allocations */ + #ifndef USE_FAST_MATH + key->n.dp = key->e.dp = 0; /* public alloc parts */ + key->d.dp = key->p.dp = 0; /* private alloc parts */ + key->q.dp = key->dP.dp = 0; + key->u.dp = key->dQ.dp = 0; + #else + mp_init(&key->n); + mp_init(&key->e); + mp_init(&key->d); + mp_init(&key->p); + mp_init(&key->q); + mp_init(&key->dP); + mp_init(&key->dQ); + mp_init(&key->u); + #endif /* USE_FAST_MATH */ + } + + return ret; +} int wc_InitRsaKey(RsaKey* key, void* heap) { -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return InitCaviumRsaKey(key, heap); -#endif - - key->type = -1; /* haven't decided yet */ - key->heap = heap; - -/* TomsFastMath doesn't use memory allocation */ -#ifndef USE_FAST_MATH - key->n.dp = key->e.dp = 0; /* public alloc parts */ - - key->d.dp = key->p.dp = 0; /* private alloc parts */ - key->q.dp = key->dP.dp = 0; - key->u.dp = key->dQ.dp = 0; -#else - mp_init(&key->n); - mp_init(&key->e); - mp_init(&key->d); - mp_init(&key->p); - mp_init(&key->q); - mp_init(&key->dP); - mp_init(&key->dQ); - mp_init(&key->u); -#endif - - return 0; + return wc_InitRsaKey_ex(key, heap, INVALID_DEVID); } - int wc_FreeRsaKey(RsaKey* key) { - (void)key; + int ret = 0; - if (key == NULL) - return 0; - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return FreeCaviumRsaKey(key); -#endif - - if (key->type == RSA_PRIVATE) { - mp_forcezero(&key->u); - mp_forcezero(&key->dQ); - mp_forcezero(&key->dP); - mp_forcezero(&key->q); - mp_forcezero(&key->p); - mp_forcezero(&key->d); + if (key == NULL) { + return BAD_FUNC_ARG; } - mp_clear(&key->e); - mp_clear(&key->n); - return 0; + wc_RsaCleanup(key); + +#ifdef WOLFSSL_ASYNC_CRYPT + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + ret = FreeAsyncRsaKey(key); + wolfAsync_DevCtxFree(&key->asyncDev); + } + else +#endif + { + if (key->type == RSA_PRIVATE) { + mp_forcezero(&key->u); + mp_forcezero(&key->dQ); + mp_forcezero(&key->dP); + mp_forcezero(&key->q); + mp_forcezero(&key->p); + mp_forcezero(&key->d); + } + mp_clear(&key->e); + mp_clear(&key->n); + } + + return ret; } @@ -237,8 +282,8 @@ int wc_FreeRsaKey(RsaKey* key) out: mask output after generation outSz: size of output buffer */ -static int wc_MGF1(enum wc_HashType hType, byte* seed, word32 seedSz, - byte* out, word32 outSz, void* heap) +static int RsaMGF1(enum wc_HashType hType, byte* seed, word32 seedSz, + byte* out, word32 outSz, void* heap) { byte* tmp; /* needs to be large enough for seed size plus counter(4) */ @@ -301,8 +346,7 @@ static int wc_MGF1(enum wc_HashType hType, byte* seed, word32 seedSz, out[idx++] = tmp[i]; } counter++; - } - while (idx < outSz); + } while (idx < outSz); /* check for if dynamic memory was needed, then free */ if (tmpF) { @@ -312,41 +356,37 @@ static int wc_MGF1(enum wc_HashType hType, byte* seed, word32 seedSz, return 0; } - /* helper function to direct which mask generation function is used switeched on type input */ -static int wc_MGF(int type, byte* seed, word32 seedSz, - byte* out, word32 outSz, void* heap) +static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out, + word32 outSz, void* heap) { int ret; switch(type) { - #ifndef NO_SHA + #ifndef NO_SHA case WC_MGF1SHA1: - ret = wc_MGF1(WC_HASH_TYPE_SHA, seed, seedSz, out, outSz, heap); - break; - #endif - #ifndef NO_SHA256 + ret = RsaMGF1(WC_HASH_TYPE_SHA, seed, seedSz, out, outSz, heap); + break; + #endif + #ifndef NO_SHA256 case WC_MGF1SHA256: - ret = wc_MGF1(WC_HASH_TYPE_SHA256, seed, seedSz, - out, outSz, heap); - break; - #endif - #ifdef WOLFSSL_SHA512 - #ifdef WOLFSSL_SHA384 + ret = RsaMGF1(WC_HASH_TYPE_SHA256, seed, seedSz, out, outSz, heap); + break; + #endif + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SHA384 case WC_MGF1SHA384: - ret = wc_MGF1(WC_HASH_TYPE_SHA384, seed, seedSz, - out, outSz, heap); - break; - #endif + ret = RsaMGF1(WC_HASH_TYPE_SHA384, seed, seedSz, out, outSz, heap); + break; + #endif case WC_MGF1SHA512: - ret = wc_MGF1(WC_HASH_TYPE_SHA512, seed, seedSz, - out, outSz, heap); - break; - #endif + ret = RsaMGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz, heap); + break; + #endif default: - WOLFSSL_MSG("Unknown MGF function: check build options"); + WOLFSSL_MSG("Unknown MGF type: check build options"); ret = BAD_FUNC_ARG; } @@ -359,12 +399,15 @@ static int wc_MGF(int type, byte* seed, word32 seedSz, return ret; } +#endif /* !WC_NO_RSA_OAEP */ -static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, - word32 pkcsBlockLen, byte padValue, WC_RNG* rng, - enum wc_HashType hType, int mgf, byte* optLabel, - word32 labelLen, void* heap) +/* Padding */ +#ifndef WC_NO_RSA_OAEP +static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, + word32 pkcsBlockLen, byte padValue, WC_RNG* rng, + enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen, + void* heap) { int ret; int hLen; @@ -383,8 +426,7 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, byte seed[ WC_MAX_DIGEST_SIZE]; #endif - /* can use with no lable but catch if no lable provided while having - length > 0 */ + /* no label is allowed, but catch if no label provided and length > 0 */ if (optLabel == NULL && labelLen > 0) { return BUFFER_E; } @@ -396,13 +438,13 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, } #ifdef WOLFSSL_SMALL_STACK - lHash = (byte*)XMALLOC(hLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + lHash = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_TMP_BUFFER); if (lHash == NULL) { return MEMORY_E; } - seed = (byte*)XMALLOC(hLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + seed = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_TMP_BUFFER); if (seed == NULL) { - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #else @@ -417,8 +459,8 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, if ((ret = wc_Hash(hType, optLabel, labelLen, lHash, hLen)) != 0) { WOLFSSL_MSG("OAEP hash type possibly not supported or lHash to small"); #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } @@ -434,8 +476,8 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, if ((word32)(2 * hLen + 2) > pkcsBlockLen) { WOLFSSL_MSG("OAEP pad error hash to big for RSA key size"); #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return BAD_FUNC_ARG; } @@ -443,8 +485,8 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, if (inputLen > (pkcsBlockLen - 2 * hLen - 2)) { WOLFSSL_MSG("OAEP pad error message too long"); #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return BAD_FUNC_ARG; } @@ -454,8 +496,8 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, psLen = pkcsBlockLen - inputLen - 2 * hLen - 2; if (pkcsBlockLen < inputLen) { /*make sure not writing over end of buffer */ #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return BUFFER_E; } @@ -472,8 +514,8 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, /* generate random seed */ if ((ret = wc_RNG_GenerateBlock(rng, seed, hLen)) != 0) { #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } @@ -482,19 +524,19 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, dbMask = (byte*)XMALLOC(pkcsBlockLen - hLen - 1, heap, DYNAMIC_TYPE_RSA); if (dbMask == NULL) { #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return MEMORY_E; } XMEMSET(dbMask, 0, pkcsBlockLen - hLen - 1); /* help static analyzer */ - ret = wc_MGF(mgf, seed, hLen, dbMask, pkcsBlockLen - hLen - 1, heap); + ret = RsaMGF(mgf, seed, hLen, dbMask, pkcsBlockLen - hLen - 1, heap); if (ret != 0) { XFREE(dbMask, heap, DYNAMIC_TYPE_RSA); #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } @@ -512,11 +554,11 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, idx = 0; pkcsBlock[idx++] = 0x00; /* create seedMask inline */ - if ((ret = wc_MGF(mgf, pkcsBlock + hLen + 1, pkcsBlockLen - hLen - 1, - pkcsBlock + 1, hLen, heap)) != 0) { + if ((ret = RsaMGF(mgf, pkcsBlock + hLen + 1, pkcsBlockLen - hLen - 1, + pkcsBlock + 1, hLen, heap)) != 0) { #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } @@ -529,20 +571,21 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, } #ifdef WOLFSSL_SMALL_STACK - XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif (void)padValue; return 0; } -#endif /* WC_NO_RSA_OAEP */ +#endif /* !WC_NO_RSA_OAEP */ -static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, - word32 pkcsBlockLen, byte padValue, WC_RNG* rng) +static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, + word32 pkcsBlockLen, byte padValue, WC_RNG* rng) { - if (inputLen == 0 || pkcsBlockLen == 0) { + if (input == NULL || inputLen == 0 || pkcsBlock == NULL || + pkcsBlockLen == 0) { return BAD_FUNC_ARG; } @@ -552,6 +595,7 @@ static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, if (padValue == RSA_BLOCK_TYPE_1) { if (pkcsBlockLen < inputLen + 2) { + WOLFSSL_MSG("RsaPad error, invalid length"); return RSA_PAD_E; } @@ -564,17 +608,20 @@ static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, int ret; if (pkcsBlockLen < inputLen + 1) { + WOLFSSL_MSG("RsaPad error, invalid length"); return RSA_PAD_E; } padLen = pkcsBlockLen - inputLen - 1; ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); - if (ret != 0) + if (ret != 0) { return ret; + } /* remove zeros */ - for (i = 1; i < padLen; i++) + for (i = 1; i < padLen; i++) { if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01; + } } pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */ @@ -583,37 +630,35 @@ static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, return 0; } - -#ifndef WC_NO_RSA_OAEP /* helper function to direct which padding is used */ static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock, - word32 pkcsBlockLen, byte padValue, WC_RNG* rng, - int padType, enum wc_HashType hType, int mgf, - byte* optLabel, word32 labelLen, void* heap) + word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType, + enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen, + void* heap) { int ret; switch (padType) { case WC_RSA_PKCSV15_PAD: - WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding"); - ret = wc_RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen, - padValue, rng); + //WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding"); + ret = RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen, + padValue, rng); break; + #ifndef WC_NO_RSA_OAEP case WC_RSA_OAEP_PAD: - WOLFSSL_MSG("wolfSSL Using RSA OAEP padding"); - ret = wc_RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen, - padValue, rng, hType, mgf, optLabel, labelLen, heap); + //WOLFSSL_MSG("wolfSSL Using RSA OAEP padding"); + ret = RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen, + padValue, rng, hType, mgf, optLabel, labelLen, heap); break; - + #endif default: WOLFSSL_MSG("Unknown RSA Pad Type"); ret = RSA_PAD_E; } /* silence warning if not used with padding scheme */ - (void)padType; (void)hType; (void)mgf; (void)optLabel; @@ -624,9 +669,11 @@ static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock, } +/* UnPadding */ +#ifndef WC_NO_RSA_OAEP /* UnPad plaintext, set start to *output, return length of plaintext, * < 0 on error */ -static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, +static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, byte **output, enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen, void* heap) { @@ -636,6 +683,11 @@ static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, byte* tmp; word32 idx; + /* no label is allowed, but catch if no label provided and length > 0 */ + if (optLabel == NULL && labelLen > 0) { + return BUFFER_E; + } + hLen = wc_HashGetDigestSize(hType); if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) { return BAD_FUNC_ARG; @@ -648,9 +700,9 @@ static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, XMEMSET(tmp, 0, pkcsBlockLen); /* find seedMask value */ - if ((ret = wc_MGF(mgf, (byte*)(pkcsBlock + (hLen + 1)), - pkcsBlockLen - hLen - 1, tmp, hLen, heap)) != 0) { - XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER); + if ((ret = RsaMGF(mgf, (byte*)(pkcsBlock + (hLen + 1)), + pkcsBlockLen - hLen - 1, tmp, hLen, heap)) != 0) { + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; } @@ -660,9 +712,9 @@ static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, } /* get dbMask value */ - if ((ret = wc_MGF(mgf, tmp, hLen, tmp + hLen, - pkcsBlockLen - hLen - 1, heap)) != 0) { - XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER); + if ((ret = RsaMGF(mgf, tmp, hLen, tmp + hLen, + pkcsBlockLen - hLen - 1, heap)) != 0) { + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; } @@ -708,19 +760,20 @@ static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, /* UnPad plaintext, set start to *output, return length of plaintext, * < 0 on error */ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, - byte **output, byte padValue) + byte **output, byte padValue) { - word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0, - invalid = 0, - i = 1, - outputLen; + word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0; + word32 invalid = 0; + word32 i = 1; + word32 outputLen; - if (pkcsBlockLen == 0) { + if (output == NULL || pkcsBlockLen == 0) { return BAD_FUNC_ARG; } - if (pkcsBlock[0] != 0x0) /* skip past zero */ + if (pkcsBlock[0] != 0x0) { /* skip past zero */ invalid = 1; + } pkcsBlock++; pkcsBlockLen--; /* Require block type padValue */ @@ -751,8 +804,6 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, return outputLen; } - -#ifndef WC_NO_RSA_OAEP /* helper function to direct unpadding */ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out, byte padValue, int padType, enum wc_HashType hType, @@ -767,19 +818,20 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out, ret = RsaUnPad(pkcsBlock, pkcsBlockLen, out, padValue); break; + #ifndef WC_NO_RSA_OAEP case WC_RSA_OAEP_PAD: WOLFSSL_MSG("wolfSSL Using RSA OAEP padding"); - ret = wc_RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out, - hType, mgf, optLabel, labelLen, heap); + ret = RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out, + hType, mgf, optLabel, labelLen, heap); break; + #endif default: - WOLFSSL_MSG("Unknown RSA Pad Type"); + WOLFSSL_MSG("Unknown RSA UnPad Type"); ret = RSA_PAD_E; } /* silence warning if not used with padding scheme */ - (void)padType; (void)hType; (void)mgf; (void)optLabel; @@ -788,7 +840,6 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out, return ret; } -#endif /* WC_NO_RSA_OAEP */ #ifdef WC_RSA_BLINDING @@ -856,11 +907,9 @@ static int mp_rand(mp_int* a, int digits, WC_RNG* rng) #endif /* WC_RSA_BLINGING */ -static int wc_RsaFunction(const byte* in, word32 inLen, byte* out, +static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, word32* outLen, int type, RsaKey* key, WC_RNG* rng) { - #define ERROR_OUT(x) { ret = (x); goto done;} - mp_int tmp; #ifdef WC_RSA_BLINDING mp_int rnd, rndi; @@ -885,92 +934,100 @@ static int wc_RsaFunction(const byte* in, word32 inLen, byte* out, if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY) ERROR_OUT(MP_READ_E); - if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { - #ifdef WC_RSA_BLINDING - /* blind */ - ret = mp_rand(&rnd, get_digit_count(&key->n), rng); - if (ret != MP_OKAY) - ERROR_OUT(ret); + switch(type) { + case RSA_PRIVATE_DECRYPT: + case RSA_PRIVATE_ENCRYPT: + { + #ifdef WC_RSA_BLINDING + /* blind */ + ret = mp_rand(&rnd, get_digit_count(&key->n), rng); + if (ret != MP_OKAY) + ERROR_OUT(ret); - /* rndi = 1/rnd mod n */ - if (mp_invmod(&rnd, &key->n, &rndi) != MP_OKAY) - ERROR_OUT(MP_INVMOD_E); + /* rndi = 1/rnd mod n */ + if (mp_invmod(&rnd, &key->n, &rndi) != MP_OKAY) + ERROR_OUT(MP_INVMOD_E); - /* rnd = rnd^e */ - if (mp_exptmod(&rnd, &key->e, &key->n, &rnd) != MP_OKAY) - ERROR_OUT(MP_EXPTMOD_E); + /* rnd = rnd^e */ + if (mp_exptmod(&rnd, &key->e, &key->n, &rnd) != MP_OKAY) + ERROR_OUT(MP_EXPTMOD_E); - /* tmp = tmp*rnd mod n */ - if (mp_mulmod(&tmp, &rnd, &key->n, &tmp) != MP_OKAY) - ERROR_OUT(MP_MULMOD_E); - #endif /* WC_RSA_BLINGING */ + /* tmp = tmp*rnd mod n */ + if (mp_mulmod(&tmp, &rnd, &key->n, &tmp) != MP_OKAY) + ERROR_OUT(MP_MULMOD_E); + #endif /* WC_RSA_BLINGING */ - #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */ - if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY) - ERROR_OUT(MP_EXPTMOD_E); - #else - #define INNER_ERROR_OUT(x) { ret = (x); goto inner_done; } + #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */ + if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY) + ERROR_OUT(MP_EXPTMOD_E); + #else + #define INNER_ERROR_OUT(x) { ret = (x); goto inner_done; } + + { /* tmpa/b scope */ + mp_int tmpa, tmpb; - { /* tmpa/b scope */ - mp_int tmpa, tmpb; + if (mp_init(&tmpa) != MP_OKAY) + ERROR_OUT(MP_INIT_E); - if (mp_init(&tmpa) != MP_OKAY) - ERROR_OUT(MP_INIT_E); - - if (mp_init(&tmpb) != MP_OKAY) { - mp_clear(&tmpa); - ERROR_OUT(MP_INIT_E); - } - - /* tmpa = tmp^dP mod p */ - if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY) - INNER_ERROR_OUT(MP_EXPTMOD_E); - - /* tmpb = tmp^dQ mod q */ - if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY) - INNER_ERROR_OUT(MP_EXPTMOD_E); - - /* tmp = (tmpa - tmpb) * qInv (mod p) */ - if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY) - INNER_ERROR_OUT(MP_SUB_E); - - if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY) - INNER_ERROR_OUT(MP_MULMOD_E); - - /* tmp = tmpb + q * tmp */ - if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY) - INNER_ERROR_OUT(MP_MUL_E); - - if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY) - INNER_ERROR_OUT(MP_ADD_E); - - inner_done: + if (mp_init(&tmpb) != MP_OKAY) { mp_clear(&tmpa); - mp_clear(&tmpb); + ERROR_OUT(MP_INIT_E); + } - if (ret != 0) { - goto done; - } - } /* tmpa/b scope */ + /* tmpa = tmp^dP mod p */ + if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); - #endif /* RSA_LOW_MEM */ + /* tmpb = tmp^dQ mod q */ + if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); - #ifdef WC_RSA_BLINDING - /* unblind */ - if (mp_mulmod(&tmp, &rndi, &key->n, &tmp) != MP_OKAY) - ERROR_OUT(MP_MULMOD_E); - #endif /* WC_RSA_BLINDING */ + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_SUB_E); + + if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_MULMOD_E); + + /* tmp = tmpb + q * tmp */ + if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_MUL_E); + + if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_ADD_E); + + inner_done: + mp_clear(&tmpa); + mp_clear(&tmpb); + + if (ret != 0) { + goto done; + } + #undef INNER_ERROR_OUT + } /* tmpa/b scope */ + #endif /* RSA_LOW_MEM */ + + #ifdef WC_RSA_BLINDING + /* unblind */ + if (mp_mulmod(&tmp, &rndi, &key->n, &tmp) != MP_OKAY) + ERROR_OUT(MP_MULMOD_E); + #endif /* WC_RSA_BLINDING */ + + break; } - else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) { + case RSA_PUBLIC_ENCRYPT: + case RSA_PUBLIC_DECRYPT: if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY) ERROR_OUT(MP_EXPTMOD_E); - } - else + break; + default: ERROR_OUT(RSA_WRONG_TYPE_E); + } - keyLen = mp_unsigned_bin_size(&key->n); - if (keyLen > *outLen) + keyLen = wc_RsaEncryptSize(key); + if (keyLen > *outLen) { ERROR_OUT(RSA_BUFFER_E); + } len = mp_unsigned_bin_size(&tmp); @@ -1000,41 +1057,91 @@ done: return ret; } - -int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, - RsaKey* key, WC_RNG* rng) +#ifdef WOLFSSL_ASYNC_CRYPT +static int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng) { - int sz, ret; + int ret = 0; -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key); -#endif +#ifdef WOLFSSL_ASYNC_CRYPT_TEST + AsyncCryptTestDev* testDev = &key->asyncDev.dev; + if (testDev->type == ASYNC_TEST_NONE) { + testDev->type = ASYNC_TEST_RSA_FUNC; + testDev->rsaFunc.in = in; + testDev->rsaFunc.inSz = inLen; + testDev->rsaFunc.out = out; + testDev->rsaFunc.outSz = outLen; + testDev->rsaFunc.type = type; + testDev->rsaFunc.key = key; + testDev->rsaFunc.rng = rng; + return WC_PENDING_E; + } +#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ - sz = mp_unsigned_bin_size(&key->n); - if (sz > (int)outLen) - return RSA_BUFFER_E; + switch(type) { + case RSA_PRIVATE_DECRYPT: + case RSA_PRIVATE_ENCRYPT: + #ifdef HAVE_CAVIUM + ret = NitroxRsaExptMod(in, inLen, key->d.dpraw, key->d.used, + key->n.dpraw, key->n.used, out, outLen, key); + #elif defined(HAVE_INTEL_QA) + /* TODO: Add support for Intel Quick Assist */ + ret = -1; + #else /* WOLFSSL_ASYNC_CRYPT_TEST */ + ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng); + #endif + break; - if (sz < RSA_MIN_PAD_SZ) { - return WC_KEY_SIZE_E; + case RSA_PUBLIC_ENCRYPT: + case RSA_PUBLIC_DECRYPT: + #ifdef HAVE_CAVIUM + ret = NitroxRsaExptMod(in, inLen, key->e.dpraw, key->e.used, + key->n.dpraw, key->n.used, out, outLen, key); + #elif defined(HAVE_INTEL_QA) + /* TODO: Add support for Intel Quick Assist */ + ret = -1; + #else /* WOLFSSL_ASYNC_CRYPT_TEST */ + ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng); + #endif + break; + + default: + ret = RSA_WRONG_TYPE_E; } - if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) - return RSA_BUFFER_E; + return ret; +} +#endif /* WOLFSSL_ASYNC_CRYPT */ - ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng); - if (ret != 0) - return ret; +int wc_RsaFunction(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng) +{ + int ret; - if ((ret = wc_RsaFunction(out, sz, out, &outLen, - RSA_PUBLIC_ENCRYPT, key, NULL)) < 0) - sz = ret; + if (key == NULL || in == NULL || inLen == 0 || out == NULL || + outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) { + return BAD_FUNC_ARG; + } - return sz; +#ifdef WOLFSSL_ASYNC_CRYPT + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + ret = wc_RsaFunctionAsync(in, inLen, out, outLen, type, key, rng); + } + else +#endif + { + ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng); + } + + if (ret == MP_EXPTMOD_E) { + /* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */ + WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem"); + } + return ret; } -#ifndef WC_NO_RSA_OAEP +/* Internal Wrappers */ /* Gives the option of choosing padding type in : input to be encrypted inLen: length of input buffer @@ -1042,332 +1149,353 @@ int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, outLen: length of encrypted output buffer key : wolfSSL initialized RSA key struct rng : wolfSSL initialized random number struct - type : type of padding to use ie WC_RSA_OAEP_PAD + rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, + RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT + pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2 + pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h mgf : type of mask generation function to use label : optional label labelSz : size of optional label buffer */ -int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key, WC_RNG* rng, int type, - enum wc_HashType hash, int mgf, byte* label, word32 labelSz) +static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key, int rsa_type, + byte pad_value, int pad_type, + enum wc_HashType hash, int mgf, + byte* label, word32 labelSz, WC_RNG* rng) { - int sz, ret; + int ret = BAD_FUNC_ARG, sz; -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key); -#endif + if (in == NULL || inLen == 0 || out == NULL || key == NULL) { + return ret; + } - sz = mp_unsigned_bin_size(&key->n); - if (sz > (int)outLen) + sz = wc_RsaEncryptSize(key); + if (sz > (int)outLen) { return RSA_BUFFER_E; + } if (sz < RSA_MIN_PAD_SZ) { return WC_KEY_SIZE_E; } - if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) { return RSA_BUFFER_E; + } - ret = wc_RsaPad_ex(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng, - type, hash, mgf, label, labelSz, key->heap); - if (ret != 0) + switch (key->state) { + case RSA_STATE_NONE: + case RSA_STATE_ENCRYPT_PAD: + + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + if (rsa_type == RSA_PUBLIC_ENCRYPT && pad_value == RSA_BLOCK_TYPE_2) { + key->state = RSA_STATE_ENCRYPT_RES; + key->tmpLen = key->n.used; + return NitroxRsaPublicEncrypt(in, inLen, out, outLen, key); + } + else if (rsa_type == RSA_PRIVATE_ENCRYPT && pad_value == RSA_BLOCK_TYPE_1) { + key->state = RSA_STATE_ENCRYPT_RES; + key->tmpLen = key->n.used; + return NitroxRsaSSL_Sign(in, inLen, out, outLen, key); + } + } + #endif + + key->state = RSA_STATE_ENCRYPT_EXPTMOD; + + ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, + pad_type, hash, mgf, label, labelSz, key->heap); + if (ret < 0) { + break; + } + /* fall through */ + case RSA_STATE_ENCRYPT_EXPTMOD: + key->state = RSA_STATE_ENCRYPT_RES; + + key->tmpLen = outLen; + ret = wc_RsaFunction(out, sz, out, &key->tmpLen, rsa_type, key, rng); + if (ret < 0) { + break; + } + /* fall through */ + case RSA_STATE_ENCRYPT_RES: + key->state = RSA_STATE_NONE; + ret = key->tmpLen; + break; + + default: + ret = BAD_STATE_E; + } + + /* if async pending then return and skip done cleanup below */ + if (ret == WC_PENDING_E) { return ret; + } - if ((ret = wc_RsaFunction(out, sz, out, &outLen, - RSA_PUBLIC_ENCRYPT, key, NULL)) < 0) - sz = ret; + key->state = RSA_STATE_NONE; - return sz; + return ret; +} + +/* Gives the option of choosing padding type + in : input to be decrypted + inLen: length of input buffer + out: decrypted message + outLen: length of decrypted message in bytes + outPtr: optional inline output pointer (if provided doing inline) + key : wolfSSL initialized RSA key struct + rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, + RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT + pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2 + pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD + hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h + mgf : type of mask generation function to use + label : optional label + labelSz : size of optional label buffer */ +static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, + word32 outLen, byte** outPtr, RsaKey* key, + int rsa_type, byte pad_value, int pad_type, + enum wc_HashType hash, int mgf, + byte* label, word32 labelSz, WC_RNG* rng) +{ + int ret = BAD_FUNC_ARG; + + if (in == NULL || inLen == 0 || out == NULL || key == NULL) { + return ret; + } + + switch (key->state) { + case RSA_STATE_NONE: + case RSA_STATE_DECRYPT_EXPTMOD: + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + key->tmpLen = 0; + if (rsa_type == RSA_PRIVATE_DECRYPT && pad_value == RSA_BLOCK_TYPE_2) { + key->state = RSA_STATE_DECRYPT_RES; + key->tmp = NULL; + ret = NitroxRsaPrivateDecrypt(in, inLen, out, outLen, key); + if (ret > 0) { + if (outPtr) + *outPtr = in; + } + return ret; + } + else if (rsa_type == RSA_PUBLIC_DECRYPT && pad_value == RSA_BLOCK_TYPE_1) { + key->state = RSA_STATE_DECRYPT_RES; + key->tmp = NULL; + return NitroxRsaSSL_Verify(in, inLen, out, outLen, key); + } + } + #endif + + key->state = RSA_STATE_DECRYPT_UNPAD; + + /* verify the tmp ptr is NULL, otherwise indicates bad state */ + if (key->tmp != NULL) { + ERROR_OUT(BAD_STATE_E); + } + + /* if not doing this inline then allocate a buffer for it */ + key->tmpLen = inLen; + if (outPtr == NULL) { + key->tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA); + key->tmpIsAlloc = 1; + if (key->tmp == NULL) { + ERROR_OUT(MEMORY_E); + } + XMEMCPY(key->tmp, in, inLen); + } + else { + key->tmp = out; + } + ret = wc_RsaFunction(key->tmp, inLen, key->tmp, &key->tmpLen, + rsa_type, key, rng); + if (ret < 0) { + break; + } + /* fall through */ + case RSA_STATE_DECRYPT_UNPAD: + { + byte* pad = NULL; + key->state = RSA_STATE_DECRYPT_RES; + ret = wc_RsaUnPad_ex(key->tmp, key->tmpLen, &pad, pad_value, pad_type, + hash, mgf, label, labelSz, key->heap); + if (ret > 0 && ret <= (int)outLen && pad != NULL) { + /* only copy output if not inline */ + if (outPtr == NULL) { + XMEMCPY(out, pad, ret); + } + else { + *outPtr = pad; + } + } + else if (ret >= 0) { + ret = RSA_BUFFER_E; + } + if (ret < 0) { + break; + } + /* fall through */ + } + case RSA_STATE_DECRYPT_RES: + key->state = RSA_STATE_NONE; + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + ret = key->tmpLen; + } + #endif + break; + default: + ret = BAD_STATE_E; + } + + /* if async pending then return and skip done cleanup below */ + if (ret == WC_PENDING_E) { + return ret; + } + +done: + + key->state = RSA_STATE_NONE; + wc_RsaCleanup(key); + + return ret; +} + + +/* Public RSA Functions */ +int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key, WC_RNG* rng) +{ + return RsaPublicEncryptEx(in, inLen, out, outLen, key, + RSA_PUBLIC_ENCRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, + WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); +} + + +#ifndef WC_NO_RSA_OAEP +int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key, WC_RNG* rng, int type, + enum wc_HashType hash, int mgf, byte* label, + word32 labelSz) +{ + return RsaPublicEncryptEx(in, inLen, out, outLen, key, RSA_PUBLIC_ENCRYPT, + RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, rng); } #endif /* WC_NO_RSA_OAEP */ int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) { - int ret; WC_RNG* rng = NULL; - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) { - ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key); - if (ret > 0) - *out = in; - return ret; - } -#endif - #ifdef WC_RSA_BLINDING rng = key->rng; #endif - - if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key, - rng)) < 0) { - return ret; - } - - return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2); + return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, + RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, + WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } #ifndef WC_NO_RSA_OAEP -/* Gives the option of choosing padding type - in : input to be decrypted - inLen: length of input buffer - out: pointer to place of decrypted message - key : wolfSSL initialized RSA key struct - type : type of padding to use ie WC_RSA_OAEP_PAD - hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h - mgf : type of mask generation function to use - label : optional label - labelSz : size of optional label buffer */ int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out, - RsaKey* key, int type, enum wc_HashType hash, int mgf, - byte* label, word32 labelSz) + RsaKey* key, int type, enum wc_HashType hash, + int mgf, byte* label, word32 labelSz) { - int ret; WC_RNG* rng = NULL; - - /* sanity check on arguments */ - if (in == NULL || key == NULL) { - return BAD_FUNC_ARG; - } - - /* check if given a label size but not given a label buffer */ - if (label == NULL && labelSz > 0) { - return BAD_FUNC_ARG; - } - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) { - ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key); - if (ret > 0) - *out = in; - return ret; - } -#endif - #ifdef WC_RSA_BLINDING rng = key->rng; #endif - - if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key, - rng)) - < 0) { - return ret; - } - - return wc_RsaUnPad_ex(in, inLen, out, RSA_BLOCK_TYPE_2, type, hash, mgf, - label, labelSz, key->heap); + return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, + RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, + mgf, label, labelSz, rng); } #endif /* WC_NO_RSA_OAEP */ -int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen, - RsaKey* key) +int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key) { - int plainLen; - byte* tmp; - byte* pad = 0; - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key); + WC_RNG* rng = NULL; +#ifdef WC_RSA_BLINDING + rng = key->rng; #endif - - tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA); - if (tmp == NULL) { - return MEMORY_E; - } - - XMEMCPY(tmp, in, inLen); - - if ( (plainLen = wc_RsaPrivateDecryptInline(tmp, inLen, &pad, key) ) < 0) { - XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); - return plainLen; - } - if (plainLen > (int)outLen || pad == NULL) - plainLen = BAD_FUNC_ARG; - else - XMEMCPY(out, pad, plainLen); - - ForceZero(tmp, inLen); - XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); - - return plainLen; + return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, + WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } #ifndef WC_NO_RSA_OAEP -/* Gives the option of choosing padding type - in : input to be decrypted - inLen: length of input buffer - out: decrypted message - outLen: length of decrypted message in bytes - key : wolfSSL initialized RSA key struct - type : type of padding to use ie WC_RSA_OAEP_PAD - hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h - mgf : type of mask generation function to use - label : optional label - labelSz : size of optional label buffer */ -int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, word32 outLen, - RsaKey* key, int type, enum wc_HashType hash, int mgf, - byte* label, word32 labelSz) +int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, + word32 outLen, RsaKey* key, int type, + enum wc_HashType hash, int mgf, byte* label, + word32 labelSz) { - int plainLen; - byte* tmp; - byte* pad = 0; - - /* sanity check on arguments */ - if (out == NULL || in == NULL || key == NULL) { - return BAD_FUNC_ARG; - } - - /* check if given a label size but not given a label buffer */ - if (label == NULL && labelSz > 0) { - return BAD_FUNC_ARG; - } - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key); + WC_RNG* rng = NULL; +#ifdef WC_RSA_BLINDING + rng = key->rng; #endif - - tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA); - if (tmp == NULL) { - return MEMORY_E; - } - - XMEMCPY(tmp, in, inLen); - - if ( (plainLen = wc_RsaPrivateDecryptInline_ex(tmp, inLen, &pad, key, - type, hash, mgf, label, labelSz) ) < 0) { - XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); - return plainLen; - } - if (plainLen > (int)outLen || pad == NULL) - plainLen = BAD_FUNC_ARG; - else - XMEMCPY(out, pad, plainLen); - - ForceZero(tmp, inLen); - XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); - - return plainLen; + return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label, + labelSz, rng); } #endif /* WC_NO_RSA_OAEP */ -/* for Rsa Verify */ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) { - int ret; - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) { - ret = CaviumRsaSSL_Verify(in, inLen, in, inLen, key); - if (ret > 0) - *out = in; - return ret; - } + WC_RNG* rng = NULL; +#ifdef WC_RSA_BLINDING + rng = key->rng; #endif - - if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key, - NULL)) < 0) { - return ret; - } - - return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1); + return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, + RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, + WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } - int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, - RsaKey* key) + RsaKey* key) { - int plainLen; - byte* tmp; - byte* pad = 0; - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return CaviumRsaSSL_Verify(in, inLen, out, outLen, key); + WC_RNG* rng = NULL; +#ifdef WC_RSA_BLINDING + rng = key->rng; #endif - - tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA); - if (tmp == NULL) { - return MEMORY_E; - } - - XMEMCPY(tmp, in, inLen); - - if ( (plainLen = wc_RsaSSL_VerifyInline(tmp, inLen, &pad, key) ) < 0) { - XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); - return plainLen; - } - - if (plainLen > (int)outLen || pad == NULL) - plainLen = BAD_FUNC_ARG; - else - XMEMCPY(out, pad, plainLen); - - ForceZero(tmp, inLen); - XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); - - return plainLen; + return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, + WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } -/* for Rsa Sign */ int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, - RsaKey* key, WC_RNG* rng) + RsaKey* key, WC_RNG* rng) { - int sz, ret; - -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return CaviumRsaSSL_Sign(in, inLen, out, outLen, key); -#endif - - sz = mp_unsigned_bin_size(&key->n); - if (sz > (int)outLen) - return RSA_BUFFER_E; - - if (sz < RSA_MIN_PAD_SZ) { - return WC_KEY_SIZE_E; - } - - if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) - return RSA_BUFFER_E; - - ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng); - if (ret != 0) - return ret; - - if ((ret = wc_RsaFunction(out, sz, out, &outLen, - RSA_PRIVATE_ENCRYPT, key, rng)) < 0) - sz = ret; - - return sz; + return RsaPublicEncryptEx(in, inLen, out, outLen, key, + RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, + WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } int wc_RsaEncryptSize(RsaKey* key) { -#ifdef HAVE_CAVIUM - if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) - return key->c_nSz; +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { + return key->n.used; + } #endif return mp_unsigned_bin_size(&key->n); } + /* flatten RsaKey structure into individual elements (e, n) */ int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n, - word32* nSz) + word32* nSz) { int sz, ret; - if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) - return BAD_FUNC_ARG; + if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) { + return BAD_FUNC_ARG; + } sz = mp_unsigned_bin_size(&key->e); if ((word32)sz > *eSz) @@ -1377,7 +1505,7 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n, return ret; *eSz = (word32)sz; - sz = mp_unsigned_bin_size(&key->n); + sz = wc_RsaEncryptSize(key); if ((word32)sz > *nSz) return RSA_BUFFER_E; ret = mp_to_unsigned_bin(&key->n, n); @@ -1494,8 +1622,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return 0; } - - #endif /* WOLFSSL_KEY_GEN */ @@ -1513,183 +1639,118 @@ int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng) #endif /* WC_RSA_BLINDING */ -#ifdef HAVE_CAVIUM -#include -#include "cavium_common.h" - -/* Initialize RSA for use with Nitrox device */ -int wc_RsaInitCavium(RsaKey* rsa, int devId) +#ifdef WOLFSSL_ASYNC_CRYPT +int wc_RsaAsyncHandle(RsaKey* key, WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) { - if (rsa == NULL) - return -1; + int ret; - if (CspAllocContext(CONTEXT_SSL, &rsa->contextHandle, devId) != 0) - return -1; + if (key == NULL || queue == NULL || event == NULL) { + return BAD_FUNC_ARG; + } - rsa->devId = devId; - rsa->magic = WOLFSSL_RSA_CAVIUM_MAGIC; + /* make sure this rsa context had "wc_RsaAsyncInit" called on it */ + if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_RSA) { + return ASYNC_INIT_E; + } + + /* setup the event and push to queue */ + ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &key->asyncDev); + if (ret == 0) { + ret = wolfEventQueue_Push(queue, event); + } + + /* check for error (helps with debugging) */ + if (ret != 0) { + WOLFSSL_MSG("wc_RsaAsyncHandle failed"); + } + return ret; +} + +int wc_RsaAsyncWait(int ret, RsaKey* key) +{ + if (ret == WC_PENDING_E) { + WOLF_EVENT event; + XMEMSET(&event, 0, sizeof(event)); + ret = wolfAsync_EventInit(&event, WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, &key->asyncDev); + if (ret == 0) { + ret = wolfAsync_EventWait(&event); + if (ret == 0 && event.ret >= 0) { + ret = event.ret; + } + } + } + return ret; +} + +/* Initialize async RSA key */ +static int InitAsyncRsaKey(RsaKey* key) +{ + XMEMSET(&key->n, 0, sizeof(key->n)); + XMEMSET(&key->e, 0, sizeof(key->e)); + XMEMSET(&key->d, 0, sizeof(key->d)); + XMEMSET(&key->p, 0, sizeof(key->p)); + XMEMSET(&key->q, 0, sizeof(key->q)); + XMEMSET(&key->dP, 0, sizeof(key->dP)); + XMEMSET(&key->dQ, 0, sizeof(key->dQ)); + XMEMSET(&key->u, 0, sizeof(key->u)); return 0; } - -/* Free RSA from use with Nitrox device */ -void wc_RsaFreeCavium(RsaKey* rsa) +/* Free async RSA key */ +static int FreeAsyncRsaKey(RsaKey* key) { - if (rsa == NULL) - return; - - CspFreeContext(CONTEXT_SSL, rsa->contextHandle, rsa->devId); - rsa->magic = 0; -} - - -/* Initialize cavium RSA key */ -static int InitCaviumRsaKey(RsaKey* key, void* heap) -{ - if (key == NULL) - return BAD_FUNC_ARG; - - key->heap = heap; - key->type = -1; /* don't know yet */ - - key->c_n = NULL; - key->c_e = NULL; - key->c_d = NULL; - key->c_p = NULL; - key->c_q = NULL; - key->c_dP = NULL; - key->c_dQ = NULL; - key->c_u = NULL; - - key->c_nSz = 0; - key->c_eSz = 0; - key->c_dSz = 0; - key->c_pSz = 0; - key->c_qSz = 0; - key->c_dP_Sz = 0; - key->c_dQ_Sz = 0; - key->c_uSz = 0; - - return 0; -} - - -/* Free cavium RSA key */ -static int FreeCaviumRsaKey(RsaKey* key) -{ - if (key == NULL) - return BAD_FUNC_ARG; - - XFREE(key->c_n, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - XFREE(key->c_e, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - XFREE(key->c_d, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - XFREE(key->c_p, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - XFREE(key->c_q, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - XFREE(key->c_dP, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - XFREE(key->c_dQ, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - XFREE(key->c_u, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); - - return InitCaviumRsaKey(key, key->heap); /* reset pointers */ -} - - -static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key) -{ - word32 requestId; - word32 ret; - - if (key == NULL || in == NULL || out == NULL || outLen < (word32)key->c_nSz) - return -1; - - ret = CspPkcs1v15Enc(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_eSz, - (word16)inLen, key->c_n, key->c_e, (byte*)in, out, - &requestId, key->devId); - if (ret != 0) { - WOLFSSL_MSG("Cavium Enc BT2 failed"); - return -1; + if (key->type == RSA_PRIVATE) { + if (key->d.dpraw) { + ForceZero(key->d.dpraw, key->d.used); + #ifndef USE_FAST_MATH + XFREE(key->d.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + #endif + } + if (key->p.dpraw) { + ForceZero(key->p.dpraw, key->p.used); + #ifndef USE_FAST_MATH + XFREE(key->p.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + #endif + } + if (key->q.dpraw) { + ForceZero(key->q.dpraw, key->q.used); + #ifndef USE_FAST_MATH + XFREE(key->q.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + #endif + } + if (key->dP.dpraw) { + ForceZero(key->dP.dpraw, key->dP.used); + #ifndef USE_FAST_MATH + XFREE(key->dP.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + #endif + } + if (key->dQ.dpraw) { + ForceZero(key->dQ.dpraw, key->dQ.used); + #ifndef USE_FAST_MATH + XFREE(key->dQ.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + #endif + } + if (key->u.dpraw) { + ForceZero(key->u.dpraw, key->u.used); + #ifndef USE_FAST_MATH + XFREE(key->u.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + #endif + } } - return key->c_nSz; + +#ifndef USE_FAST_MATH + XFREE(key->n.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); + XFREE(key->e.dpraw, key->heap, DYNAMIC_TYPE_ASYNC_RSA); +#endif + + return InitAsyncRsaKey(key); /* reset pointers */ } +#endif /* WOLFSSL_ASYNC_CRYPT */ -static INLINE void ato16(const byte* c, word16* u16) -{ - *u16 = (c[0] << 8) | (c[1]); -} - - -static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key) -{ - word32 requestId; - word32 ret; - word16 outSz = (word16)outLen; - - if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz) - return -1; - - ret = CspPkcs1v15CrtDec(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_q, - key->c_dQ, key->c_p, key->c_dP, key->c_u, - (byte*)in, &outSz, out, &requestId, key->devId); - if (ret != 0) { - WOLFSSL_MSG("Cavium CRT Dec BT2 failed"); - return -1; - } - ato16((const byte*)&outSz, &outSz); - - return outSz; -} - - -static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key) -{ - word32 requestId; - word32 ret; - - if (key == NULL || in == NULL || out == NULL || inLen == 0 || outLen < - (word32)key->c_nSz) - return -1; - - ret = CspPkcs1v15CrtEnc(CAVIUM_BLOCKING, BT1, key->c_nSz, (word16)inLen, - key->c_q, key->c_dQ, key->c_p, key->c_dP, key->c_u, - (byte*)in, out, &requestId, key->devId); - if (ret != 0) { - WOLFSSL_MSG("Cavium CRT Enc BT1 failed"); - return -1; - } - return key->c_nSz; -} - - -static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out, - word32 outLen, RsaKey* key) -{ - word32 requestId; - word32 ret; - word16 outSz = (word16)outLen; - - if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz) - return -1; - - ret = CspPkcs1v15Dec(CAVIUM_BLOCKING, BT1, key->c_nSz, key->c_eSz, - key->c_n, key->c_e, (byte*)in, &outSz, out, - &requestId, key->devId); - if (ret != 0) { - WOLFSSL_MSG("Cavium Dec BT1 failed"); - return -1; - } - outSz = ntohs(outSz); - - return outSz; -} - - -#endif /* HAVE_CAVIUM */ +#undef ERROR_OUT #endif /* HAVE_FIPS */ #endif /* NO_RSA */ - diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index 46e8ff2383..388aafde03 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -209,7 +209,7 @@ int wc_SignatureVerify( if (plain_len < sig_len) { plain_len = sig_len; } - plain_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + plain_data = (byte*)XMALLOC(plain_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (plain_data) { /* Perform verification of signature using provided RSA key */ ret = wc_RsaSSL_Verify(sig, sig_len, plain_data, plain_len, diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 35364334ad..7079fb9f3b 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1035,13 +1035,37 @@ int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) #ifdef TFM_TIMING_RESISTANT +#ifndef WC_NO_CACHE_RESISTANT +/* all off / all on pointer addresses for constant calculations */ +/* ecc.c uses same table */ +const wolfssl_word wc_off_on_addr[2] = +{ +#if defined(WC_64BIT_CPU) + W64LIT(0x0000000000000000), + W64LIT(0xffffffffffffffff) +#elif defined(WC_16BIT_CPU) + 0x0000U, + 0xffffU +#else + /* 32 bit */ + 0x00000000U, + 0xffffffffU +#endif +}; + +#endif /* WC_NO_CACHE_RESISTANT */ + /* timing resistant montgomery ladder based exptmod Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder", Cryptographic Hardware and Embedded Systems, CHES 2002 */ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) { +#ifdef WC_NO_CACHE_RESISTANT fp_int R[2]; +#else + fp_int R[3]; /* need a temp for cache resistance */ +#endif fp_digit buf, mp; int err, bitcnt, digidx, y; @@ -1052,6 +1076,9 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) fp_init(&R[0]); fp_init(&R[1]); +#ifndef WC_NO_CACHE_RESISTANT + fp_init(&R[2]); +#endif /* now we need R mod m */ fp_montgomery_calc_normalization (&R[0], P); @@ -1092,7 +1119,21 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) /* do ops */ fp_mul(&R[0], &R[1], &R[y^1]); fp_montgomery_reduce(&R[y^1], P, mp); + +#ifdef WC_NO_CACHE_RESISTANT fp_sqr(&R[y], &R[y]); fp_montgomery_reduce(&R[y], P, mp); +#else + /* instead of using R[y] for sqr, which leaks key bit to cache monitor, + * use R[2] as temp, make sure address calc is constant, keep + * &R[0] and &R[1] in cache */ + fp_copy((fp_int*) ( ((wolfssl_word)&R[0] & wc_off_on_addr[y^1]) + + ((wolfssl_word)&R[1] & wc_off_on_addr[y]) ), + &R[2]); + fp_sqr(&R[2], &R[2]); fp_montgomery_reduce(&R[2], P, mp); + fp_copy(&R[2], + (fp_int*) ( ((wolfssl_word)&R[0] & wc_off_on_addr[y^1]) + + ((wolfssl_word)&R[1] & wc_off_on_addr[y]) ) ); +#endif /* WC_NO_CACHE_RESISTANT */ } fp_montgomery_reduce(&R[0], P, mp); diff --git a/wolfcrypt/src/wolfevent.c b/wolfcrypt/src/wolfevent.c new file mode 100644 index 0000000000..4da1b2b33b --- /dev/null +++ b/wolfcrypt/src/wolfevent.c @@ -0,0 +1,274 @@ +/* wolfevent.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + + +#ifdef HAVE_WOLF_EVENT + +#include +#include +#include + +#include + + +int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context) +{ + if (event == NULL) { + return BAD_FUNC_ARG; + } + + if (event->pending) { + WOLFSSL_MSG("event already pending!"); + return BAD_COND_E; + } + + XMEMSET(event, 0, sizeof(WOLF_EVENT)); + event->type = type; + event->context = context; + + return 0; +} + +int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags) +{ + int ret = BAD_COND_E; + + /* Check hardware */ +#ifdef WOLFSSL_ASYNC_CRYPT + if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST && + event->type <= WOLF_EVENT_TYPE_ASYNC_LAST) + { + ret = wolfAsync_EventPoll(event, flags); + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + return ret; +} + +int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue) +{ + int ret = 0; + + if (queue == NULL) { + return BAD_FUNC_ARG; + } + + XMEMSET(queue, 0, sizeof(WOLF_EVENT_QUEUE)); +#ifndef SINGLE_THREADED + ret = InitMutex(&queue->lock); +#endif + return ret; +} + + +int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) +{ + int ret; + + if (queue == NULL || event == NULL) { + return BAD_FUNC_ARG; + } + +#ifndef SINGLE_THREADED + if ((ret = LockMutex(&queue->lock)) != 0) { + return ret; + } +#endif + + /* Setup event */ + event->next = NULL; + event->pending = 1; + + if (queue->tail == NULL) { + queue->head = event; + } + else { + queue->tail->next = event; + event->prev = queue->tail; + } + queue->tail = event; /* add to the end either way */ + queue->count++; + ret = 0; + +#ifndef SINGLE_THREADED + UnLockMutex(&queue->lock); +#endif + + return ret; +} + +int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event) +{ + int ret = 0; + + if (queue == NULL || event == NULL) { + return BAD_FUNC_ARG; + } + +#ifndef SINGLE_THREADED + /* In single threaded mode "event_queue.lock" doesn't exist */ + if ((ret = LockMutex(&queue->lock)) != 0) { + return ret; + } +#endif + + /* Pop first item off queue */ + *event = queue->head; + ret = wolfEventQueue_Remove(queue, *event); + +#ifndef SINGLE_THREADED + UnLockMutex(&queue->lock); +#endif + + return ret; +} + +/* assumes queue is locked by caller */ +int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) +{ + int ret = 0; + + if (queue == NULL || event == NULL) { + return BAD_FUNC_ARG; + } + + if (event == queue->head && event == queue->tail) { + queue->head = NULL; + queue->tail = NULL; + } + else if (event == queue->head) { + queue->head = event->next; + queue->head->prev = NULL; + } + else if (event == queue->tail) { + queue->tail = event->prev; + queue->tail->next = NULL; + } + else { + WOLF_EVENT* next = event->next; + WOLF_EVENT* prev = event->prev; + next->prev = prev; + prev->next = next; + } + queue->count--; + + return ret; +} + +int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter, + WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount) +{ + WOLF_EVENT* event; + int ret = 0, count = 0; + + if (queue == NULL) { + return BAD_FUNC_ARG; + } + +#ifndef SINGLE_THREADED + /* In single threaded mode "event_queue.lock" doesn't exist */ + if ((ret = LockMutex(&queue->lock)) != 0) { + return ret; + } +#endif + + /* itterate event queue */ + for (event = queue->head; event != NULL; event = event->next) + { + /* optional filter based on context */ + if (context_filter == NULL || event->context == context_filter) { + + /* poll event */ + ret = wolfEvent_Poll(event, flags); + if (ret < 0) break; /* exit for */ + + /* If event is done then process */ + if (event->done) { + /* remove from queue */ + ret = wolfEventQueue_Remove(queue, event); + if (ret < 0) break; /* exit for */ + + /* return pointer in 'events' arg */ + if (events) { + events[count] = event; /* return pointer */ + } + count++; + + /* check to make sure our event list isn't full */ + if (events && count >= maxEvents) { + break; /* exit for */ + } + } + } + } + +#ifndef SINGLE_THREADED + UnLockMutex(&queue->lock); +#endif + + /* return number of properly populated events */ + if (eventCount) { + *eventCount = count; + } + + return ret; +} + +int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue) +{ + int ret; + + if (queue == NULL) { + return BAD_FUNC_ARG; + } + +#ifndef SINGLE_THREADED + /* In single threaded mode "event_queue.lock" doesn't exist */ + if ((ret = LockMutex(&queue->lock)) != 0) { + return ret; + } +#endif + + ret = queue->count; + +#ifndef SINGLE_THREADED + UnLockMutex(&queue->lock); +#endif + + return ret; +} + +void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue) +{ + if (queue) { + #ifndef SINGLE_THREADED + FreeMutex(&queue->lock); + #endif + } +} + +#endif /* HAVE_WOLF_EVENT */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 9feda3ad6a..8107501c34 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -32,28 +32,13 @@ #ifndef NO_CRYPT_TEST -#if defined(WOLFSSL_STATIC_MEMORY) && !defined(HAVE_IO_POOL) - #ifndef HAVE_PKCS7 - #define USE_CERT_BUFFERS_1024 /* avoid dynamic memory from fopen */ - #endif +#ifdef WOLFSSL_STATIC_MEMORY #include - #ifndef XMALLOC_USER - #define TEST_XMALLOC(s, h, t) XMALLOC((s),(h),(t)) - #define TEST_XFREE(p, h, t) XFREE((p),(h),(t)) - #endif - #ifdef WOLFSSL_HEAP_TEST - #define HEAP_HINT (void*)WOLFSSL_HEAP_TEST - #else - #define HEAP_HINT NULL - #endif + static WOLFSSL_HEAP_HINT* HEAP_HINT; #else - /* only use XMALLOC and XFREE when testing static memory feature */ - #define TEST_XMALLOC(s, h, t) ((void)h, (void)t, malloc((s))) - #define TEST_XFREE(p, h, t) {void* xp = (p); if((xp)) free((xp));} - #define HEAP_HINT NULL + #define HEAP_HINT NULL #endif /* WOLFSSL_STATIC_MEMORY */ - #ifdef WOLFSSL_TEST_CERT #include #else @@ -107,6 +92,9 @@ #ifdef HAVE_FIPS #include #endif +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ @@ -133,11 +121,6 @@ #ifdef HAVE_NTRU #include "libntruencrypt/ntru_crypto.h" #endif -#ifdef HAVE_CAVIUM - #include "cavium_sysdep.h" - #include "cavium_common.h" - #include "cavium_ioctl.h" -#endif #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) #include @@ -165,6 +148,9 @@ #include "wolfssl/wolfcrypt/mem_track.h" #endif +/* for async devices */ +static int devId = INVALID_DEVID; + #ifdef HAVE_WNR const char* wnrConfigFile = "wnr-example.conf"; #endif @@ -251,6 +237,10 @@ int idea_test(void); int memory_test(void); #endif +#if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) && !defined(OPENSSL_EXTRA) + int wolfSSL_Debugging_ON(void); +#endif + /* General big buffer size for many tests. */ #define FOURK_BUF 4096 @@ -292,13 +282,32 @@ static void myFipsCb(int ok, int err, const char* hash) int wolfcrypt_test(void* args) { int ret = 0; +#ifdef WOLFSSL_STATIC_MEMORY + #ifdef BENCH_EMBEDDED + byte memory[10000]; + #else + byte memory[100000]; + #endif +#endif ((func_args*)args)->return_code = -1; /* error state */ +#ifdef WOLFSSL_STATIC_MEMORY + if (wc_LoadStaticMemory(&HEAP_HINT, memory, sizeof(memory), + WOLFMEM_GENERAL, 1) != 0) { + printf("unable to load static memory"); + exit(EXIT_FAILURE); + } +#endif + #if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY) InitMemoryTracker(); #endif +#if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) + wolfSSL_Debugging_ON(); +#endif + wolfCrypt_Init(); #ifdef HAVE_FIPS @@ -316,6 +325,16 @@ int wolfcrypt_test(void* args) #endif /* USE_FAST_MATH */ #endif /* !NO_BIG_INT */ +#ifdef WOLFSSL_ASYNC_CRYPT + ret = wolfAsync_DevOpen(&devId); + if (ret != 0) { + err_sys("Async device open failed", -1236); + return -1236; + } +#else + (void)devId; +#endif /* WOLFSSL_ASYNC_CRYPT */ + #ifndef NO_MD5 if ( (ret = md5_test()) != 0) return err_sys("MD5 test failed!\n", ret); @@ -661,45 +680,12 @@ int wolfcrypt_test(void* args) #ifndef NO_MAIN_DRIVER -#ifdef HAVE_CAVIUM - -static int OpenNitroxDevice(int dma_mode,int dev_id) -{ - Csp1CoreAssignment core_assign; - Uint32 device; - - if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID)) - return -1; - if (Csp1GetDevType(&device)) - return -1; - if (device != NPX_DEVICE) { - if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT, - (Uint32 *)&core_assign)!= 0) - return -1; - } - CspShutdown(CAVIUM_DEV_ID); - - return CspInitialize(dma_mode, dev_id); -} - -#endif /* HAVE_CAVIUM */ - /* so overall tests can pull in test function */ int main(int argc, char** argv) { - func_args args; - -#ifdef HAVE_CAVIUM - int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); - if (ret != 0) { - err_sys("Cavium OpenNitroxDevice failed", -1236); - return -1236; - } -#endif /* HAVE_CAVIUM */ - #ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0) { err_sys("Whitewood netRandom global config failed", -1237); @@ -712,10 +698,6 @@ static int OpenNitroxDevice(int dma_mode,int dev_id) wolfcrypt_test(&args); -#ifdef HAVE_CAVIUM - CspShutdown(CAVIUM_DEV_ID); -#endif - #ifdef HAVE_WNR if (wc_FreeNetRandom() < 0) err_sys("Failed to free netRandom context", -1238); @@ -1337,14 +1319,18 @@ int hmac_md5_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { -#if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) - if (i == 1) + #if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) + if (i == 1) { continue; /* cavium can't handle short keys, fips not allowed */ -#endif -#ifdef HAVE_CAVIUM - if (wc_HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + } + #endif + + #ifdef WOLFSSL_ASYNC_CRYPT + if (wc_HmacAsyncInit(&hmac, devId) != 0) { return -20009; -#endif + } + #endif + ret = wc_HmacSetKey(&hmac, MD5, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) return -4015; @@ -1358,9 +1344,10 @@ int hmac_md5_test(void) if (XMEMCMP(hash, test_hmac[i].output, MD5_DIGEST_SIZE) != 0) return -20 - i; -#ifdef HAVE_CAVIUM - wc_HmacFreeCavium(&hmac); -#endif + + #ifdef WOLFSSL_ASYNC_CRYPT + wc_HmacAsyncFree(&hmac); + #endif } return 0; @@ -1418,8 +1405,8 @@ int hmac_sha_test(void) if (i == 1) continue; /* cavium can't handle short keys, fips not allowed */ #endif -#ifdef HAVE_CAVIUM - if (wc_HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) +#ifdef WOLFSSL_ASYNC_CRYPT + if (wc_HmacAsyncInit(&hmac, devId) != 0) return -20010; #endif ret = wc_HmacSetKey(&hmac, SHA, (byte*)keys[i], (word32)XSTRLEN(keys[i])); @@ -1435,8 +1422,8 @@ int hmac_sha_test(void) if (XMEMCMP(hash, test_hmac[i].output, SHA_DIGEST_SIZE) != 0) return -20 - i; -#ifdef HAVE_CAVIUM - wc_HmacFreeCavium(&hmac); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_HmacAsyncFree(&hmac); #endif } @@ -1499,8 +1486,8 @@ int hmac_sha256_test(void) if (i == 1) continue; /* cavium can't handle short keys, fips not allowed */ #endif -#ifdef HAVE_CAVIUM - if (wc_HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) +#ifdef WOLFSSL_ASYNC_CRYPT + if (wc_HmacAsyncInit(&hmac, devId) != 0) return -20011; #endif ret = wc_HmacSetKey(&hmac, SHA256, (byte*)keys[i],(word32)XSTRLEN(keys[i])); @@ -1516,8 +1503,8 @@ int hmac_sha256_test(void) if (XMEMCMP(hash, test_hmac[i].output, SHA256_DIGEST_SIZE) != 0) return -20 - i; -#ifdef HAVE_CAVIUM - wc_HmacFreeCavium(&hmac); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_HmacAsyncFree(&hmac); #endif } @@ -1580,8 +1567,12 @@ int hmac_blake2b_test(void) if (i == 1) continue; /* cavium can't handle short keys, fips not allowed */ #endif -#ifdef HAVE_CAVIUM - if (wc_HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) +#ifdef WOLFSSL_ASYNC_CRYPT + #ifdef HAVE_CAVIUM_V + /* Blake2 not supported on Cavium V, but SHA3 is */ + return 0; + #endif + if (wc_HmacAsyncInit(&hmac, devId) != 0) return -20011; #endif ret = wc_HmacSetKey(&hmac, BLAKE2B_ID, (byte*)keys[i], @@ -1598,8 +1589,8 @@ int hmac_blake2b_test(void) if (XMEMCMP(hash, test_hmac[i].output, BLAKE2B_256) != 0) return -20 - i; -#ifdef HAVE_CAVIUM - wc_HmacFreeCavium(&hmac); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_HmacAsyncFree(&hmac); #endif } @@ -1816,12 +1807,12 @@ int arc4_test(void) if (i == 3) keylen = 4; -#ifdef HAVE_CAVIUM - if (wc_Arc4InitCavium(&enc, CAVIUM_DEV_ID) != 0) + #ifdef WOLFSSL_ASYNC_CRYPT + if (wc_Arc4AsyncInit(&enc, devId) != 0) return -20001; - if (wc_Arc4InitCavium(&dec, CAVIUM_DEV_ID) != 0) + if (wc_Arc4AsyncInit(&dec, devId) != 0) return -20002; -#endif + #endif wc_Arc4SetKey(&enc, (byte*)keys[i], keylen); wc_Arc4SetKey(&dec, (byte*)keys[i], keylen); @@ -1836,10 +1827,10 @@ int arc4_test(void) if (XMEMCMP(cipher, test_arc4[i].output, test_arc4[i].outLen)) return -20 - 5 - i; -#ifdef HAVE_CAVIUM - wc_Arc4FreeCavium(&enc); - wc_Arc4FreeCavium(&dec); -#endif + #ifdef WOLFSSL_ASYNC_CRYPT + wc_Arc4AsyncFree(&enc); + wc_Arc4AsyncFree(&dec); + #endif } return 0; @@ -2596,18 +2587,24 @@ int des_test(void) if (ret != 0) return -31; - wc_Des_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); - ret = wc_Des_SetKey(&dec, key, iv, DES_DECRYPTION); + ret = wc_Des_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); if (ret != 0) return -32; - wc_Des_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); - if (XMEMCMP(plain, vector, sizeof(plain))) + ret = wc_Des_SetKey(&dec, key, iv, DES_DECRYPTION); + if (ret != 0) return -33; - if (XMEMCMP(cipher, verify, sizeof(cipher))) + ret = wc_Des_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); + if (ret != 0) return -34; + if (XMEMCMP(plain, vector, sizeof(plain))) + return -35; + + if (XMEMCMP(cipher, verify, sizeof(cipher))) + return -36; + return 0; } #endif /* NO_DES3 */ @@ -2652,10 +2649,10 @@ int des3_test(void) int ret; -#ifdef HAVE_CAVIUM - if (wc_Des3_InitCavium(&enc, CAVIUM_DEV_ID) != 0) +#ifdef WOLFSSL_ASYNC_CRYPT + if (wc_Des3AsyncInit(&enc, devId) != 0) return -20005; - if (wc_Des3_InitCavium(&dec, CAVIUM_DEV_ID) != 0) + if (wc_Des3AsyncInit(&dec, devId) != 0) return -20006; #endif ret = wc_Des3_SetKey(&enc, key3, iv3, DES_ENCRYPTION); @@ -2677,9 +2674,9 @@ int des3_test(void) if (XMEMCMP(cipher, verify3, sizeof(cipher))) return -36; -#ifdef HAVE_CAVIUM - wc_Des3_FreeCavium(&enc); - wc_Des3_FreeCavium(&dec); +#ifdef WOLFSSL_ASYNC_CRYPT + wc_Des3AsyncFree(&enc); + wc_Des3AsyncFree(&dec); #endif return 0; } @@ -2714,11 +2711,11 @@ int aes_test(void) byte key[] = "0123456789abcdef "; /* align */ byte iv[] = "1234567890abcdef "; /* align */ -#ifdef HAVE_CAVIUM - if (wc_AesInitCavium(&enc, CAVIUM_DEV_ID) != 0) - return -20003; - if (wc_AesInitCavium(&dec, CAVIUM_DEV_ID) != 0) - return -20004; +#ifdef WOLFSSL_ASYNC_CRYPT + if (wc_AesAsyncInit(&enc, devId) != 0) + return -20003; + if (wc_AesAsyncInit(&dec, devId) != 0) + return -20004; #endif ret = wc_AesSetKey(&enc, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); if (ret != 0) @@ -2829,10 +2826,11 @@ int aes_test(void) } #endif /* WOLFSSL_AESNI HAVE_AES_DECRYPT */ -#ifdef HAVE_CAVIUM - wc_AesFreeCavium(&enc); - wc_AesFreeCavium(&dec); -#endif +#ifdef WOLFSSL_ASYNC_CRYPT + wc_AesAsyncFree(&enc); + wc_AesAsyncFree(&dec); +#endif /* WOLFSSL_ASYNC_CRYPT */ + #endif /* HAVE_AES_CBC */ #ifdef WOLFSSL_AES_COUNTER @@ -3745,10 +3743,6 @@ static int random_rng_test(void) byte block[32]; int ret, i; -#ifdef HAVE_CAVIUM - ret = wc_InitRngCavium(&rng, CAVIUM_DEV_ID); - if (ret != 0) return -2007; -#endif ret = wc_InitRng(&rng); if (ret != 0) return -39; @@ -4096,7 +4090,7 @@ int certext_test(void) byte kid_ca[] = "\x33\xD8\x45\x66\xD7\x68\x87\x18\x7E\x54" "\x0D\x70\x27\x91\xC7\x26\xD7\x85\x65\xC0"; - tmp = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return -200; @@ -4107,7 +4101,7 @@ int certext_test(void) file = fopen("./othercert.der", "rb"); #endif if (!file) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -200; } @@ -4158,7 +4152,7 @@ int certext_test(void) file = fopen("./certecc.der", "rb"); #endif if (!file) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -210; } @@ -4212,7 +4206,7 @@ int certext_test(void) file = fopen("./cert.der", "rb"); #endif if (!file) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -220; } @@ -4257,12 +4251,13 @@ int certext_test(void) #endif FreeDecodedCert(&cert); - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return 0; } #endif /* WOLFSSL_CERT_EXT && WOLFSSL_TEST_CERT */ + int rsa_test(void) { byte* tmp; @@ -4285,7 +4280,7 @@ int rsa_test(void) DecodedCert cert; #endif - tmp = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return -40; @@ -4301,7 +4296,7 @@ int rsa_test(void) if (!file) { err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -40); - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -40; } @@ -4309,63 +4304,96 @@ int rsa_test(void) fclose(file); #endif /* USE_CERT_BUFFERS */ -#ifdef HAVE_CAVIUM - wc_RsaInitCavium(&key, CAVIUM_DEV_ID); -#endif - - ret = wc_InitRsaKey(&key, HEAP_HINT); + ret = wc_InitRsaKey_ex(&key, HEAP_HINT, devId); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -39; } ret = wc_RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -41; } ret = wc_InitRng(&rng); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -42; } - ret = wc_RsaPublicEncrypt(in, inLen, out, sizeof(out), &key, &rng); + + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt(in, inLen, out, sizeof(out), &key, &rng); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -43; } + #ifdef WC_RSA_BLINDING { int tmpret = ret; ret = wc_RsaSetRNG(&key, &rng); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -843; } ret = tmpret; } #endif - ret = wc_RsaPrivateDecrypt(out, ret, plain, sizeof(plain), &key); + + idx = ret; /* save off encrypted length */ + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt(out, idx, plain, sizeof(plain), &key); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -44; } + if (XMEMCMP(plain, in, inLen)) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -45; } - ret = wc_RsaSSL_Sign(in, inLen, out, sizeof(out), &key, &rng); + + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaSSL_Sign(in, inLen, out, sizeof(out), &key, &rng); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -46; } + + idx = ret; XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaSSL_Verify(out, ret, plain, sizeof(plain), &key); + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaSSL_Verify(out, idx, plain, sizeof(plain), &key); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); return -47; } + if (XMEMCMP(plain, in, ret)) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -48; } @@ -4375,92 +4403,178 @@ int rsa_test(void) !defined(HAVE_FIPS) #ifndef NO_SHA XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, + + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -143; } - ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key, + + idx = ret; + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt_ex(out, idx, plain, sizeof(plain), &key, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -144; } + if (XMEMCMP(plain, in, inLen)) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -145; } #endif /* NO_SHA */ #ifndef NO_SHA256 XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -243; } - ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key, + + idx = ret; + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt_ex(out, idx, plain, sizeof(plain), &key, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -244; } + if (XMEMCMP(plain, in, inLen)) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -245; } /* check fails if not using the same optional label */ XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -246; } - ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key, - WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + + idx = ret; + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt_ex(out, idx, plain, sizeof(plain), &key, + WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + } + } while (ret == WC_PENDING_E); if (ret > 0) { /* in this case decrypt should fail */ - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -247; } + ret = 0; /* check using optional label with encrypt/decrypt */ XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, - WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, + WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -248; } - ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key, - WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + + idx = ret; + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt_ex(out, idx, plain, sizeof(plain), &key, + WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -249; } + if (XMEMCMP(plain, in, inLen)) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -250; } - #ifndef NO_SHA + #ifndef NO_SHA /* check fail using mismatch hash algorithms */ XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, - WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, WC_MGF1SHA1, in, sizeof(in)); + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); + #endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, + WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, WC_MGF1SHA1, in, sizeof(in)); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -251; } - ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key, - WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + + idx = ret; + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); + #endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt_ex(out, idx, plain, sizeof(plain), &key, + WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in)); + } + } while (ret == WC_PENDING_E); if (ret > 0) { /* should fail */ - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -252; } + ret = 0; #endif /* NO_SHA*/ #endif /* NO_SHA256 */ @@ -4471,20 +4585,37 @@ int rsa_test(void) BAD_FUNC_ARG is returned when this case is not met */ if (wc_RsaEncryptSize(&key) > ((int)SHA512_DIGEST_SIZE * 2) + 2) { XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); + #endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA512, WC_MGF1SHA512, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -343; } - ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key, + + idx = ret; + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); + #endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt_ex(out, idx, plain, sizeof(plain), &key, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA512, WC_MGF1SHA512, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -344; } + if (XMEMCMP(plain, in, inLen)) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -345; } } @@ -4492,20 +4623,37 @@ int rsa_test(void) /* check using pkcsv15 padding with _ex API */ XMEMSET(plain, 0, sizeof(plain)); - ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, 0, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -443; } - ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key, + + idx = ret; + do { +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_RsaAsyncWait(ret, &key); +#endif + if (ret >= 0) { + ret = wc_RsaPrivateDecrypt_ex(out, idx, plain, sizeof(plain), &key, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, 0, NULL, 0); + } + } while (ret == WC_PENDING_E); if (ret < 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -444; } + if (XMEMCMP(plain, in, inLen)) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -445; } #endif /* !HAVE_FAST_RSA && !HAVE_FIPS */ @@ -4524,7 +4672,7 @@ int rsa_test(void) #else file2 = fopen(clientCert, "rb"); if (!file2) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -49; } @@ -4540,7 +4688,10 @@ int rsa_test(void) InitDecodedCert(&cert, tmp, (word32)bytes, 0); ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); - if (ret != 0) return -491; + if (ret != 0) { + free(tmp); + return -491; + } FreeDecodedCert(&cert); #else @@ -4560,7 +4711,7 @@ int rsa_test(void) if (!file) { err_sys("can't open ./certs/client-keyPub.der, " "Please run from wolfSSL home dir", -40); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -50; } @@ -4568,16 +4719,16 @@ int rsa_test(void) fclose(file); #endif /* USE_CERT_BUFFERS */ - ret = wc_InitRsaKey(&keypub, 0); + ret = wc_InitRsaKey(&keypub, HEAP_HINT); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -51; } idx = 0; ret = wc_RsaPublicKeyDecode(tmp, &idx, &keypub, (word32)bytes); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&keypub); return -52; } @@ -4596,34 +4747,34 @@ int rsa_test(void) ret = wc_InitRsaKey(&genKey, HEAP_HINT); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -300; } ret = wc_MakeRsaKey(&genKey, 1024, 65537, &rng); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -301; } - der = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -307; } - pem = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -308; } derSz = wc_RsaKeyToDer(&genKey, der, FOURK_BUF); if (derSz < 0) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -302; } @@ -4633,27 +4784,27 @@ int rsa_test(void) keyFile = fopen("./key.der", "wb"); #endif if (!keyFile) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -303; } ret = (int)fwrite(der, 1, derSz, keyFile); fclose(keyFile); if (ret != derSz) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -313; } pemSz = wc_DerToPem(der, derSz, pem, FOURK_BUF, PRIVATEKEY_TYPE); if (pemSz < 0) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -304; } @@ -4664,36 +4815,36 @@ int rsa_test(void) pemFile = fopen("./key.pem", "wb"); #endif if (!pemFile) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -305; } ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); if (ret != pemSz) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -314; } ret = wc_InitRsaKey(&derIn, HEAP_HINT); if (ret != 0) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&genKey); return -3060; } idx = 0; ret = wc_RsaPrivateKeyDecode(der, &idx, &derIn, derSz); if (ret != 0) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&derIn); wc_FreeRsaKey(&genKey); return -306; @@ -4701,8 +4852,8 @@ int rsa_test(void) wc_FreeRsaKey(&derIn); wc_FreeRsaKey(&genKey); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } #endif /* WOLFSSL_KEY_GEN */ @@ -4720,16 +4871,16 @@ int rsa_test(void) DecodedCert decode; #endif - derCert = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, + derCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (derCert == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -309; } - pem = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); + pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -310; } @@ -4755,34 +4906,34 @@ int rsa_test(void) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(&myCert, &keypub, NULL) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -398; } /* add AKID from the Public Key */ if (wc_SetAuthKeyIdFromPublicKey(&myCert, &keypub, NULL) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -399; } /* add Key Usage */ if (wc_SetKeyUsage(&myCert,"cRLSign,keyCertSign") != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -400; } #endif /* WOLFSSL_CERT_EXT */ certSz = wc_MakeSelfCert(&myCert, derCert, FOURK_BUF, &key, &rng); if (certSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -401; } @@ -4790,9 +4941,9 @@ int rsa_test(void) InitDecodedCert(&decode, derCert, certSz, HEAP_HINT); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -402; } FreeDecodedCert(&decode); @@ -4804,25 +4955,25 @@ int rsa_test(void) derFile = fopen("./cert.der", "wb"); #endif if (!derFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -403; } ret = (int)fwrite(derCert, 1, certSz, derFile); fclose(derFile); if (ret != certSz) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -414; } pemSz = wc_DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); if (pemSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -404; } @@ -4832,21 +4983,21 @@ int rsa_test(void) pemFile = fopen("./cert.pem", "wb"); #endif if (!pemFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -405; } ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); if (ret != pemSz) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -406; } - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } /* CA style */ { @@ -4865,25 +5016,25 @@ int rsa_test(void) DecodedCert decode; #endif - derCert = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, + derCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (derCert == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -311; } - pem = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); + pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -312; } file3 = fopen(caKeyFile, "rb"); if (!file3) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -412; } @@ -4892,16 +5043,16 @@ int rsa_test(void) ret = wc_InitRsaKey(&caKey, HEAP_HINT); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -411; } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -413; } @@ -4928,43 +5079,43 @@ int rsa_test(void) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(&myCert, &key, NULL) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -398; } /* add AKID from the CA certificate */ if (wc_SetAuthKeyId(&myCert, caCertFile) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -399; } /* add Key Usage */ if (wc_SetKeyUsage(&myCert,"keyEncipherment,keyAgreement") != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -400; } #endif /* WOLFSSL_CERT_EXT */ ret = wc_SetIssuer(&myCert, caCertFile); if (ret < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -405; } certSz = wc_MakeCert(&myCert, derCert, FOURK_BUF, &key, NULL, &rng); if (certSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -407; } @@ -4972,9 +5123,9 @@ int rsa_test(void) certSz = wc_SignCert(myCert.bodySz, myCert.sigType, derCert, FOURK_BUF, &caKey, NULL, &rng); if (certSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -408; } @@ -4983,9 +5134,9 @@ int rsa_test(void) InitDecodedCert(&decode, derCert, certSz, HEAP_HINT); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -409; } @@ -4998,27 +5149,27 @@ int rsa_test(void) derFile = fopen("./othercert.der", "wb"); #endif if (!derFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -410; } ret = (int)fwrite(derCert, 1, certSz, derFile); fclose(derFile); if (ret != certSz) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -416; } pemSz = wc_DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); if (pemSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -411; } @@ -5029,24 +5180,24 @@ int rsa_test(void) pemFile = fopen("./othercert.pem", "wb"); #endif if (!pemFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); return -412; } ret = (int)fwrite(pem, 1, pemSz, pemFile); if (ret != pemSz) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); fclose(pemFile); wc_FreeRsaKey(&caKey); return -415; } fclose(pemFile); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); } #ifdef HAVE_ECC @@ -5070,25 +5221,25 @@ int rsa_test(void) DecodedCert decode; #endif - derCert = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, + derCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (derCert == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5311; } - pem = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); + pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5312; } file3 = fopen(eccCaKeyFile, "rb"); if (!file3) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5412; } @@ -5098,9 +5249,9 @@ int rsa_test(void) wc_ecc_init(&caKey); ret = wc_EccPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5413; } @@ -5126,9 +5277,9 @@ int rsa_test(void) file3 = fopen(eccCaKeyPubFile, "rb"); if (!file3) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5500; } @@ -5137,36 +5288,36 @@ int rsa_test(void) wc_ecc_init(&caKeyPub); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5501; } idx3 = 0; ret = wc_EccPublicKeyDecode(tmp, &idx3, &caKeyPub, (word32)bytes3); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKeyPub); return -5502; } /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(&myCert, &key, NULL) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKeyPub); return -5503; } /* add AKID from the Public Key */ if (wc_SetAuthKeyIdFromPublicKey(&myCert, NULL, &caKeyPub) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKeyPub); return -5504; } @@ -5174,38 +5325,38 @@ int rsa_test(void) /* add Key Usage */ if (wc_SetKeyUsage(&myCert,"digitalSignature,nonRepudiation") != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5505; } #endif /* WOLFSSL_CERT_EXT */ ret = wc_SetIssuer(&myCert, eccCaCertFile); if (ret < 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5405; } certSz = wc_MakeCert(&myCert, derCert, FOURK_BUF, &key, NULL, &rng); if (certSz < 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5407; } certSz = wc_SignCert(myCert.bodySz, myCert.sigType, derCert, FOURK_BUF, NULL, &caKey, &rng); if (certSz < 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5408; } @@ -5213,9 +5364,9 @@ int rsa_test(void) InitDecodedCert(&decode, derCert, certSz, 0); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); return -5409; } @@ -5228,28 +5379,28 @@ int rsa_test(void) derFile = fopen("./certecc.der", "wb"); #endif if (!derFile) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5410; } ret = (int)fwrite(derCert, 1, certSz, derFile); fclose(derFile); if (ret != certSz) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5414; } pemSz = wc_DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); if (pemSz < 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5411; } @@ -5259,18 +5410,18 @@ int rsa_test(void) pemFile = fopen("./certecc.pem", "wb"); #endif if (!pemFile) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5412; } ret = (int)fwrite(pem, 1, pemSz, pemFile); if (ret != pemSz) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_ecc_free(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -5415; } @@ -5296,16 +5447,16 @@ int rsa_test(void) #ifdef WOLFSSL_TEST_CERT DecodedCert decode; #endif - derCert = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, + derCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (derCert == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -311; } - pem = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); + pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -312; } @@ -5320,9 +5471,9 @@ int rsa_test(void) word32 rc = ntru_crypto_drbg_instantiate(112, pers_str, sizeof(pers_str), GetEntropy, &drbg); if (rc != DRBG_OK) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -448; } @@ -5330,9 +5481,9 @@ int rsa_test(void) &public_key_len, NULL, &private_key_len, NULL); if (rc != NTRU_OK) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -449; } @@ -5340,45 +5491,45 @@ int rsa_test(void) &public_key_len, public_key, &private_key_len, private_key); if (rc != NTRU_OK) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -450; } rc = ntru_crypto_drbg_uninstantiate(drbg); if (rc != NTRU_OK) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -451; } caFile = fopen(caKeyFile, "rb"); if (!caFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -452; } bytes = fread(tmp, 1, FOURK_BUF, caFile); fclose(caFile); - ret = wc_InitRsaKey(&caKey, 0); + ret = wc_InitRsaKey(&caKey, HEAP_HINT); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -453; } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -454; } @@ -5398,46 +5549,46 @@ int rsa_test(void) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromNtruPublicKey(&myCert, public_key, public_key_len) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -496; } /* add AKID from the CA certificate */ if (wc_SetAuthKeyId(&myCert, caCertFile) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -495; } /* add Key Usage */ if (wc_SetKeyUsage(&myCert,"digitalSignature,nonRepudiation," "keyEncipherment,keyAgreement") != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -494; } #endif /* WOLFSSL_CERT_EXT */ ret = wc_SetIssuer(&myCert, caCertFile); if (ret < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -455; } certSz = wc_MakeNtruCert(&myCert, derCert, FOURK_BUF, public_key, public_key_len, &rng); if (certSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&caKey); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -456; } @@ -5445,9 +5596,9 @@ int rsa_test(void) &caKey, NULL, &rng); wc_FreeRsaKey(&caKey); if (certSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -457; } @@ -5456,70 +5607,70 @@ int rsa_test(void) InitDecodedCert(&decode, derCert, certSz, HEAP_HINT); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -458; } FreeDecodedCert(&decode); #endif derFile = fopen("./ntru-cert.der", "wb"); if (!derFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -459; } ret = (int)fwrite(derCert, 1, certSz, derFile); fclose(derFile); if (ret != certSz) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -473; } pemSz = wc_DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE); if (pemSz < 0) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -460; } pemFile = fopen("./ntru-cert.pem", "wb"); if (!pemFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -461; } ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); if (ret != pemSz) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -474; } ntruPrivFile = fopen("./ntru-key.raw", "wb"); if (!ntruPrivFile) { - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -462; } ret = (int)fwrite(private_key, 1, private_key_len, ntruPrivFile); fclose(ntruPrivFile); if (ret != private_key_len) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -475; } - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } #endif /* HAVE_NTRU */ #ifdef WOLFSSL_CERT_REQ @@ -5531,15 +5682,15 @@ int rsa_test(void) int pemSz; FILE* reqFile; - der = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); + der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -463; } - pem = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); + pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -464; } @@ -5560,44 +5711,44 @@ int rsa_test(void) #ifdef WOLFSSL_CERT_EXT /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(&req, &keypub, NULL) != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -496; } /* add Key Usage */ if (wc_SetKeyUsage(&req,"digitalSignature,nonRepudiation," "keyEncipherment,keyAgreement") != 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -494; } #endif /* WOLFSSL_CERT_EXT */ derSz = wc_MakeCertReq(&req, der, FOURK_BUF, &key, NULL); if (derSz < 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -465; } derSz = wc_SignCert(req.bodySz, req.sigType, der, FOURK_BUF, &key, NULL, &rng); if (derSz < 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -466; } pemSz = wc_DerToPem(der, derSz, pem, FOURK_BUF, CERTREQ_TYPE); if (pemSz < 0) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -467; } @@ -5607,18 +5758,18 @@ int rsa_test(void) reqFile = fopen("./certreq.der", "wb"); #endif if (!reqFile) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -468; } ret = (int)fwrite(der, 1, derSz, reqFile); fclose(reqFile); if (ret != derSz) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -471; } @@ -5628,22 +5779,22 @@ int rsa_test(void) reqFile = fopen("./certreq.pem", "wb"); #endif if (!reqFile) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -469; } ret = (int)fwrite(pem, 1, pemSz, reqFile); fclose(reqFile); if (ret != pemSz) { - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -470; } - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } #endif /* WOLFSSL_CERT_REQ */ #endif /* WOLFSSL_CERT_GEN */ @@ -5655,7 +5806,7 @@ int rsa_test(void) #ifdef HAVE_CAVIUM wc_RsaFreeCavium(&key); #endif - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRng(&rng); return 0; @@ -5841,22 +5992,22 @@ int dsa_test(void) ret = wc_MakeDsaKey(&rng, &genKey); if (ret != 0) return -363; - der = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { wc_FreeDsaKey(&genKey); return -364; } - pem = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); return -365; } derSz = wc_DsaKeyToDer(&genKey, der, FOURK_BUF); if (derSz < 0) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -366; } @@ -5866,24 +6017,24 @@ int dsa_test(void) keyFile = fopen("./key.der", "wb"); #endif if (!keyFile) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); return -367; } ret = (int)fwrite(der, 1, derSz, keyFile); fclose(keyFile); if (ret != derSz) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); return -368; } pemSz = wc_DerToPem(der, derSz, pem, FOURK_BUF, DSA_PRIVATEKEY_TYPE); if (pemSz < 0) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); return -369; } @@ -5894,16 +6045,16 @@ int dsa_test(void) pemFile = fopen("./key.pem", "wb"); #endif if (!pemFile) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); return -370; } ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); if (ret != pemSz) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); return -371; } @@ -5912,8 +6063,8 @@ int dsa_test(void) idx = 0; ret = wc_DsaPrivateKeyDecode(der, &idx, &derIn, derSz); if (ret != 0) { - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&derIn); wc_FreeDsaKey(&genKey); return -373; @@ -5921,8 +6072,8 @@ int dsa_test(void) wc_FreeDsaKey(&derIn); wc_FreeDsaKey(&genKey); - TEST_XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } #endif /* WOLFSSL_KEY_GEN */ @@ -6526,7 +6677,7 @@ typedef struct eccVector { static int ecc_test_vector_item(const eccVector* vector) { - int ret, verify; + int ret = 0, verify; word32 x; ecc_key userA; byte sig[1024]; @@ -6539,22 +6690,24 @@ static int ecc_test_vector_item(const eccVector* vector) ret = wc_ecc_import_raw(&userA, vector->Qx, vector->Qy, vector->d, vector->curveName); if (ret != 0) - return -1018; + goto done; ret = wc_ecc_rs_to_sig(vector->R, vector->S, sig, &x); if (ret != 0) - return -1019; + goto done; - ret = wc_ecc_verify_hash(sig, x, (byte*)vector->msg, vector->msgLen, &verify, &userA); + ret = wc_ecc_verify_hash(sig, x, (byte*)vector->msg, vector->msgLen, + &verify, &userA); if (ret != 0) - return -1021; + goto done; if (verify != 1) - return -1023; + ret = -1023; +done: wc_ecc_free(&userA); - return 0; + return ret; } static int ecc_test_vector(int keySize) @@ -6638,7 +6791,7 @@ static int ecc_test_vector(int keySize) #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES) case 30: - return 0; + return 0; #endif /* HAVE_ECC239 */ #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) @@ -6751,7 +6904,7 @@ static int ecc_test_vector(int keySize) #ifdef WOLFSSL_KEY_GEN static int ecc_test_key_gen(WC_RNG* rng, int keySize) { - int ret; + int ret = 0; int derSz, pemSz; byte der[FOURK_BUF]; byte pem[FOURK_BUF]; @@ -6764,46 +6917,49 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) ret = wc_ecc_make_key(rng, keySize, &userA); if (ret != 0) - return -1014; + goto done; ret = wc_ecc_check_key(&userA); if (ret != 0) - return -1023; + goto done; derSz = wc_EccKeyToDer(&userA, der, FOURK_BUF); if (derSz < 0) { - return -1024; + ERROR_OUT(derSz, done); } keyFile = fopen("./ecc-key.der", "wb"); if (!keyFile) { - return -1025; + ERROR_OUT(-1025, done); } ret = (int)fwrite(der, 1, derSz, keyFile); fclose(keyFile); if (ret != derSz) { - return -1026; + ERROR_OUT(-1026, done); } pemSz = wc_DerToPem(der, derSz, pem, FOURK_BUF, ECC_PRIVATEKEY_TYPE); if (pemSz < 0) { - return -1027; + ERROR_OUT(pemSz, done); } pemFile = fopen("./ecc-key.pem", "wb"); if (!pemFile) { - return -1028; + ERROR_OUT(-1028, done); } ret = (int)fwrite(pem, 1, pemSz, pemFile); fclose(pemFile); if (ret != pemSz) { - return -1029; + ERROR_OUT(-1029, done); } /* test export of public key */ derSz = wc_EccPublicKeyToDer(&userA, der, FOURK_BUF, 1); - if (derSz <= 0) { - return -5516; + if (derSz < 0) { + ERROR_OUT(derSz, done); + } + if (derSz == 0) { + ERROR_OUT(-5416, done); } #ifdef FREESCALE_MQX keyFile = fopen("a:\\certs\\ecc-public-key.der", "wb"); @@ -6811,17 +6967,19 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) keyFile = fopen("./ecc-public-key.der", "wb"); #endif if (!keyFile) { - return -5417; + ERROR_OUT(-5417, done); } ret = (int)fwrite(der, 1, derSz, keyFile); fclose(keyFile); if (ret != derSz) { - return -5418; + ERROR_OUT(-5418, done); } + ret = 0; +done: wc_ecc_free(&userA); - return 0; + return ret; } #endif /* WOLFSSL_KEY_GEN */ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, @@ -6857,28 +7015,27 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, ret = wc_ecc_make_key_ex(rng, keySize, &userA, curve_id); if (ret != 0) - ERROR_OUT(-1014, done); + goto done; ret = wc_ecc_check_key(&userA); if (ret != 0) - ERROR_OUT(-1023, done); + goto done; ret = wc_ecc_make_key_ex(rng, keySize, &userB, curve_id); if (ret != 0) - ERROR_OUT(-1002, done); + goto done; #ifdef HAVE_ECC_DHE x = sizeof(sharedA); ret = wc_ecc_shared_secret(&userA, &userB, sharedA, &x); if (ret != 0) { - printf("wc_ecc_shared_secret %d\n", ret); - ERROR_OUT(-1015, done); + goto done; } y = sizeof(sharedB); ret = wc_ecc_shared_secret(&userB, &userA, sharedB, &y); if (ret != 0) - ERROR_OUT(-1003, done); + goto done; if (y != x) ERROR_OUT(-1004, done); @@ -6891,18 +7048,18 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, x = sizeof(exportBuf); ret = wc_ecc_export_x963(&userA, exportBuf, &x); if (ret != 0) - ERROR_OUT(-1006, done); + goto done; #ifdef HAVE_ECC_KEY_IMPORT ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, curve_id); if (ret != 0) - ERROR_OUT(-1007, done); + goto done; #ifdef HAVE_ECC_DHE y = sizeof(sharedB); ret = wc_ecc_shared_secret(&userB, &pubKey, sharedB, &y); if (ret != 0) - ERROR_OUT(-1008, done); + goto done; if (XMEMCMP(sharedA, sharedB, y)) ERROR_OUT(-1009, done); @@ -6913,19 +7070,19 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, x = sizeof(exportBuf); ret = wc_ecc_export_x963_ex(&userA, exportBuf, &x, 1); if (ret != 0) - ERROR_OUT(-1010, done); + goto done; wc_ecc_free(&pubKey); wc_ecc_init(&pubKey); ret = wc_ecc_import_x963_ex(exportBuf, x, &pubKey, curve_id); if (ret != 0) - ERROR_OUT(-1011, done); + goto done; #ifdef HAVE_ECC_DHE y = sizeof(sharedB); ret = wc_ecc_shared_secret(&userB, &pubKey, sharedB, &y); if (ret != 0) - ERROR_OUT(-1012, done); + goto done; if (XMEMCMP(sharedA, sharedB, y)) ERROR_OUT(-1013, done); @@ -6944,16 +7101,15 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, x = sizeof(sig); ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &x, rng, &userA); - if (ret != 0) - ERROR_OUT(-1014, done); + goto done; #ifdef HAVE_ECC_VERIFY for (i=0; i 0) @@ -8419,27 +8575,27 @@ int pkcs7signed_test(void) dataSz = (word32) XSTRLEN(data); outSz = FOURK_BUF; - certDer =(byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + certDer =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (certDer == NULL) return -207; - keyDer = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + keyDer = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (keyDer == NULL) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -208; } - out = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + out = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (out == NULL) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -209; } /* read in DER cert of recipient, into cert of size certSz */ file = fopen(clientCert, "rb"); if (!file) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); err_sys("can't open ./certs/client-cert.der, " "Please run from wolfSSL home dir", -44); return -44; @@ -8449,9 +8605,9 @@ int pkcs7signed_test(void) file = fopen(clientKey, "rb"); if (!file) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -45); return -45; @@ -8461,9 +8617,9 @@ int pkcs7signed_test(void) ret = wc_InitRng(&rng); if (ret != 0) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -210; } @@ -8472,9 +8628,9 @@ int pkcs7signed_test(void) ret = wc_RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ); if (ret != 0) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -211; } @@ -8498,9 +8654,9 @@ int pkcs7signed_test(void) ret = wc_InitSha(&sha); if (ret != 0) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -4003; } wc_ShaUpdate(&sha, msg.publicKey, msg.publicKeySz); @@ -8512,9 +8668,9 @@ int pkcs7signed_test(void) } ret = wc_PKCS7_EncodeSignedData(&msg, out, outSz); if (ret < 0) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&msg); return -212; } @@ -8524,18 +8680,18 @@ int pkcs7signed_test(void) /* write PKCS#7 to output file for more testing */ file = fopen("./pkcs7signedData.der", "wb"); if (!file) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&msg); return -213; } ret = (int)fwrite(out, 1, outSz, file); fclose(file); if (ret != (int)outSz) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&msg); return -218; } @@ -8545,35 +8701,35 @@ int pkcs7signed_test(void) ret = wc_PKCS7_VerifySignedData(&msg, out, outSz); if (ret < 0) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&msg); return -214; } if (msg.singleCert == NULL || msg.singleCertSz == 0) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&msg); return -215; } file = fopen("./pkcs7cert.der", "wb"); if (!file) { - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&msg); return -216; } ret = (int)fwrite(msg.singleCert, 1, msg.singleCertSz, file); fclose(file); - TEST_XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&msg); wc_FreeRng(&rng); diff --git a/wolfcrypt/user-crypto/include/user_rsa.h b/wolfcrypt/user-crypto/include/user_rsa.h index 72d2c610eb..771982fa8c 100644 --- a/wolfcrypt/user-crypto/include/user_rsa.h +++ b/wolfcrypt/user-crypto/include/user_rsa.h @@ -76,6 +76,7 @@ typedef struct RsaKey { } RsaKey; WOLFSSL_API int wc_InitRsaKey(RsaKey* key, void*); +WOLFSSL_API int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId); WOLFSSL_API int wc_FreeRsaKey(RsaKey* key); WOLFSSL_API int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, diff --git a/wolfcrypt/user-crypto/src/rsa.c b/wolfcrypt/user-crypto/src/rsa.c index 974789ce7c..8beb6bf8c1 100644 --- a/wolfcrypt/user-crypto/src/rsa.c +++ b/wolfcrypt/user-crypto/src/rsa.c @@ -74,7 +74,7 @@ enum { }; -int wc_InitRsaKey(RsaKey* key, void* heap) +int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) { USER_DEBUG(("Entering wc_InitRsaKey\n")); @@ -87,10 +87,16 @@ int wc_InitRsaKey(RsaKey* key, void* heap) USER_DEBUG(("\tExit wc_InitRsaKey\n")); + (void)devId; (void)heap; return 0; } +int wc_InitRsaKey(RsaKey* key, void* heap) +{ + return wc_InitRsaKey_ex(key, heap, INVALID_DEVID); +} + /* three functions needed for cert and key gen */ #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) diff --git a/wolfssl-ntru.vcproj b/wolfssl-ntru.vcproj index b427e9c0a8..a9f5c45770 100755 --- a/wolfssl-ntru.vcproj +++ b/wolfssl-ntru.vcproj @@ -322,6 +322,10 @@ RelativePath=".\wolfcrypt\src\wc_encrypt.c" > + + + + + diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 4f484aa6b2..bf9861946c 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -142,7 +142,6 @@ enum wolfSSL_ErrorCodes { UNKNOWN_ALPN_PROTOCOL_NAME_E = -405, /* Unrecognized protocol name Error*/ BAD_CERTIFICATE_STATUS_ERROR = -406, /* Bad certificate status message */ OCSP_INVALID_STATUS = -407, /* Invalid OCSP Status */ - ASYNC_NOT_PENDING = -408, /* Async operation not pending */ RSA_KEY_SIZE_E = -409, /* RSA key too small */ ECC_KEY_SIZE_E = -410, /* ECC key too small */ @@ -150,11 +149,13 @@ enum wolfSSL_ErrorCodes { DTLS_EXPORT_VER_E = -411, /* export version error */ INPUT_SIZE_E = -412, /* input size too big error */ CTX_INIT_MUTEX_E = -413, /* initialize ctx mutex error */ + EXT_MASTER_SECRET_NEEDED_E = -414, /* need EMS enabled to resume */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ /* begin negotiation parameter errors */ UNSUPPORTED_SUITE = -500, /* unsupported cipher suite */ - MATCH_SUITE_ERROR = -501 /* can't match cipher suite */ + MATCH_SUITE_ERROR = -501, /* can't match cipher suite */ + COMPRESSION_ERROR = -502 /* compression mismatch */ /* end negotiation parameter errors only 10 for now */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ac6f062f89..5f67dc33eb 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -155,7 +155,7 @@ #endif #ifdef WOLFSSL_ASYNC_CRYPT - #include + #include #endif #ifdef _MSC_VER @@ -878,6 +878,7 @@ enum Misc { NO_COMPRESSION = 0, ZLIB_COMPRESSION = 221, /* wolfSSL zlib compression */ HELLO_EXT_SIG_ALGO = 13, /* ID for the sig_algo hello extension */ + HELLO_EXT_EXTMS = 0x0017, /* ID for the extended master secret ext */ SECRET_LEN = 48, /* pre RSA and all master */ #if defined(WOLFSSL_MYSQL_COMPATIBLE) ENCRYPT_LEN = 1024, /* allow larger static buffer with mysql */ @@ -939,10 +940,10 @@ enum Misc { REQ_HEADER_SZ = 2, /* cert request header sz */ HINT_LEN_SZ = 2, /* length of hint size field */ TRUNCATED_HMAC_SZ = 10, /* length of hmac w/ truncated hmac extension */ + HELLO_EXT_SZ = 4, /* base length of a hello extension */ HELLO_EXT_TYPE_SZ = 2, /* length of a hello extension type */ - HELLO_EXT_SZ = 8, /* total length of the lazy hello extensions */ - HELLO_EXT_LEN = 6, /* length of the lazy hello extensions */ - HELLO_EXT_SIGALGO_SZ = 2, /* length of signature algo extension */ + HELLO_EXT_SZ_SZ = 2, /* length of a hello extension size */ + HELLO_EXT_SIGALGO_SZ = 2, /* length of number of items in sigalgo list */ HELLO_EXT_SIGALGO_MAX = 32, /* number of items in the signature algo list */ DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */ @@ -963,6 +964,7 @@ enum Misc { MAX_EXPORT_BUFFER = 500, /* max size of buffer for exporting */ FINISHED_LABEL_SZ = 15, /* TLS finished label size */ TLS_FINISHED_SZ = 12, /* TLS has a shorter size */ + EXT_MASTER_LABEL_SZ = 22, /* TLS extended master secret label sz */ MASTER_LABEL_SZ = 13, /* TLS master secret label sz */ KEY_LABEL_SZ = 13, /* TLS key block expansion sz */ MAX_PRF_HALF = 256, /* Maximum half secret len */ @@ -1059,8 +1061,6 @@ enum Misc { HASH_SIG_SIZE = 2, /* default SHA1 RSA */ - NO_CAVIUM_DEVICE = -2, /* invalid cavium device id */ - NO_COPY = 0, /* should we copy static buffer for write */ COPY = 1 /* should we copy static buffer for write */ }; @@ -1899,24 +1899,6 @@ WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name); #endif /* HAVE_QSH */ -#ifdef HAVE_WOLF_EVENT -typedef struct { - WOLF_EVENT* head; /* head of queue */ - WOLF_EVENT* tail; /* tail of queue */ -#ifndef SINGLE_THREADED - wolfSSL_Mutex lock; /* queue lock */ -#endif -} WOLF_EVENT_QUEUE; - -WOLFSSL_LOCAL int wolfSSL_EventInit(WOLFSSL* ssl, WOLF_EVENT_TYPE type); - -WOLFSSL_LOCAL int wolfSSL_CTX_EventPush(WOLFSSL_CTX* ctx, WOLF_EVENT* event); -#endif /* HAVE_WOLF_EVENT */ - -#ifdef WOLFSSL_STATIC_MEMORY -WOLFSSL_LOCAL int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap); -#endif - /* wolfSSL context type */ struct WOLFSSL_CTX { WOLFSSL_METHOD* method; @@ -1956,6 +1938,11 @@ struct WOLFSSL_CTX { byte quietShutdown; /* don't send close notify */ byte groupMessages; /* group handshake messages before sending */ byte minDowngrade; /* minimum downgrade version */ + byte haveEMS; /* have extended master secret extension */ +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) + byte dtlsSctp; /* DTLS-over-SCTP mode */ + word16 dtlsMtuSz; /* DTLS MTU size */ +#endif #ifndef NO_DH word16 minDhKeySz; /* minimum DH key size */ #endif @@ -2002,9 +1989,7 @@ struct WOLFSSL_CTX { #ifdef HAVE_OCSP WOLFSSL_OCSP ocsp; #endif -#ifdef HAVE_CAVIUM - int devId; /* cavium device id to use */ -#endif + int devId; /* async device id to use */ #ifdef HAVE_TLS_EXTENSIONS TLSX* extensions; /* RFC 6066 TLS Extensions data */ #ifndef NO_WOLFSSL_SERVER @@ -2243,6 +2228,7 @@ struct WOLFSSL_SESSION { byte sessionID[ID_LEN]; /* id for protocol */ byte sessionIDSz; byte masterSecret[SECRET_LEN]; /* stored secret */ + word16 haveEMS; /* ext master secret flag */ #ifdef SESSION_CERTS WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */ ProtocolVersion version; /* which version was used */ @@ -2314,6 +2300,7 @@ enum AcceptState { enum KeyShareState { KEYSHARE_BEGIN = 0, KEYSHARE_BUILD, + KEYSHARE_DO, KEYSHARE_VERIFY, KEYSHARE_FINALIZE, KEYSHARE_END @@ -2326,6 +2313,7 @@ typedef struct Buffers { buffer domainName; /* for client check */ buffer clearOutputBuffer; buffer sig; /* signature data */ + buffer digest; /* digest data */ int prevSent; /* previous plain text bytes sent when got WANT_WRITE */ int plainSz; /* plain text bytes in buffer to send @@ -2421,7 +2409,11 @@ typedef struct Options { #endif #ifdef WOLFSSL_DTLS word16 dtlsHsRetain:1; /* DTLS retaining HS data */ +#ifdef WOLFSSL_SCTP + word16 dtlsSctp:1; /* DTLS-over-SCTP mode */ #endif +#endif + word16 haveEMS:1; /* using extended master secret */ /* need full byte values for this section */ byte processReply; /* nonblocking resume */ @@ -2683,7 +2675,8 @@ struct WOLFSSL { void* hsDoneCtx; /* user handshake cb context */ #endif #ifdef WOLFSSL_ASYNC_CRYPT - AsyncCrypt async; + AsyncCryptSSLState async; + AsyncCryptDev asyncDev; #endif void* sigKey; /* RsaKey or ecc_key allocated from heap */ word32 sigType; /* Type of sigKey */ @@ -2759,6 +2752,9 @@ struct WOLFSSL { void* IOCB_CookieCtx; /* gen cookie ctx */ word32 dtls_expected_rx; wc_dtls_export dtls_export; /* export function for session */ +#ifdef WOLFSSL_SCTP + word16 dtlsMtuSz; +#endif /* WOLFSSL_SCTP */ #endif #ifdef WOLFSSL_CALLBACKS HandShakeInfo handShakeInfo; /* info saved during handshake */ @@ -2782,9 +2778,7 @@ struct WOLFSSL { #if defined(FORTRESS) || defined(HAVE_STUNNEL) void* ex_data[MAX_EX_DATA]; /* external data, for Fortress */ #endif -#ifdef HAVE_CAVIUM - int devId; /* cavium device id to use */ -#endif + int devId; /* async device id to use */ #ifdef HAVE_ONE_TIME_AUTH OneTimeAuth auth; #endif @@ -2846,9 +2840,6 @@ struct WOLFSSL { #ifdef HAVE_WOLF_EVENT WOLF_EVENT event; #endif /* HAVE_WOLF_EVENT */ -#ifdef WOLFSSL_ASYNC_CRYPT_TEST - AsyncCryptTests asyncCryptTest; -#endif /* WOLFSSL_ASYNC_CRYPT_TEST */ }; @@ -3001,7 +2992,7 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); #ifndef NO_CERTS #ifndef NO_RSA WOLFSSL_LOCAL int VerifyRsaSign(WOLFSSL* ssl, - const byte* sig, word32 sigSz, + byte* verifySig, word32 sigSz, const byte* plain, word32 plainSz, RsaKey* key); WOLFSSL_LOCAL int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, @@ -3010,6 +3001,8 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); byte** out, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx); WOLFSSL_LOCAL int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx); + WOLFSSL_LOCAL int RsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, + word32* outSz, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx); #endif /* !NO_RSA */ #ifdef HAVE_ECC @@ -3017,7 +3010,7 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); byte* out, word32* outSz, ecc_key* key, byte* keyBuf, word32 keySz, void* ctx); WOLFSSL_LOCAL int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, - byte* out, word32 outSz, ecc_key* key, byte* keyBuf, word32 keySz, + const byte* out, word32 outSz, ecc_key* key, byte* keyBuf, word32 keySz, void* ctx); WOLFSSL_LOCAL int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, byte* out, word32* outSz); @@ -3040,6 +3033,8 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); WOLFSSL_LOCAL Signer* GetCAByName(void* cm, byte* hash); #endif #endif /* !NO_CERTS */ +WOLFSSL_LOCAL int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, + word32* hashLen); WOLFSSL_LOCAL int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender); WOLFSSL_LOCAL void FreeArrays(WOLFSSL* ssl, int keep); @@ -3132,7 +3127,7 @@ WOLFSSL_LOCAL int SetKeysSide(WOLFSSL*, enum encrypt_side); #endif #ifdef HAVE_ECC - WOLFSSL_LOCAL int EccMakeTempKey(WOLFSSL* ssl); + WOLFSSL_LOCAL int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer); #endif WOLFSSL_LOCAL int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, diff --git a/wolfssl/sniffer_error.h b/wolfssl/sniffer_error.h index 327455ec2a..0c04ba878e 100644 --- a/wolfssl/sniffer_error.h +++ b/wolfssl/sniffer_error.h @@ -117,6 +117,7 @@ #define CLEAR_ACK_FAULT 80 #define BAD_DECRYPT_SIZE 81 +#define EXTENDED_MASTER_HASH_STR 82 /* !!!! also add to msgTable in sniffer.c and .rc file !!!! */ diff --git a/wolfssl/sniffer_error.rc b/wolfssl/sniffer_error.rc index e7d9980598..947be61191 100644 --- a/wolfssl/sniffer_error.rc +++ b/wolfssl/sniffer_error.rc @@ -98,5 +98,6 @@ STRINGTABLE 80, "Clear ACK Fault" 81, "Bad Decrypt Size" + 82, "Extended Master Secret Hash Error" } diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index ca35458fa1..ffebc9ee21 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -31,6 +31,10 @@ #include #include +#ifdef HAVE_WOLF_EVENT + #include +#endif + #ifndef NO_FILESYSTEM #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) #if MQX_USE_IO_OLD @@ -405,6 +409,11 @@ WOLFSSL_API int wolfSSL_dtls(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int); WOLFSSL_API int wolfSSL_dtls_get_peer(WOLFSSL*, void*, unsigned int*); +WOLFSSL_API int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_dtls_set_sctp(WOLFSSL*); +WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned short); +WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned short); + WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err); WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*); WOLFSSL_API void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, @@ -1416,9 +1425,9 @@ WOLFSSL_API void wolfSSL_KeepArrays(WOLFSSL*); WOLFSSL_API void wolfSSL_FreeArrays(WOLFSSL*); -/* cavium additions */ -WOLFSSL_API int wolfSSL_UseCavium(WOLFSSL*, int devId); -WOLFSSL_API int wolfSSL_CTX_UseCavium(WOLFSSL_CTX*, int devId); +/* async additions */ +WOLFSSL_API int wolfSSL_UseAsync(WOLFSSL*, int devId); +WOLFSSL_API int wolfSSL_CTX_UseAsync(WOLFSSL_CTX*, int devId); /* TLS Extensions */ @@ -1695,6 +1704,11 @@ WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name); #endif #endif +/* TLS Extended Master Secret Extension */ +WOLFSSL_API int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx); + + #define WOLFSSL_CRL_MONITOR 0x01 /* monitor this dir flag */ #define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */ @@ -1716,6 +1730,12 @@ int wolfSSL_MakeTlsMasterSecret(unsigned char* ms, unsigned int msLen, const unsigned char* cr, const unsigned char* sr, int tls1_2, int hash_type); +WOLFSSL_API +int wolfSSL_MakeTlsExtendedMasterSecret(unsigned char* ms, unsigned int msLen, + const unsigned char* pms, unsigned int pmsLen, + const unsigned char* sHash, unsigned int sHashLen, + int tls1_2, int hash_type); + WOLFSSL_API int wolfSSL_DeriveTlsKeys(unsigned char* key_data, unsigned int keyLen, const unsigned char* ms, unsigned int msLen, @@ -1909,41 +1929,13 @@ WOLFSSL_API int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr); WOLFSSL_API void* wolfSSL_get_jobject(WOLFSSL* ssl); #endif /* WOLFSSL_JNI */ -#ifdef HAVE_WOLF_EVENT -typedef enum WOLF_EVENT_TYPE { - WOLF_EVENT_TYPE_NONE, - #ifdef WOLFSSL_ASYNC_CRYPT - WOLF_EVENT_TYPE_ASYNC_ACCEPT, - WOLF_EVENT_TYPE_ASYNC_CONNECT, - WOLF_EVENT_TYPE_ASYNC_READ, - WOLF_EVENT_TYPE_ASYNC_WRITE, - WOLF_EVENT_TYPE_ASYNC_FIRST = WOLF_EVENT_TYPE_ASYNC_ACCEPT, - WOLF_EVENT_TYPE_ASYNC_LAST = WOLF_EVENT_TYPE_ASYNC_WRITE, - #endif -} WOLF_EVENT_TYPE; -typedef struct WOLF_EVENT WOLF_EVENT; -struct WOLF_EVENT { - WOLF_EVENT* next; /* To support event linked list */ - WOLFSSL* ssl; /* Reference back to SSL object */ - int ret; /* Async return code */ - WOLF_EVENT_TYPE type; - unsigned short pending:1; - unsigned short done:1; - /* Future event flags can go here */ -}; +#ifdef WOLFSSL_ASYNC_CRYPT +WOLFSSL_API int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags); +WOLFSSL_API int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents, + WOLF_EVENT_FLAG flags, int* eventCount); +#endif /* WOLFSSL_ASYNC_CRYPT */ -enum WOLF_POLL_FLAGS { - WOLF_POLL_FLAG_CHECK_HW = 0x01, - WOLF_POLL_FLAG_PEEK = 0x02, -}; - -WOLFSSL_API int wolfSSL_CTX_poll(WOLFSSL_CTX* ctx, WOLF_EVENT* events, - int maxEvents, unsigned char flags, int* eventCount); -WOLFSSL_API int wolfSSL_poll(WOLFSSL* ssl, WOLF_EVENT* events, - int maxEvents, unsigned char flags, int* eventCount); - -#endif /* HAVE_WOLF_EVENT */ #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/test.h b/wolfssl/test.h index d8922b2232..51be479e33 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -107,10 +107,11 @@ #define SNPRINTF snprintf #endif /* USE_WINDOWS_API */ +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif #ifdef HAVE_CAVIUM - #include "cavium_sysdep.h" - #include "cavium_common.h" - #include "cavium_ioctl.h" + #include #endif #ifdef _MSC_VER @@ -354,11 +355,29 @@ void join_thread(THREAD_TYPE); #endif static const word16 wolfSSLPort = 11111; -static INLINE void err_sys(const char* msg) + +#if defined(__GNUC__) + #define WC_NORETURN __attribute__((noreturn)) +#else + #define WC_NORETURN +#endif + +static INLINE WC_NORETURN void err_sys(const char* msg) { printf("wolfSSL error: %s\n", msg); + +#if !defined(__GNUC__) + /* scan-build (which pretends to be gnuc) can get confused and think the + * msg pointer can be null even when hardcoded and then it won't exit, + * making null pointer checks above the err_sys() call useless. + * We could just always exit() but some compilers will complain about no + * possible return, with gcc we know the attribute to handle that with + * WC_NORETURN. */ if (msg) +#endif + { exit(EXIT_FAILURE); + } } @@ -545,11 +564,12 @@ static INLINE void showPeer(WOLFSSL* ssl) static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, - word16 port, int udp) + word16 port, int udp, int sctp) { int useLookup = 0; (void)useLookup; (void)udp; + (void)sctp; if (addr == NULL) err_sys("invalid argument to build_addr, addr is NULL"); @@ -609,8 +629,17 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET_V; - hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; + if (udp) { + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else if (sctp) { + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_SCTP; + } + else { + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + } SNPRINTF(strPort, sizeof(strPort), "%d", port); strPort[79] = '\0'; @@ -630,12 +659,14 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, } -static INLINE void tcp_socket(SOCKET_T* sockfd, int udp) +static INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) { if (udp) - *sockfd = socket(AF_INET_V, SOCK_DGRAM, 0); + *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP); + else if (sctp) + *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP); else - *sockfd = socket(AF_INET_V, SOCK_STREAM, 0); + *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP); if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) { err_sys("socket failed\n"); @@ -658,7 +689,7 @@ static INLINE void tcp_socket(SOCKET_T* sockfd, int udp) #endif /* S_NOSIGPIPE */ #if defined(TCP_NODELAY) - if (!udp) + if (!udp && !sctp) { int on = 1; socklen_t len = sizeof(on); @@ -671,14 +702,14 @@ static INLINE void tcp_socket(SOCKET_T* sockfd, int udp) } static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, - int udp, WOLFSSL* ssl) + int udp, int sctp, WOLFSSL* ssl) { SOCKADDR_IN_T addr; - build_addr(&addr, ip, port, udp); - if(udp) { + build_addr(&addr, ip, port, udp, sctp); + if (udp) { wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); } - tcp_socket(sockfd, udp); + tcp_socket(sockfd, udp, sctp); if (!udp) { if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) @@ -738,14 +769,14 @@ static INLINE int tcp_select(SOCKET_T socketfd, int to_sec) static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr, - int udp) + int udp, int sctp) { SOCKADDR_IN_T addr; /* don't use INADDR_ANY by default, firewall may block, make user switch on */ - build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp); - tcp_socket(sockfd, udp); + build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp); + tcp_socket(sockfd, udp, sctp); #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\ && !defined(WOLFSSL_KEIL_TCP_NET) @@ -807,8 +838,8 @@ static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, SOCKADDR_IN_T addr; (void)args; - build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1); - tcp_socket(sockfd, 1); + build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0); + tcp_socket(sockfd, 1, 0); #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \ @@ -860,7 +891,7 @@ static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, func_args* args, word16 port, int useAnyAddr, - int udp, int ready_file, int do_listen) + int udp, int sctp, int ready_file, int do_listen) { SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); @@ -874,7 +905,7 @@ static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, } if(do_listen) { - tcp_listen(sockfd, &port, useAnyAddr, udp); + tcp_listen(sockfd, &port, useAnyAddr, udp, sctp); #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) /* signal ready to tcp_accept */ @@ -1218,29 +1249,6 @@ static INLINE void CaCb(unsigned char* der, int sz, int type) #endif /* !NO_CERTS */ -#ifdef HAVE_CAVIUM - -static INLINE int OpenNitroxDevice(int dma_mode,int dev_id) -{ - Csp1CoreAssignment core_assign; - Uint32 device; - - if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID)) - return -1; - if (Csp1GetDevType(&device)) - return -1; - if (device != NPX_DEVICE) { - if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT, - (Uint32 *)&core_assign)!= 0) - return -1; - } - CspShutdown(CAVIUM_DEV_ID); - - return CspInitialize(dma_mode, dev_id); -} - -#endif /* HAVE_CAVIUM */ - /* Wolf Root Directory Helper */ /* KEIL-RL File System does not support relative directory */ @@ -1974,24 +1982,6 @@ static INLINE const char* mymktemp(char *tempfn, int len, int num) #endif /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */ -#ifdef WOLFSSL_ASYNC_CRYPT - static INLINE int AsyncCryptPoll(WOLFSSL* ssl) - { - int ret, eventCount = 0; - WOLF_EVENT events[1]; - - printf("Connect/Accept got WC_PENDING_E\n"); - - ret = wolfSSL_poll(ssl, events, sizeof(events)/sizeof(WOLF_EVENT), - WOLF_POLL_FLAG_CHECK_HW, &eventCount); - if (ret == 0 && eventCount > 0) { - ret = 1; /* Success */ - } - - return ret; - } -#endif - static INLINE word16 GetRandomPort(void) { word16 port = 0; diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 125d63b94c..c812741eb2 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -39,10 +39,6 @@ #endif #ifndef HAVE_FIPS /* to avoid redefinition of macros */ -#ifdef HAVE_CAVIUM - #include - #include "cavium_common.h" -#endif #ifdef WOLFSSL_AESNI @@ -50,23 +46,8 @@ #include #include -#if !defined (ALIGN16) - #if defined (__GNUC__) - #define ALIGN16 __attribute__ ( (aligned (16))) - #elif defined(_MSC_VER) - /* disable align warning, we want alignment ! */ - #pragma warning(disable: 4324) - #define ALIGN16 __declspec (align (16)) - #else - #define ALIGN16 - #endif -#endif - #endif /* WOLFSSL_AESNI */ -#if !defined (ALIGN16) - #define ALIGN16 -#endif #endif /* HAVE_FIPS */ #ifdef __cplusplus @@ -74,7 +55,10 @@ #endif #ifndef HAVE_FIPS /* to avoid redefinition of structures */ -#define WOLFSSL_AES_CAVIUM_MAGIC 0xBEEF0002 + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif enum { AES_ENC_TYPE = 1, /* cipher unique type */ @@ -102,12 +86,12 @@ typedef struct Aes { #ifdef WOLFSSL_AESNI byte use_aesni; #endif /* WOLFSSL_AESNI */ -#ifdef HAVE_CAVIUM - AesType type; /* aes key type */ - int devId; /* nitrox device id */ - word32 magic; /* using cavium magic */ - word64 contextHandle; /* nitrox context memory handle */ -#endif +#ifdef WOLFSSL_ASYNC_CRYPT + AsyncCryptDev asyncDev; + #ifdef HAVE_CAVIUM + AesType type; /* aes key type */ + #endif +#endif /* WOLFSSL_ASYNC_CRYPT */ #ifdef WOLFSSL_AES_COUNTER word32 left; /* unused bytes left from last call */ #endif @@ -183,9 +167,9 @@ WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* authIn, word32 authInSz); #endif /* HAVE_AESCCM */ -#ifdef HAVE_CAVIUM - WOLFSSL_API int wc_AesInitCavium(Aes*, int); - WOLFSSL_API void wc_AesFreeCavium(Aes*); +#ifdef WOLFSSL_ASYNC_CRYPT + WOLFSSL_API int wc_AesAsyncInit(Aes*, int); + WOLFSSL_API void wc_AesAsyncFree(Aes*); #endif #ifdef __cplusplus diff --git a/wolfssl/wolfcrypt/arc4.h b/wolfssl/wolfcrypt/arc4.h index a97430632e..752f1d0623 100644 --- a/wolfssl/wolfcrypt/arc4.h +++ b/wolfssl/wolfcrypt/arc4.h @@ -30,7 +30,9 @@ extern "C" { #endif -#define WOLFSSL_ARC4_CAVIUM_MAGIC 0xBEEF0001 +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif enum { ARC4_ENC_TYPE = 4, /* cipher unique type */ @@ -42,19 +44,17 @@ typedef struct Arc4 { byte x; byte y; byte state[ARC4_STATE_SIZE]; -#ifdef HAVE_CAVIUM - int devId; /* nitrox device id */ - word32 magic; /* using cavium magic */ - word64 contextHandle; /* nitrox context memory handle */ +#ifdef WOLFSSL_ASYNC_CRYPT + AsyncCryptDev asyncDev; #endif } Arc4; WOLFSSL_API void wc_Arc4Process(Arc4*, byte*, const byte*, word32); WOLFSSL_API void wc_Arc4SetKey(Arc4*, const byte*, word32); -#ifdef HAVE_CAVIUM - WOLFSSL_API int wc_Arc4InitCavium(Arc4*, int); - WOLFSSL_API void wc_Arc4FreeCavium(Arc4*); +#ifdef WOLFSSL_ASYNC_CRYPT + WOLFSSL_API int wc_Arc4AsyncInit(Arc4*, int); + WOLFSSL_API void wc_Arc4AsyncFree(Arc4*); #endif #ifdef __cplusplus diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index f609e0ab14..6aba913d2a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -312,8 +312,10 @@ enum ExtKeyUsage_Sum { /* From RFC 5280 */ enum VerifyType { - NO_VERIFY = 0, - VERIFY = 1 + NO_VERIFY = 0, + VERIFY = 1, + VERIFY_CRL = 2, + VERIFY_OCSP = 3 }; #ifdef WOLFSSL_CERT_EXT diff --git a/wolfssl/wolfcrypt/des3.h b/wolfssl/wolfcrypt/des3.h index 370b52d44b..07ddb1aaa6 100644 --- a/wolfssl/wolfcrypt/des3.h +++ b/wolfssl/wolfcrypt/des3.h @@ -37,7 +37,10 @@ #endif #ifndef HAVE_FIPS /* to avoid redefinition of macros */ -#define WOLFSSL_3DES_CAVIUM_MAGIC 0xBEEF0003 + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif enum { DES_ENC_TYPE = 2, /* cipher unique type */ @@ -76,10 +79,8 @@ typedef struct Des3 { word32 key[3][DES_KS_SIZE]; word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */ -#ifdef HAVE_CAVIUM - int devId; /* nitrox device id */ - word32 magic; /* using cavium magic */ - word64 contextHandle; /* nitrox context memory handle */ +#ifdef WOLFSSL_ASYNC_CRYPT + AsyncCryptDev asyncDev; #endif } Des3; #endif /* HAVE_FIPS */ @@ -102,9 +103,9 @@ WOLFSSL_API int wc_Des3_CbcEncrypt(Des3* des, byte* out, WOLFSSL_API int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in,word32 sz); -#ifdef HAVE_CAVIUM - WOLFSSL_API int wc_Des3_InitCavium(Des3*, int); - WOLFSSL_API void wc_Des3_FreeCavium(Des3*); +#ifdef WOLFSSL_ASYNC_CRYPT + WOLFSSL_API int wc_Des3AsyncInit(Des3*, int); + WOLFSSL_API void wc_Des3AsyncFree(Des3*); #endif #ifdef __cplusplus diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 9e82cb1117..70d67e4818 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -30,6 +30,10 @@ #include #include +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -230,6 +234,10 @@ typedef struct { ecc_point pubkey; /* public key */ mp_int k; /* private key */ void* heap; /* heap hint */ + +#ifdef WOLFSSL_ASYNC_CRYPT + AsyncCryptDev asyncDev; +#endif } ecc_key; @@ -275,7 +283,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, WOLFSSL_API int wc_ecc_init(ecc_key* key); WOLFSSL_API -int wc_ecc_init_h(ecc_key* key, void* heap); +int wc_ecc_init_ex(ecc_key* key, void* heap, int devId); WOLFSSL_API void wc_ecc_free(ecc_key* key); WOLFSSL_API @@ -421,6 +429,12 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, #endif /* HAVE_ECC_ENCRYPT */ +#ifdef WOLFSSL_ASYNC_CRYPT + WOLFSSL_API int wc_ecc_async_handle(ecc_key* key, + WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event); + WOLFSSL_API int wc_ecc_async_wait(int ret, ecc_key* key); +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index f165f27f50..d52c55acf4 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -44,6 +44,9 @@ enum { CRYPTGEN_E = -104, /* windows crypt generation error */ RAN_BLOCK_E = -105, /* reading random device would block */ BAD_MUTEX_E = -106, /* Bad mutex operation */ + WC_TIMEOUT_E = -107, /* timeout error */ + WC_PENDING_E = -108, /* wolfCrypt operation pending (would block) */ + WC_NOT_PENDING_E = -109, /* wolfCrypt operation not pending */ MP_INIT_E = -110, /* mp_init error state */ MP_READ_E = -111, /* mp_read error state */ @@ -61,7 +64,6 @@ enum { MEMORY_E = -125, /* out of memory error */ VAR_STATE_CHANGE_E = -126, /* var state modified by different thread */ - RSA_WRONG_TYPE_E = -130, /* RSA wrong block type for RSA function */ RSA_BUFFER_E = -131, /* RSA buffer error, output too small or input too large */ @@ -108,7 +110,7 @@ enum { AES_GCM_AUTH_E = -180, /* AES-GCM Authentication check failure */ AES_CCM_AUTH_E = -181, /* AES-CCM Authentication check failure */ - CAVIUM_INIT_E = -182, /* Cavium Init type error */ + ASYNC_INIT_E = -182, /* Async Init type error */ COMPRESS_INIT_E = -183, /* Compress init error */ COMPRESS_E = -184, /* Compress error */ @@ -121,7 +123,7 @@ enum { ASN_CRL_NO_SIGNER_E = -190, /* ASN CRL no signer to confirm failure */ ASN_OCSP_CONFIRM_E = -191, /* ASN OCSP signature confirm failure */ - BAD_ENC_STATE_E = -192, /* Bad ecc enc state operation */ + BAD_STATE_E = -192, /* Bad state operation */ BAD_PADDING_E = -193, /* Bad padding, msg not correct length */ REQ_ATTRIBUTE_E = -194, /* setting cert request attributes error */ @@ -169,7 +171,6 @@ enum { BAD_COND_E = -230, /* Bad condition variable operation */ SIG_TYPE_E = -231, /* Signature Type not enabled/available */ HASH_TYPE_E = -232, /* Hash Type not enabled/available */ - WC_PENDING_E = -233, /* wolfCrypt operation pending (would block) */ WC_KEY_SIZE_E = -234, /* Key size error, either too small or large */ ASN_COUNTRY_SIZE_E = -235, /* ASN Cert Gen, invalid country code size */ diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 37125cdcc7..1296c56f57 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -58,7 +58,7 @@ enum wc_HashType { #define WC_MAX_DIGEST_SIZE 64 /* default to max size of 64 */ #endif -#ifndef NO_ASN +#if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) WOLFSSL_API int wc_HashGetOID(enum wc_HashType hash_type); #endif @@ -105,10 +105,12 @@ WOLFSSL_API int wc_Sha256Hash(const byte*, word32, byte*); #ifdef WOLFSSL_SHA512 #include +WOLFSSL_API int wc_Sha512GetHash(Sha512*, byte*); WOLFSSL_API int wc_Sha512Hash(const byte*, word32, byte*); #define wc_Sha512Free(d) #if defined(WOLFSSL_SHA384) + WOLFSSL_API int wc_Sha384GetHash(Sha384*, byte*); WOLFSSL_API int wc_Sha384Hash(const byte*, word32, byte*); #define wc_Sha384Free(d) #endif /* defined(WOLFSSL_SHA384) */ diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index 5311c92e04..46f0b60790 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -53,17 +53,15 @@ #include #endif -#ifdef HAVE_CAVIUM - #include - #include "cavium_common.h" -#endif - #ifdef __cplusplus extern "C" { #endif #ifndef HAVE_FIPS -#define WOLFSSL_HMAC_CAVIUM_MAGIC 0xBEEF0005 + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif enum { HMAC_FIPS_MIN_KEY = 14, /* 112 bit key length minimum */ @@ -144,18 +142,18 @@ typedef struct Hmac { word32 ipad[HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/ word32 opad[HMAC_BLOCK_SIZE / sizeof(word32)]; word32 innerHash[MAX_DIGEST_SIZE / sizeof(word32)]; -#ifdef HAVE_CAVIUM - word64 contextHandle; /* nitrox context memory handle */ - HashType type; /* hmac key type */ - word32 magic; /* using cavium magic */ - int devId; /* nitrox device id */ - void* heap /* heap hint , currently only used with cavium */ - byte* data; /* buffered input data for one call */ - word16 keyLen; /* hmac key length */ - word16 dataLen; -#endif - byte macType; /* md5 sha or sha256 */ - byte innerHashKeyed; /* keyed flag */ + void* heap; /* heap hint */ + byte macType; /* md5 sha or sha256 */ + byte innerHashKeyed; /* keyed flag */ +#ifdef WOLFSSL_ASYNC_CRYPT + AsyncCryptDev asyncDev; + #ifdef HAVE_CAVIUM + word16 keyLen; /* hmac key length */ + word16 dataLen; + HashType type; /* hmac key type */ + byte* data; /* buffered input data for one call */ + #endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ } Hmac; #endif /* HAVE_FIPS */ @@ -164,12 +162,14 @@ typedef struct Hmac { WOLFSSL_API int wc_HmacSetKey(Hmac*, int type, const byte* key, word32 keySz); WOLFSSL_API int wc_HmacUpdate(Hmac*, const byte*, word32); WOLFSSL_API int wc_HmacFinal(Hmac*, byte*); - -#ifdef HAVE_CAVIUM - WOLFSSL_API int wc_HmacInitCavium(Hmac*, int); - WOLFSSL_API void wc_HmacFreeCavium(Hmac*); +WOLFSSL_API int wc_HmacSizeByType(int type); +#ifdef WOLFSSL_ASYNC_CRYPT + WOLFSSL_API int wc_HmacAsyncInit(Hmac*, int); + WOLFSSL_API void wc_HmacAsyncFree(Hmac*); #endif + + WOLFSSL_API int wolfSSL_GetHmacMaxSize(void); diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index cdce81c61d..43d9c227b1 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -56,10 +56,15 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/memory.h \ wolfssl/wolfcrypt/mpi_class.h \ wolfssl/wolfcrypt/mpi_superclass.h \ - wolfssl/wolfcrypt/mem_track.h + wolfssl/wolfcrypt/mem_track.h \ + wolfssl/wolfcrypt/wolfevent.h noinst_HEADERS+= \ wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ wolfssl/wolfcrypt/port/ti/ti-hash.h \ wolfssl/wolfcrypt/port/ti/ti-ccm.h \ wolfssl/wolfcrypt/port/nrf51.h + +if BUILD_CAVIUM +noinst_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h +endif diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 938fb2527f..3aa808b888 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -96,6 +96,7 @@ extern "C" { #elif defined(MP_16BIT) || defined(NO_64BIT) typedef unsigned short mp_digit; typedef unsigned int mp_word; + #define DIGIT_BIT 12 #elif defined(MP_64BIT) /* for GCC only on supported platforms */ typedef unsigned long long mp_digit; /* 64 bit type, 128 uses mode(TI) */ @@ -181,6 +182,9 @@ typedef int mp_err; typedef struct { int used, alloc, sign; mp_digit *dp; +#ifdef WOLFSSL_ASYNC_CRYPT + byte* dpraw; /* Used for hardware crypto */ +#endif } mp_int; /* callback for mp_prime_random, should fill dst with random bytes and return diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index cd44741b42..96dce8bdd6 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -33,36 +33,42 @@ extern "C" { #endif -#ifdef WOLFSSL_DEBUG_MEMORY - typedef void *(*wolfSSL_Malloc_cb)(size_t size, const char* func, unsigned int line); - typedef void (*wolfSSL_Free_cb)(void *ptr, const char* func, unsigned int line); - typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, const char* func, unsigned int line); - - /* Public in case user app wants to use XMALLOC/XFREE */ - WOLFSSL_API void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line); - WOLFSSL_API void wolfSSL_Free(void *ptr, const char* func, unsigned int line); - WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line); - -#else - #if defined(WOLFSSL_STATIC_MEMORY) - typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type); - typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type); - typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, - void* heap, int type); - WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type); - WOLFSSL_API void wolfSSL_Free(void *ptr, void* heap, int type); - WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, - void* heap, int type); +#ifdef WOLFSSL_STATIC_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY + typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type, const char* func, unsigned int line); + typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type, const char* func, unsigned int line); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line); + WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line); + WOLFSSL_API void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line); #else - typedef void *(*wolfSSL_Malloc_cb)(size_t size); - typedef void (*wolfSSL_Free_cb)(void *ptr); - typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size); - /* Public in case user app wants to use XMALLOC/XFREE */ - WOLFSSL_API void* wolfSSL_Malloc(size_t size); - WOLFSSL_API void wolfSSL_Free(void *ptr); - WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size); - #endif -#endif + typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type); + typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type); + WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type); + WOLFSSL_API void wolfSSL_Free(void *ptr, void* heap, int type); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type); + #endif /* WOLFSSL_DEBUG_MEMORY */ +#else + #ifdef WOLFSSL_DEBUG_MEMORY + typedef void *(*wolfSSL_Malloc_cb)(size_t size, const char* func, unsigned int line); + typedef void (*wolfSSL_Free_cb)(void *ptr, const char* func, unsigned int line); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, const char* func, unsigned int line); + + /* Public in case user app wants to use XMALLOC/XFREE */ + WOLFSSL_API void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line); + WOLFSSL_API void wolfSSL_Free(void *ptr, const char* func, unsigned int line); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line); + #else + typedef void *(*wolfSSL_Malloc_cb)(size_t size); + typedef void (*wolfSSL_Free_cb)(void *ptr); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size); + /* Public in case user app wants to use XMALLOC/XFREE */ + WOLFSSL_API void* wolfSSL_Malloc(size_t size); + WOLFSSL_API void wolfSSL_Free(void *ptr); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size); + #endif /* WOLFSSL_DEBUG_MEMORY */ +#endif /* WOLFSSL_STATIC_MEMORY */ /* Public set function */ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function, @@ -156,7 +162,10 @@ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function, byte haFlag; /* flag used for checking handshake count */ } WOLFSSL_HEAP_HINT; + WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, + unsigned char* buf, unsigned int sz, int flag, int max); + WOLFSSL_LOCAL int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap); WOLFSSL_LOCAL int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag, WOLFSSL_HEAP* heap); WOLFSSL_LOCAL int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, diff --git a/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h b/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h new file mode 100644 index 0000000000..aed338f406 --- /dev/null +++ b/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h @@ -0,0 +1,165 @@ +/* cavium-nitrox.h + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _CAVIUM_NITROX_H_ +#define _CAVIUM_NITROX_H_ + +#ifdef HAVE_CAVIUM + +#include + +#ifndef HAVE_CAVIUM_V + #include "cavium_sysdep.h" +#endif +#include "cavium_common.h" +#ifndef HAVE_CAVIUM_V + #include "cavium_ioctl.h" +#else + #include "cavium_sym_crypto.h" + #include "cavium_asym_crypto.h" +#endif +#include + +#define CAVIUM_SSL_GRP 0 +#define CAVIUM_DPORT 256 + +/* Compatibility with older Cavium SDK's */ +#ifndef HAVE_CAVIUM_V + typedef int CspHandle; + typedef word32 CavReqId; + + #define AES_128 AES_128_BIT + #define AES_192 AES_192_BIT + #define AES_256 AES_256_BIT +#else + #define CAVIUM_DEV_ID 0 + #define CAVIUM_BLOCKING BLOCKING + #define CAVIUM_NON_BLOCKING NON_BLOCKING + #define CAVIUM_DIRECT DMA_DIRECT_DIRECT + typedef Uint64 CavReqId; +#endif + +#ifdef WOLFSSL_ASYNC_CRYPT + #define CAVIUM_REQ_MODE CAVIUM_NON_BLOCKING +#else + #define CAVIUM_REQ_MODE CAVIUM_BLOCKING +#endif + + +#ifdef WOLFSSL_ASYNC_CRYPT + #define CAVIUM_MAX_PENDING 90 + #define CAVIUM_MAX_POLL MAX_TO_POLL +#endif + + +typedef struct CaviumNitroxDev { + CspHandle devId; /* nitrox device id */ + ContextType type; /* Typically CONTEXT_SSL, but also ECC types */ + Uint64 contextHandle; /* nitrox context memory handle */ + CavReqId reqId; /* Current requestId */ +} CaviumNitroxDev; + +struct WOLF_EVENT; + + +/* Wrapper API's */ +WOLFSSL_LOCAL int NitroxTranslateResponseCode(int ret); +WOLFSSL_LOCAL CspHandle NitroxGetDeviceHandle(void); +WOLFSSL_LOCAL CspHandle NitroxOpenDevice(int dma_mode, int dev_id); +WOLFSSL_LOCAL int NitroxAllocContext(CaviumNitroxDev* nitrox, CspHandle devId, + ContextType type); +WOLFSSL_LOCAL void NitroxFreeContext(CaviumNitroxDev* nitrox); +WOLFSSL_LOCAL void NitroxCloseDevice(CspHandle devId); + +#if defined(WOLFSSL_ASYNC_CRYPT) +WOLFSSL_LOCAL int NitroxCheckRequest(CspHandle devId, CavReqId reqId); +WOLFSSL_LOCAL int NitroxCheckRequests(CspHandle devId, + CspMultiRequestStatusBuffer* req_stat_buf); +#endif /* WOLFSSL_ASYNC_CRYPT */ + + +/* Crypto wrappers */ +#ifndef NO_RSA + struct RsaKey; + WOLFSSL_LOCAL int NitroxRsaExptMod( + const byte* in, word32 inLen, + byte* exponent, word32 expLen, + byte* modulus, word32 modLen, + byte* out, word32* outLen, struct RsaKey* key); + WOLFSSL_LOCAL int NitroxRsaPublicEncrypt(const byte* in, word32 inLen, + byte* out, word32 outLen, struct RsaKey* key); + WOLFSSL_LOCAL int NitroxRsaPrivateDecrypt(const byte* in, word32 inLen, + byte* out, word32 outLen, struct RsaKey* key); + WOLFSSL_LOCAL int NitroxRsaSSL_Sign(const byte* in, word32 inLen, + byte* out, word32 outLen, struct RsaKey* key); + WOLFSSL_LOCAL int NitroxRsaSSL_Verify(const byte* in, word32 inLen, + byte* out, word32 outLen, struct RsaKey* key); +#endif /* !NO_RSA */ + +#ifndef NO_AES + struct Aes; + WOLFSSL_LOCAL int NitroxAesSetKey(struct Aes* aes, const byte* key, + word32 length, const byte* iv); + #ifdef HAVE_AES_CBC + WOLFSSL_LOCAL int NitroxAesCbcEncrypt(struct Aes* aes, byte* out, + const byte* in, word32 length); + #ifdef HAVE_AES_DECRYPT + WOLFSSL_LOCAL int NitroxAesCbcDecrypt(struct Aes* aes, byte* out, + const byte* in, word32 length); + #endif /* HAVE_AES_DECRYPT */ + #endif /* HAVE_AES_CBC */ +#endif /* !NO_AES */ + +#ifndef NO_RC4 + struct Arc4; + WOLFSSL_LOCAL void NitroxArc4SetKey(struct Arc4* arc4, const byte* key, + word32 length); + WOLFSSL_LOCAL void NitroxArc4Process(struct Arc4* arc4, byte* out, + const byte* in, word32 length); +#endif /* !NO_RC4 */ + +#ifndef NO_DES3 + struct Des3; + WOLFSSL_LOCAL int NitroxDes3SetKey(struct Des3* des3, const byte* key, + const byte* iv); + WOLFSSL_LOCAL int NitroxDes3CbcEncrypt(struct Des3* des3, byte* out, + const byte* in, word32 length); + WOLFSSL_LOCAL int NitroxDes3CbcDecrypt(struct Des3* des3, byte* out, + const byte* in, word32 length); +#endif /* !NO_DES3 */ + +#ifndef NO_HMAC + struct Hmac; + WOLFSSL_LOCAL int NitroxHmacFinal(struct Hmac* hmac, byte* hash); + WOLFSSL_LOCAL int NitroxHmacUpdate(struct Hmac* hmac, const byte* msg, + word32 length); + WOLFSSL_LOCAL int NitroxHmacSetKey(struct Hmac* hmac, int type, + const byte* key, word32 length); +#endif /* NO_HMAC */ + +#if !defined(HAVE_HASHDRBG) && !defined(NO_RC4) + WOLFSSL_API void NitroxRngGenerateBlock(WC_RNG* rng, byte* output, word32 sz); +#endif + + +#endif /* HAVE_CAVIUM */ + +#endif /* _CAVIUM_NITROX_H_ */ diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index e8d63257a7..1669a6e267 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -39,18 +39,35 @@ #define RNG_MAX_BLOCK_LEN (0x10000) #ifndef HAVE_FIPS /* avoid redefining structs and macros */ + #if defined(WOLFSSL_FORCE_RC4_DRBG) && defined(NO_RC4) #error Cannot have WOLFSSL_FORCE_RC4_DRBG and NO_RC4 defined. #endif /* WOLFSSL_FORCE_RC4_DRBG && NO_RC4 */ -#if defined(HAVE_HASHDRBG) || defined(NO_RC4) + + +/* RNG supports the following sources (in order): + * 1. CUSTOM_RAND_GENERATE_BLOCK: Defines name of function as RNG source and + * bypasses the P-RNG. + * 2. HAVE_HASHDRBG && !NO_SHA256 (SHA256 enabled): Uses SHA256 based P-RNG + * seeded via wc_GenerateSeed. This is the default source. + * 3. !NO_RC4 (RC4 enabled): Uses RC4 + */ + +#if defined(CUSTOM_RAND_GENERATE_BLOCK) + /* To use define the following: + * #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc + * extern int myRngFunc(byte* output, word32 sz); + */ +#elif (defined(HAVE_HASHDRBG) || defined(NO_RC4)) #ifdef NO_SHA256 #error "Hash DRBG requires SHA-256." #endif /* NO_SHA256 */ #include -#else /* HAVE_HASHDRBG || NO_RC4 */ +#else #include -#endif /* HAVE_HASHDRBG || NO_RC4 */ +#endif + #ifdef HAVE_WNR #include @@ -101,7 +118,9 @@ struct WC_RNG { #else /* (HAVE_HASHDRBG || NO_RC4) && !CUSTOM_RAND_GENERATE_BLOCK */ -#define WOLFSSL_RNG_CAVIUM_MAGIC 0xBEEF0004 +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif /* secure Random Number Generator */ @@ -111,9 +130,8 @@ struct WC_RNG { #ifndef NO_RC4 Arc4 cipher; #endif -#ifdef HAVE_CAVIUM - int devId; /* nitrox device id */ - word32 magic; /* using cavium magic */ +#ifdef WOLFSSL_ASYNC_CRYPT + AsyncCryptDev asyncDev; #endif }; @@ -131,13 +149,6 @@ struct WC_RNG { WOLFSSL_LOCAL int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz); -#if defined(HAVE_HASHDRBG) || defined(NO_RC4) - -#ifdef HAVE_CAVIUM - WOLFSSL_API int wc_InitRngCavium(WC_RNG*, int); -#endif - -#endif /* HAVE_HASH_DRBG || NO_RC4 */ #ifdef HAVE_WNR /* Whitewood netRandom client library */ diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 6e51e9fbe9..79b7870141 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -52,42 +52,55 @@ /* avoid redefinition of structs */ #if !defined(HAVE_FIPS) -#define WOLFSSL_RSA_CAVIUM_MAGIC 0xBEEF0006 + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif enum { RSA_PUBLIC = 0, RSA_PRIVATE = 1, -}; + RSA_TYPE_UNKNOWN = -1, + RSA_PUBLIC_ENCRYPT = 0, + RSA_PUBLIC_DECRYPT = 1, + RSA_PRIVATE_ENCRYPT = 2, + RSA_PRIVATE_DECRYPT = 3, + + RSA_BLOCK_TYPE_1 = 1, + RSA_BLOCK_TYPE_2 = 2, + + RSA_MIN_SIZE = 512, + RSA_MAX_SIZE = 4096, + + RSA_MIN_PAD_SZ = 11 /* separator + 0 + pad value + 8 pads */ +}; /* RSA */ typedef struct RsaKey { mp_int n, e, d, p, q, dP, dQ, u; int type; /* public or private */ void* heap; /* for user memory overrides */ + int state; + byte* tmp; /* temp buffer for async RSA */ + word32 tmpLen; + byte tmpIsAlloc; #ifdef WC_RSA_BLINDING WC_RNG* rng; /* for PrivateDecrypt blinding */ #endif -#ifdef HAVE_CAVIUM - int devId; /* nitrox device id */ - word32 magic; /* using cavium magic */ - word64 contextHandle; /* nitrox context memory handle */ - byte* c_n; /* cavium byte buffers for key parts */ - byte* c_e; - byte* c_d; - byte* c_p; - byte* c_q; - byte* c_dP; - byte* c_dQ; - byte* c_u; /* sizes in bytes */ - word16 c_nSz, c_eSz, c_dSz, c_pSz, c_qSz, c_dP_Sz, c_dQ_Sz, c_uSz; -#endif +#ifdef WOLFSSL_ASYNC_CRYPT + AsyncCryptDev asyncDev; +#endif /* WOLFSSL_ASYNC_CRYPT */ } RsaKey; #endif /*HAVE_FIPS */ -WOLFSSL_API int wc_InitRsaKey(RsaKey* key, void*); +WOLFSSL_API int wc_InitRsaKey(RsaKey* key, void* heap); +WOLFSSL_API int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId); WOLFSSL_API int wc_FreeRsaKey(RsaKey* key); +WOLFSSL_LOCAL int wc_RsaFunction(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng); + WOLFSSL_API int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, WC_RNG* rng); WOLFSSL_API int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, @@ -120,6 +133,7 @@ WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng); */ /* Mask Generation Function Identifiers */ +#define WC_MGF1NONE 0 #define WC_MGF1SHA1 26 #define WC_MGF1SHA256 1 #define WC_MGF1SHA384 2 @@ -147,11 +161,13 @@ WOLFSSL_API int wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*, WOLFSSL_API int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng); #endif -#ifdef HAVE_CAVIUM - WOLFSSL_API int wc_RsaInitCavium(RsaKey*, int); - WOLFSSL_API void wc_RsaFreeCavium(RsaKey*); +#ifdef WOLFSSL_ASYNC_CRYPT + WOLFSSL_API int wc_RsaAsyncHandle(RsaKey* key, WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event); + WOLFSSL_API int wc_RsaAsyncWait(int ret, RsaKey* key); #endif + #endif /* HAVE_USER_RSA */ + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index ad95b61372..63e57b4a09 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -134,7 +134,9 @@ /* #define WOLFSSL_STATIC_RSA */ /* Uncomment next line if building for ARDUINO */ +/* Uncomment both lines if building for ARDUINO on INTEL_GALILEO */ /* #define WOLFSSL_ARDUINO */ +/* #define INTEL_GALILEO */ /* Uncomment next line to enable asynchronous crypto WC_PENDING_E */ /* #define WOLFSSL_ASYNC_CRYPT */ @@ -1235,9 +1237,10 @@ static char *fgets(char *buff, int sz, FILE *fp) /* Make sure wolf events are enabled */ #undef HAVE_WOLF_EVENT #define HAVE_WOLF_EVENT -#else - #ifdef WOLFSSL_ASYNC_CRYPT_TEST - #error Must have WOLFSSL_ASYNC_CRYPT enabled with WOLFSSL_ASYNC_CRYPT_TEST + + #if !defined(HAVE_CAVIUM) && !defined(HAVE_INTEL_QA) && \ + !defined(WOLFSSL_ASYNC_CRYPT_TEST) + #error No async hardware defined with WOLFSSL_ASYNC_CRYPT! #endif #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -1250,6 +1253,9 @@ static char *fgets(char *buff, int sz, FILE *fp) /* restriction with static memory */ #ifdef WOLFSSL_STATIC_MEMORY + #if defined(HAVE_IO_POOL) || defined(XMALLOC_USER) || defined(NO_WOLFSSL_MEMORY) + #error static memory cannot be used with HAVE_IO_POOL, XMALLOC_USER or NO_WOLFSSL_MEMORY + #endif #ifndef USE_FAST_MATH #error static memory requires fast math please define USE_FAST_MATH #endif @@ -1257,6 +1263,8 @@ static char *fgets(char *buff, int sz, FILE *fp) #error static memory does not support small stack please undefine #endif #endif /* WOLFSSL_STATIC_MEMORY */ + + /* Place any other flags or defines here */ #if defined(WOLFSSL_MYSQL_COMPATIBLE) && defined(_WIN32) \ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 93b515ee37..503db7f2a9 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -59,8 +59,8 @@ typedef struct Sha256 { word32 buffLen; /* in bytes */ word32 loLen; /* length in bytes */ word32 hiLen; /* length in bytes */ - word32 digest[SHA256_DIGEST_SIZE / sizeof(word32)]; - word32 buffer[SHA256_BLOCK_SIZE / sizeof(word32)]; + ALIGN16 word32 digest[SHA256_DIGEST_SIZE / sizeof(word32)]; + ALIGN16 word32 buffer[SHA256_BLOCK_SIZE / sizeof(word32)]; #ifdef WOLFSSL_PIC32MZ_HASH pic32mz_desc desc ; /* Crypt Engine descriptor */ #endif diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index e44e7dbf30..4d1661f99f 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -289,6 +289,9 @@ typedef struct { int size; #endif fp_digit dp[FP_SIZE]; +#ifdef WOLFSSL_ASYNC_CRYPT + byte *dpraw; /* Used for hardware crypto */ +#endif } fp_int; /* externally define this symbol to ignore the default settings, useful for changing the build from the make process */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index ff5d41e954..7612546c06 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -91,6 +91,7 @@ defined(__mips64) || defined(__x86_64__) || defined(_M_X64)) || \ defined(__aarch64__) typedef word64 wolfssl_word; + #define WC_64BIT_CPU #else typedef word32 wolfssl_word; #ifdef WORD64_AVAILABLE @@ -171,24 +172,22 @@ /* default to libc stuff */ /* XREALLOC is used once in normal math lib, not in fast math lib */ /* XFREE on some embeded systems doesn't like free(0) so test */ - #if defined(XMALLOC_USER) + #if defined(HAVE_IO_POOL) + WOLFSSL_API void* XMALLOC(size_t n, void* heap, int type); + WOLFSSL_API void* XREALLOC(void *p, size_t n, void* heap, int type); + WOLFSSL_API void XFREE(void *p, void* heap, int type); + #elif defined(XMALLOC_USER) /* prototypes for user heap override functions */ #include /* for size_t */ extern void *XMALLOC(size_t n, void* heap, int type); extern void *XREALLOC(void *p, size_t n, void* heap, int type); extern void XFREE(void *p, void* heap, int type); - #ifdef WOLFSSL_STATIC_MEMORY /* don't use wolfSSL static memory either*/ - #undef WOLFSSL_STATIC_MEMORY - #endif #elif defined(NO_WOLFSSL_MEMORY) /* just use plain C stdlib stuff if desired */ #include #define XMALLOC(s, h, t) ((void)h, (void)t, malloc((s))) #define XFREE(p, h, t) {void* xp = (p); if((xp)) free((xp));} #define XREALLOC(p, n, h, t) realloc((p), (n)) - #ifdef WOLFSSL_STATIC_MEMORY /* don't use wolfSSL static memory either*/ - #undef WOLFSSL_STATIC_MEMORY - #endif #elif !defined(MICRIUM_MALLOC) && !defined(EBSNET) \ && !defined(WOLFSSL_SAFERTOS) && !defined(FREESCALE_MQX) \ && !defined(FREESCALE_KSDK_MQX) && !defined(FREESCALE_FREE_RTOS) \ @@ -196,19 +195,27 @@ && !defined(WOLFSSL_uITRON4) && !defined(WOLFSSL_uTKERNEL2) /* default C runtime, can install different routines at runtime via cbs */ #include - #if defined(WOLFSSL_DEBUG_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) - #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s), __func__, __LINE__)) - #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), __func__, __LINE__);} - #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), __func__, __LINE__) - #elif defined(WOLFSSL_STATIC_MEMORY) - #define XMALLOC(s, h, t) wolfSSL_Malloc((s), (h), (t)) - #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), (h), (t));} - #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), (h), (t)) - #else - #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s))) - #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp));} - #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n)) - #endif + #ifdef WOLFSSL_STATIC_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY + #define XMALLOC(s, h, t) wolfSSL_Malloc((s), (h), (t), __func__, __LINE__) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), (h), (t), __func__, __LINE__);} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), (h), (t), __func__, __LINE__) + #else + #define XMALLOC(s, h, t) wolfSSL_Malloc((s), (h), (t)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), (h), (t));} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), (h), (t)) + #endif /* WOLFSSL_DEBUG_MEMORY */ + #else + #ifdef WOLFSSL_DEBUG_MEMORY + #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s), __func__, __LINE__)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), __func__, __LINE__);} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), __func__, __LINE__) + #else + #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s))) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp));} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n)) + #endif /* WOLFSSL_DEBUG_MEMORY */ + #endif /* WOLFSSL_STATIC_MEMORY */ #endif @@ -312,8 +319,8 @@ DYNAMIC_TYPE_ECC = 37, DYNAMIC_TYPE_TMP_BUFFER = 38, DYNAMIC_TYPE_DTLS_MSG = 39, - DYNAMIC_TYPE_CAVIUM_TMP = 40, - DYNAMIC_TYPE_CAVIUM_RSA = 41, + DYNAMIC_TYPE_ASYNC_TMP = 40, + DYNAMIC_TYPE_ASYNC_RSA = 41, DYNAMIC_TYPE_X509 = 42, DYNAMIC_TYPE_TLSX = 43, DYNAMIC_TYPE_OCSP = 44, @@ -376,6 +383,29 @@ return 1 if a match otherwise 0 */ #define CheckCtcSettings() (CTC_SETTINGS == CheckRunTimeSettings()) + /* invalid device id */ + #define INVALID_DEVID -2 + + + /* AESNI requires alignment and ARMASM gains some performance from it */ + #if defined(WOLFSSL_AESNI) || defined(WOLFSSL_ARMASM) + #if !defined (ALIGN16) + #if defined (__GNUC__) + #define ALIGN16 __attribute__ ( (aligned (16))) + #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) + #define ALIGN16 __declspec (align (16)) + #else + #define ALIGN16 + #endif + #endif + #else + #ifndef ALIGN16 + #define ALIGN16 + #endif + #endif /* WOLFSSL_AESNI or WOLFSSL_ARMASM */ + #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/wolfcrypt/wolfevent.h b/wolfssl/wolfcrypt/wolfevent.h new file mode 100644 index 0000000000..5dbf164505 --- /dev/null +++ b/wolfssl/wolfcrypt/wolfevent.h @@ -0,0 +1,103 @@ +/* wolfevent.h + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef _WOLF_EVENT_H_ +#define _WOLF_EVENT_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef SINGLE_THREADED + #include +#endif + +typedef struct WOLFSSL WOLFSSL; +typedef struct WOLF_EVENT WOLF_EVENT; +typedef struct WOLFSSL_CTX WOLFSSL_CTX; + +typedef unsigned short WOLF_EVENT_FLAG; + +typedef enum WOLF_EVENT_TYPE { + WOLF_EVENT_TYPE_NONE, + #ifdef WOLFSSL_ASYNC_CRYPT + WOLF_EVENT_TYPE_ASYNC_ANY, + WOLF_EVENT_TYPE_ASYNC_WOLFSSL, + WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, + WOLF_EVENT_TYPE_ASYNC_FIRST = WOLF_EVENT_TYPE_ASYNC_WOLFSSL, + WOLF_EVENT_TYPE_ASYNC_LAST = WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT, + #endif +} WOLF_EVENT_TYPE; + +struct WOLF_EVENT { + /* double linked list */ + WOLF_EVENT* next; + WOLF_EVENT* prev; + + void* context; +#ifdef HAVE_CAVIUM + word64 reqId; +#endif + int ret; /* Async return code */ + WOLF_EVENT_TYPE type; + WOLF_EVENT_FLAG pending:1; + WOLF_EVENT_FLAG done:1; + /* Future event flags can go here */ +}; + +enum WOLF_POLL_FLAGS { + WOLF_POLL_FLAG_CHECK_HW = 0x01, +}; + +typedef struct { + WOLF_EVENT* head; /* head of queue */ + WOLF_EVENT* tail; /* tail of queue */ +#ifndef SINGLE_THREADED + wolfSSL_Mutex lock; /* queue lock */ +#endif + int count; +} WOLF_EVENT_QUEUE; + + +#ifdef HAVE_WOLF_EVENT + +/* Event */ +WOLFSSL_API int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context); +WOLFSSL_API int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags); + +/* Event Queue */ +WOLFSSL_API int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue); +WOLFSSL_API int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event); +WOLFSSL_API int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event); +WOLFSSL_API int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event); +WOLFSSL_API int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter, + WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount); +WOLFSSL_API int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue); +WOLFSSL_API void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue); + +#endif /* HAVE_WOLF_EVENT */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* _WOLF_EVENT_H_ */