From 17a34c58997465849c3adb9f170d9cc64acd6f58 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 15 Aug 2016 13:59:41 -0600 Subject: [PATCH 01/69] Added asynchronous wolfCrypt RSA, TLS client and Cavium Nitrox V support. Asynchronous wolfSSL client support for "DoServerKeyExchange", "SendClientKeyExchange", "SendCertificateVerify" and "DoCertificateVerify". Fixes for async DTLS. Refactor of the wolf event and async handling for use in wolfCrypt. Refactor of the async device support so its hardware agnostic. Added Cavium Nitrox V support (Nitrox tested using SDK v0.2 CNN55XX-SDK with new configure "--with-cavium-v=/dir" option). Moved Nitrox specific functions to new port file "port/cavium/cavium_nitrox.c". RSA refactor to handle async with states. RSA optimization for using dpraw for private key decode. Use double linked list in wolf event for faster/cleaner code. Use typedef for wolf event flag. Cleanup of the async error codes. wolfCrypt test and benchmark support for async RSA. Asynchronous mode enabled using "./configure --enable-asynccrypt". If no async hardware is defined then the internal async simulator (WOLFSSL_ASYNC_CRYPT_TEST) is used. Note: Using async mode requires async.c/h files from wolfSSL. If interested in using asynchronous mode please send email to info@wolfssl.com. --- .gitignore | 2 + IDE/WIN/wolfssl-fips.vcxproj | 1 + autogen.sh | 4 +- configure.ac | 79 +- cyassl/ctaocrypt/aes.h | 5 - cyassl/ctaocrypt/arc4.h | 5 +- cyassl/ctaocrypt/des3.h | 6 +- cyassl/ctaocrypt/hmac.h | 6 +- cyassl/ctaocrypt/rsa.h | 6 +- examples/client/client.c | 43 +- examples/echoclient/echoclient.c | 33 +- examples/echoserver/echoserver.c | 28 +- examples/server/server.c | 27 +- mcapi/crypto.c | 1 + mcapi/crypto.h | 2 +- src/include.am | 12 +- src/internal.c | 5403 +++++++++-------- src/keys.c | 52 +- src/ssl.c | 135 +- tests/api.c | 93 +- tests/unit.c | 9 - testsuite/testsuite.c | 10 - wolfcrypt/benchmark/benchmark.c | 364 +- wolfcrypt/src/aes.c | 168 +- wolfcrypt/src/arc4.c | 86 +- wolfcrypt/src/asn.c | 168 +- wolfcrypt/src/des3.c | 161 +- wolfcrypt/src/ecc.c | 201 +- wolfcrypt/src/error.c | 20 +- wolfcrypt/src/hash.c | 38 +- wolfcrypt/src/hmac.c | 242 +- wolfcrypt/src/include.am | 4 + wolfcrypt/src/port/cavium/README.md | 32 + wolfcrypt/src/port/cavium/cavium_nitrox.c | 778 +++ wolfcrypt/src/random.c | 78 +- wolfcrypt/src/rsa.c | 1439 ++--- wolfcrypt/src/wolfevent.c | 274 + wolfcrypt/test/test.c | 413 +- wolfcrypt/user-crypto/include/user_rsa.h | 1 + wolfcrypt/user-crypto/src/rsa.c | 8 +- wolfssl-ntru.vcproj | 4 + wolfssl.vcproj | 4 + wolfssl.vcxproj | 1 + wolfssl/error-ssl.h | 1 - wolfssl/internal.h | 42 +- wolfssl/ssl.h | 48 +- wolfssl/test.h | 48 +- wolfssl/wolfcrypt/aes.h | 27 +- wolfssl/wolfcrypt/arc4.h | 16 +- wolfssl/wolfcrypt/des3.h | 17 +- wolfssl/wolfcrypt/ecc.h | 16 +- wolfssl/wolfcrypt/error-crypt.h | 9 +- wolfssl/wolfcrypt/hash.h | 2 +- wolfssl/wolfcrypt/hmac.h | 44 +- wolfssl/wolfcrypt/include.am | 7 +- wolfssl/wolfcrypt/integer.h | 3 + wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h | 165 + wolfssl/wolfcrypt/random.h | 16 +- wolfssl/wolfcrypt/rsa.h | 55 +- wolfssl/wolfcrypt/settings.h | 7 +- wolfssl/wolfcrypt/tfm.h | 3 + wolfssl/wolfcrypt/types.h | 7 +- wolfssl/wolfcrypt/wolfevent.h | 103 + 63 files changed, 6611 insertions(+), 4471 deletions(-) create mode 100644 wolfcrypt/src/port/cavium/README.md create mode 100644 wolfcrypt/src/port/cavium/cavium_nitrox.c create mode 100644 wolfcrypt/src/wolfevent.c create mode 100644 wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h create mode 100644 wolfssl/wolfcrypt/wolfevent.h diff --git a/.gitignore b/.gitignore index 47c38e3f1f..ab22d786e5 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 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..79d44702e4 100644 --- a/configure.ac +++ b/configure.ac @@ -2439,28 +2439,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 +2709,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 +2720,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], @@ -3069,6 +3113,7 @@ 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 "" 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..f814c0d4e7 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)) { @@ -1175,9 +1181,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) @@ -1343,7 +1353,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 @@ -1622,6 +1632,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 +1664,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 +1683,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/echoclient/echoclient.c b/examples/echoclient/echoclient.c index 2c5f10b2b7..6cb836e6a9 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,9 +167,17 @@ 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); @@ -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..d917c946bf 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) @@ -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 @@ -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/server/server.c b/examples/server/server.c index b5dc3de2d2..74feccc0b7 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 @@ -806,6 +810,14 @@ 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) { @@ -947,7 +959,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 @@ -1088,6 +1100,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 +1128,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 +1150,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/src/include.am b/src/include.am index 5044bd9a47..8dc391ce85 100644 --- a/src/include.am +++ b/src/include.am @@ -65,6 +65,14 @@ src_libwolfssl_la_SOURCES += \ wolfcrypt/src/sha256.c \ wolfcrypt/src/hash.c +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 +262,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..6f11389e31 100755 --- a/src/internal.c +++ b/src/internal.c @@ -588,15 +588,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 +713,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 +1300,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 +1311,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,9 +1371,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) } #endif -#ifdef HAVE_CAVIUM - ctx->devId = NO_CAVIUM_DEVICE; -#endif + ctx->devId = INVALID_DEVID; #ifndef NO_CERTS ctx->cm = wolfSSL_CertManagerNew_ex(heap); @@ -1441,18 +1386,12 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #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 +1403,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 +1465,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) } #endif } -#endif +#endif /* WOLFSSL_STATIC_MEMORY */ } @@ -1616,30 +1553,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 +2618,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 +2630,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 +2663,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 +2674,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 +2702,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 +2711,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 +2749,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 +2767,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 +2848,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 +2860,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 +2888,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 +2928,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 +2997,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 +3018,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 +3153,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 +3302,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; @@ -3380,7 +3361,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 +3504,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 +3573,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 +3625,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 +3716,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 +3799,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 +3816,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 @@ -6573,14 +6561,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 +6633,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); @@ -7542,6 +7532,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; } @@ -7807,10 +7807,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); @@ -10770,8 +10773,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 */ @@ -10899,8 +10907,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 @@ -11379,9 +11392,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"; @@ -13283,926 +13293,894 @@ 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; + int typeH = 0; + 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; + (void)typeH; + + 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; + typeH = ssl->async.hashAlgo; + 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 + } + typeH = wc_HashGetOID(hashType); + + /* 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; + ssl->async.hashAlgo = typeH; + ssl->async.sigAlgo = sigAlgo; + #if !defined(NO_DH) || defined(HAVE_ECC) + ssl->async.data = verifySig; #endif - #ifndef NO_SHA256 - XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #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 +14552,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 +14808,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 +15098,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 +15123,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 +15196,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 +15218,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 +15247,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 +15255,377 @@ 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 (ssl->options.dtls) { + 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: + { + /* restore verify pointer */ + verify = &output[idx]; + + #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 +15634,14 @@ 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) { 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 +15650,66 @@ 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 +15717,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 (ssl->options.dtls) { + 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; @@ -15935,15 +16155,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 +16185,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 +16213,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 +16307,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 +16568,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 +16603,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 +16805,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 +16834,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 +16929,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 +17192,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 +17227,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 +17269,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 @@ -17053,6 +17390,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 +17406,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 +17417,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); @@ -17830,179 +18180,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) @@ -18296,7 +18796,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 +18814,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 +18836,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 +18883,7 @@ int DoSessionTicket(WOLFSSL* ssl, return NO_PEER_CERT; } } - #endif + #endif /* !NO_CERTS */ #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) { @@ -18489,13 +18998,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 +19042,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 +19131,6 @@ int DoSessionTicket(WOLFSSL* ssl, idx += cipherLen; ssl->arrays->preMasterSz = plainLen; - break; } #endif /* HAVE_NTRU */ @@ -18656,7 +19150,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 +19163,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 +19189,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, @@ -18708,14 +19213,10 @@ int DoSessionTicket(WOLFSSL* ssl, ssl->peerEccKeyPresent = 1; 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 +19236,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 +19277,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 +19325,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 +19350,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 +19485,7 @@ int DoSessionTicket(WOLFSSL* ssl, /* Advance state and proceed */ ssl->options.keyShareState = KEYSHARE_VERIFY; - } /* KEYSHARE_BUILD */ + } /* KEYSHARE_DO */ case KEYSHARE_VERIFY: { @@ -18956,12 +19531,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 +19635,7 @@ int DoSessionTicket(WOLFSSL* ssl, ERROR_OUT(BUFFER_ERROR, exit_dcke); } } - #endif + #endif /* HAVE_QSH */ ret = MakeMasterSecret(ssl); /* Check for error */ @@ -19064,26 +19665,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/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/ssl.c b/src/ssl.c index 11c313c455..2fb0d17ed6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1090,10 +1090,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 +1104,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 +1115,7 @@ int wolfSSL_CTX_UseCavium(WOLFSSL_CTX* ctx, int devId) return SSL_SUCCESS; } - -#endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ #ifdef HAVE_SNI @@ -19016,118 +19015,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/tests/api.c b/tests/api.c index 689100e68d..a387a404de 100644 --- a/tests/api.c +++ b/tests/api.c @@ -537,6 +537,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()); @@ -602,9 +603,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 +680,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()); @@ -706,12 +721,25 @@ static void test_client_nofail(void* args) 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 +787,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()); @@ -829,13 +858,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 +941,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()); @@ -932,12 +976,27 @@ static void run_wolfssl_client(void* args) 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))) { 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..e535d0b728 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -77,15 +77,16 @@ #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 + static int devId = INVALID_DEVID; +#endif #ifdef HAVE_WNR const char* wnrConfigFile = "wnr-example.conf"; @@ -161,6 +162,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 +193,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 @@ -274,29 +255,28 @@ int benchmark_test(void *args) wolfCrypt_Init(); - #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 +364,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 +408,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 +438,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 +518,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 +551,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 +585,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 +797,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 +825,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 +874,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 +898,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 +1387,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 +1406,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, 0)) < 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; } @@ -1447,25 +1440,232 @@ void bench_rsa(void) wc_RsaSetRNG(&rsaKey, &rng); #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], 0, 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 diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index c12cd328b8..e13ae49a2d 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" @@ -1870,9 +1855,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 +2476,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 +2540,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 @@ -3909,8 +3896,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 +3967,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 +4306,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..59d89b8825 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,62 @@ 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 ( (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 +1353,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 +1367,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 +3663,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); @@ -7359,7 +7359,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..7fc45faa39 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2223,8 +2223,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 +2243,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 +2321,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 +2412,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 +2606,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 +2634,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 +2649,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 +2689,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 +2849,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 +3124,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 @@ -5680,7 +5777,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 +5786,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 +5968,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 +6120,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 */ } @@ -6526,4 +6623,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..28d04e76b0 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 */ diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 23b53b3057..2a26d26634 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, hmac->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, hmac->heap, DYNAMIC_TYPE_TMP_BUFFER); if (prk == NULL) { - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, hmac->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..983b63b4f3 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -46,4 +46,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/pic32/pic32mz-hash.c \ wolfcrypt/src/port/nrf51.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/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..efcd3a5705 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 -2007; #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..cff7477a42 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_CHECK_KEYTYPE: RSA check key type default: off */ +/* +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,101 @@ 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, }; +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; + +#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 + { + 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); + } + + 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; +#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 +251,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 +315,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 +325,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 +368,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 +395,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 +407,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 +428,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 +445,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 +454,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 +465,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 +483,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 +493,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 +523,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 +540,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 +564,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 +577,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 +599,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 +638,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 +652,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 +669,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 +681,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 +729,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 +773,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, @@ -763,23 +783,24 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out, switch (padType) { case WC_RSA_PKCSV15_PAD: - WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding"); + //WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding"); 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); + //WOLFSSL_MSG("wolfSSL Using RSA OAEP padding"); + 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 +809,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 +876,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 +903,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 +1026,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 +1118,380 @@ 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) + /* Optional key type check (disabled by default) */ + /* Note: internal tests allow private to be used as public */ +#ifdef RSA_CHECK_KEYTYPE + if ((rsa_type == RSA_PUBLIC_ENCRYPT && key->type != RSA_PUBLIC) || + (rsa_type == RSA_PRIVATE_ENCRYPT && key->type != RSA_PRIVATE)) { + WOLFSSL_MSG("Wrong RSA Encrypt key type"); + return RSA_WRONG_TYPE_E; + } +#endif + + 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; + } + + /* Optional key type check (disabled by default) */ + /* Note: internal tests allow private to be used as public */ +#ifdef RSA_CHECK_KEYTYPE + if ((rsa_type == RSA_PUBLIC_DECRYPT && key->type != RSA_PUBLIC) || + (rsa_type == RSA_PRIVATE_DECRYPT && key->type != RSA_PRIVATE)) { + WOLFSSL_MSG("Wrong RSA Decrypt key type"); + return RSA_WRONG_TYPE_E; + } +#endif + + 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); + 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; + if (key->tmp) { + /* if not inline */ + if (outPtr == NULL) { + ForceZero(key->tmp, key->tmpLen); + XFREE(key->tmp, key->heap, DYNAMIC_TYPE_RSA); + } + key->tmp = NULL; + key->tmpLen = 0; + } + + 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 +1501,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 +1618,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return 0; } - - #endif /* WOLFSSL_KEY_GEN */ @@ -1513,183 +1635,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/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..a9c2088ff2 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -107,6 +107,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 +136,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 +163,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 +252,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 @@ -295,10 +300,18 @@ int wolfcrypt_test(void* args) ((func_args*)args)->return_code = -1; /* error state */ +#if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) + wolfSSL_Debugging_ON(); +#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 +329,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 +684,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 +702,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 +1323,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 +1348,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 +1409,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 +1426,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 +1490,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 +1507,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 +1571,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 +1593,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 +1811,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 +1831,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 +2591,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 +2653,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 +2678,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 +2715,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 +2830,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 +3747,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; @@ -4263,6 +4261,7 @@ int certext_test(void) } #endif /* WOLFSSL_CERT_EXT && WOLFSSL_TEST_CERT */ + int rsa_test(void) { byte* tmp; @@ -4309,11 +4308,7 @@ 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); return -39; @@ -4328,11 +4323,20 @@ int rsa_test(void) TEST_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); return -43; } + #ifdef WC_RSA_BLINDING { int tmpret = ret; @@ -4344,26 +4348,54 @@ int rsa_test(void) 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); return -44; } + if (XMEMCMP(plain, in, inLen)) { TEST_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); 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); return -47; } + if (XMEMCMP(plain, in, ret)) { TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -48; @@ -4375,18 +4407,36 @@ 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); 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); return -144; } + if (XMEMCMP(plain, in, inLen)) { TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -145; @@ -4395,18 +4445,35 @@ int rsa_test(void) #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); 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); return -244; } + if (XMEMCMP(plain, in, inLen)) { TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -245; @@ -4414,53 +4481,104 @@ int rsa_test(void) /* 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); 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); 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); 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); return -249; } + if (XMEMCMP(plain, in, inLen)) { TEST_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); 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); return -252; } + ret = 0; #endif /* NO_SHA*/ #endif /* NO_SHA256 */ @@ -4471,18 +4589,35 @@ 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); 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); return -344; } + if (XMEMCMP(plain, in, inLen)) { TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -345; @@ -4492,18 +4627,35 @@ 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); 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); return -444; } + if (XMEMCMP(plain, in, inLen)) { TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -445; @@ -4540,7 +4692,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 @@ -4568,7 +4723,7 @@ 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); return -51; @@ -5367,7 +5522,7 @@ int rsa_test(void) 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); @@ -5652,9 +5807,7 @@ int rsa_test(void) #ifdef WOLFSSL_CERT_EXT wc_FreeRsaKey(&keypub); #endif -#ifdef HAVE_CAVIUM - wc_RsaFreeCavium(&key); -#endif + TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); 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..bdf8f5bab0 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 */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ac6f062f89..3a3e006356 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -155,7 +155,7 @@ #endif #ifdef WOLFSSL_ASYNC_CRYPT - #include + #include #endif #ifdef _MSC_VER @@ -1059,8 +1059,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,20 +1897,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 @@ -2002,9 +1986,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 @@ -2314,6 +2296,7 @@ enum AcceptState { enum KeyShareState { KEYSHARE_BEGIN = 0, KEYSHARE_BUILD, + KEYSHARE_DO, KEYSHARE_VERIFY, KEYSHARE_FINALIZE, KEYSHARE_END @@ -2326,6 +2309,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 @@ -2683,7 +2667,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 */ @@ -2782,9 +2767,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 +2829,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 +2981,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 +2990,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 +2999,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); @@ -3132,7 +3114,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/ssl.h b/wolfssl/ssl.h index 1b84c4c809..2af2dfffa0 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 @@ -1416,9 +1420,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 */ @@ -1909,41 +1913,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..360d3e9087 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 @@ -1218,29 +1219,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 +1952,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..8d91f43673 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 @@ -74,7 +70,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 +101,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 +182,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/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..a2d2eca920 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 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..3c8a0020a1 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -181,6 +181,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/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..64889f15ef 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -101,7 +101,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 +113,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 +132,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..4916920578 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -52,42 +52,54 @@ /* 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; + word32 tmpLen; #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 +132,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 +160,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..55de9030f6 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1235,9 +1235,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 */ 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..b6e91b8aaa 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -312,8 +312,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 +376,9 @@ return 1 if a match otherwise 0 */ #define CheckCtcSettings() (CTC_SETTINGS == CheckRunTimeSettings()) + /* invalid device id */ + #define INVALID_DEVID -2 + #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_ */ From 3e6be9bf2c1b9984be8c67a23ecc9a092f050aab Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 15 Aug 2016 14:07:16 -0600 Subject: [PATCH 02/69] Fix in "wc_InitRsaKey_ex" for normal math so mp_init isn't called to defer allocation. --- wolfcrypt/src/rsa.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index cff7477a42..f5f65541fe 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -193,6 +193,13 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) 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); @@ -201,6 +208,7 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) mp_init(&key->dP); mp_init(&key->dQ); mp_init(&key->u); + #endif /* USE_FAST_MATH */ } return ret; From 65b2b14a0f033475110bd3dc01a1d26b7d40130f Mon Sep 17 00:00:00 2001 From: John Blixt Date: Wed, 17 Aug 2016 10:32:03 -0600 Subject: [PATCH 03/69] added test functions for wolfCrypt_Init and OCSP stapling v1 and v2 --- tests/api.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 689100e68d..af0fb45c4c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -101,6 +101,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 *----------------------------------------------------------------------------*/ @@ -1828,6 +1844,78 @@ static void test_wolfSSL_X509_NAME_get_entry(void) } +/*----------------------------------------------------------------------------* + | OCSP Stapling + *----------------------------------------------------------------------------*/ + + +/* Testing wolfSSL_UseOCSPStapling function. + * PRE: HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST + * POST: 1 returned for success. + */ +#if defined(HAVE_OCSP) + +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) +static int test_wolfSSL_UseOCSPStapling(void) +{ + 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); + wolfSSL_Cleanup(); + + if(ret) { return SSL_SUCCESS;} + else { return SSL_FAILURE;} + +} /*END test_wolfSSL_UseOCSPStapling */ + +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 +static int test_wolfSSL_UseOCSPStaplingV2(void) +{ + 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); + wolfSSL_Cleanup(); + + if(ret) {return SSL_SUCCESS;} + else {return SSL_FAILURE;} +} /*END test_wolfSSL_UseOCSPStaplingV2*/ + +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ +#endif /* HAVE_OCSP*/ + + + + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -1852,16 +1940,30 @@ void ApiTest(void) test_wolfSSL_read_write(); test_wolfSSL_dtls_export(); + /* TLS extensions tests */ test_wolfSSL_UseSNI(); test_wolfSSL_UseMaxFragment(); test_wolfSSL_UseTruncatedHMAC(); test_wolfSSL_UseSupportedCurve(); test_wolfSSL_UseALPN(); - /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); + /* wolfcrypt initialization tests */ + AssertFalse(test_wolfCrypt_Init()); + + /*OCSP Stapling. */ +#if defined(HAVE_OCSP) +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) + AssertTrue(test_wolfSSL_UseOCSPStapling()); +#endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + AssertTrue(test_wolfSSL_UseOCSPStaplingV2()); +#endif +#endif /* HAVE_OCSP. */ + test_wolfSSL_Cleanup(); printf(" End API Tests\n"); + } From 584733b138e7b513fb088a8c90177dba5d9fe3dd Mon Sep 17 00:00:00 2001 From: John Blixt Date: Wed, 17 Aug 2016 11:27:14 -0600 Subject: [PATCH 04/69] Chris looked at functions added for correctness. --- tests/api.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/tests/api.c b/tests/api.c index af0fb45c4c..00656fef6d 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1853,9 +1853,8 @@ static void test_wolfSSL_X509_NAME_get_entry(void) * PRE: HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST * POST: 1 returned for success. */ -#if defined(HAVE_OCSP) - -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) +#if defined(HAVE_OCSP) + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) static int test_wolfSSL_UseOCSPStapling(void) { int ret; @@ -1876,16 +1875,19 @@ static int test_wolfSSL_UseOCSPStapling(void) wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); - wolfSSL_Cleanup(); - - if(ret) { return SSL_SUCCESS;} - else { return SSL_FAILURE;} + + if(ret != SSL_SUCCESS){ + wolfSSL_Cleanup(); + return SSL_FAILURE; + } + + return wolfSSL_Cleanup(); } /*END test_wolfSSL_UseOCSPStapling */ -#endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ + #endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 static int test_wolfSSL_UseOCSPStaplingV2(void) { int ret; @@ -1904,13 +1906,17 @@ static int test_wolfSSL_UseOCSPStaplingV2(void) wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); - wolfSSL_Cleanup(); - if(ret) {return SSL_SUCCESS;} - else {return SSL_FAILURE;} + if(ret != SSL_SUCCESS){ + wolfSSL_Cleanup(); + return SSL_FAILURE; + } + + return wolfSSL_Cleanup(); + } /*END test_wolfSSL_UseOCSPStaplingV2*/ -#endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ + #endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ #endif /* HAVE_OCSP*/ @@ -1923,7 +1929,7 @@ static int test_wolfSSL_UseOCSPStaplingV2(void) void ApiTest(void) { printf(" Begin API Tests\n"); - test_wolfSSL_Init(); + AssertTrue(test_wolfSSL_Init()); test_wolfSSL_Method_Allocators(); test_wolfSSL_CTX_new(wolfSSLv23_server_method()); @@ -1955,15 +1961,19 @@ void ApiTest(void) /*OCSP Stapling. */ #if defined(HAVE_OCSP) -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) + AssertTrue(test_wolfSSL_UseOCSPStapling()); -#endif -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + + #endif + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + AssertTrue(test_wolfSSL_UseOCSPStaplingV2()); -#endif + + #endif #endif /* HAVE_OCSP. */ - test_wolfSSL_Cleanup(); + AssertTrue(test_wolfSSL_Cleanup()); printf(" End API Tests\n"); } From cddc771829fe4eccc00ca236001fbebba6427463 Mon Sep 17 00:00:00 2001 From: John Blixt Date: Wed, 17 Aug 2016 14:05:37 -0600 Subject: [PATCH 05/69] Added wolfSSL_SetMinVersion --- tests/api.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/api.c b/tests/api.c index 00656fef6d..310d4cf0f6 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 */ @@ -502,6 +503,40 @@ static void test_wolfSSL_SetTmpDH_buffer(void) #endif } + +/* Test function for wolfSSL_SetMinVersion + * POST: return 1 on success. + */ +static int test_wolfSSL_SetMinVersion(void) +{ + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + int version, ret; + + AssertTrue(wolfSSL_Init()); + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + ssl = wolfSSL_new(ctx); + + version = 3; + + printf(testingFmt, "wolfSSL_SetMinVersion()"); + + ret = wolfSSL_SetMinVersion(ssl, version); + + printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + AssertTrue(wolfSSL_Cleanup()); + + if(ret != SSL_SUCCESS) { return SSL_FAILURE; } + + return SSL_SUCCESS; + +} /* END test_wolfSSL_SetMinVersion */ + + + /*----------------------------------------------------------------------------* | IO *----------------------------------------------------------------------------*/ @@ -1945,6 +1980,7 @@ void ApiTest(void) test_wolfSSL_SetTmpDH_buffer(); test_wolfSSL_read_write(); test_wolfSSL_dtls_export(); + AssertTrue(test_wolfSSL_SetMinVersion()); /* TLS extensions tests */ From b068eec96d598a3f09157261ba0cb120ad24b993 Mon Sep 17 00:00:00 2001 From: John Blixt Date: Wed, 17 Aug 2016 14:41:37 -0600 Subject: [PATCH 06/69] added wolfSSL_CTX_SetMinVersion --- tests/api.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/api.c b/tests/api.c index 310d4cf0f6..ddfd8e17b3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1878,6 +1878,30 @@ static void test_wolfSSL_X509_NAME_get_entry(void) #endif /* !NO_CERTS */ } +static int test_wolfSSL_CTX_SetMinVersion(void) +{ + WOLFSSL_CTX* ctx; + int version, ret; + + AssertTrue(wolfSSL_Init()); + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + version = 3; + + printf(testingFmt, "wolfSSL_CTX_SetMinVersion()"); + + ret = wolfSSL_CTX_SetMinVersion(ctx, version); + + printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + + wolfSSL_CTX_free(ctx); + AssertTrue(wolfSSL_Cleanup()); + + if(ret != SSL_SUCCESS) {return SSL_FAILURE;} + + return SSL_SUCCESS; + +} /* END test_wolfSSL_CTX_SetMinVersion */ + /*----------------------------------------------------------------------------* | OCSP Stapling @@ -1991,6 +2015,7 @@ void ApiTest(void) test_wolfSSL_UseALPN(); /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); + AssertTrue(test_wolfSSL_CTX_SetMinVersion()); /* wolfcrypt initialization tests */ AssertFalse(test_wolfCrypt_Init()); From f61c045e65e3018b78c1735389b8f9d1d16953c1 Mon Sep 17 00:00:00 2001 From: John Blixt Date: Thu, 18 Aug 2016 10:03:33 -0600 Subject: [PATCH 07/69] Changes to the Assert Macros used and added wolfSSL_CTX_use_certificate_buffer() --- tests/api.c | 67 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/tests/api.c b/tests/api.c index ddfd8e17b3..299800f252 100644 --- a/tests/api.c +++ b/tests/api.c @@ -211,6 +211,25 @@ static void test_wolfSSL_CTX_use_certificate_file(void) #endif } +static int test_wolfSSL_CTX_use_certificate_buffer(void) +{ +#ifndef NO_CERTS + WOLFSSL_CTX* ctx; + int ret; + + printf(testingFmt, "wolfSSL_CTX_use_certificate_buffer()"); + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); + #ifdef USE_CERT_BUFFERS_2048 + ret = wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048, + sizeof_server_cert_der_2048, SSL_FILETYPE_ASN1); + #endif + printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + + return ret; +#else + return; +#endif +} /*END test_wolfSSL_CTX_use_certificate_buffer*/ static void test_wolfSSL_CTX_use_PrivateKey_file(void) { @@ -511,17 +530,15 @@ static int test_wolfSSL_SetMinVersion(void) { WOLFSSL_CTX* ctx; WOLFSSL* ssl; - int version, ret; + int ret; AssertTrue(wolfSSL_Init()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); ssl = wolfSSL_new(ctx); - - version = 3; printf(testingFmt, "wolfSSL_SetMinVersion()"); - ret = wolfSSL_SetMinVersion(ssl, version); + ret = wolfSSL_SetMinVersion(ssl, 3); printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); @@ -536,7 +553,6 @@ static int test_wolfSSL_SetMinVersion(void) } /* END test_wolfSSL_SetMinVersion */ - /*----------------------------------------------------------------------------* | IO *----------------------------------------------------------------------------*/ @@ -1878,25 +1894,27 @@ static void test_wolfSSL_X509_NAME_get_entry(void) #endif /* !NO_CERTS */ } +/* Testing function wolfSSL_CTX_SetMinVersion + * POST: 1 on success. + */ static int test_wolfSSL_CTX_SetMinVersion(void) { WOLFSSL_CTX* ctx; - int version, ret; + int ret; AssertTrue(wolfSSL_Init()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); - version = 3; printf(testingFmt, "wolfSSL_CTX_SetMinVersion()"); - ret = wolfSSL_CTX_SetMinVersion(ctx, version); + ret = wolfSSL_CTX_SetMinVersion(ctx, 3); printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); wolfSSL_CTX_free(ctx); AssertTrue(wolfSSL_Cleanup()); - if(ret != SSL_SUCCESS) {return SSL_FAILURE;} + if(ret != SSL_SUCCESS) { return SSL_FAILURE; } return SSL_SUCCESS; @@ -1912,32 +1930,32 @@ static int test_wolfSSL_CTX_SetMinVersion(void) * PRE: HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST * POST: 1 returned for success. */ -#if defined(HAVE_OCSP) +#if defined(HAVE_OCSP) #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) static int test_wolfSSL_UseOCSPStapling(void) { 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, + 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){ + if(ret != SSL_SUCCESS){ wolfSSL_Cleanup(); - return SSL_FAILURE; + return SSL_FAILURE; } return wolfSSL_Cleanup(); @@ -1958,7 +1976,7 @@ static int test_wolfSSL_UseOCSPStaplingV2(void) ssl = wolfSSL_new(ctx); printf(testingFmt, "wolfSSL_UseOCSPStaplingV2()"); - ret = wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP, + ret = wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP, WOLFSSL_CSR2_OCSP_USE_NONCE ); printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); @@ -1988,11 +2006,12 @@ static int test_wolfSSL_UseOCSPStaplingV2(void) void ApiTest(void) { printf(" Begin API Tests\n"); - AssertTrue(test_wolfSSL_Init()); + AssertIntEQ(test_wolfSSL_Init(), SSL_SUCCESS); 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(); @@ -2004,7 +2023,8 @@ void ApiTest(void) test_wolfSSL_SetTmpDH_buffer(); test_wolfSSL_read_write(); test_wolfSSL_dtls_export(); - AssertTrue(test_wolfSSL_SetMinVersion()); + AssertIntEQ(test_wolfSSL_SetMinVersion(), SSL_SUCCESS); + AssertIntEQ(test_wolfSSL_CTX_SetMinVersion(), SSL_SUCCESS); /* TLS extensions tests */ @@ -2015,7 +2035,6 @@ void ApiTest(void) test_wolfSSL_UseALPN(); /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); - AssertTrue(test_wolfSSL_CTX_SetMinVersion()); /* wolfcrypt initialization tests */ AssertFalse(test_wolfCrypt_Init()); @@ -2024,17 +2043,17 @@ void ApiTest(void) #if defined(HAVE_OCSP) #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) - AssertTrue(test_wolfSSL_UseOCSPStapling()); + AssertIntEQ(test_wolfSSL_UseOCSPStapling(), SSL_SUCCESS); #endif #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - AssertTrue(test_wolfSSL_UseOCSPStaplingV2()); + AssertIntEQ(test_wolfSSL_UseOCSPStaplingV2(), SSL_SUCCESS); #endif #endif /* HAVE_OCSP. */ - AssertTrue(test_wolfSSL_Cleanup()); + AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS); printf(" End API Tests\n"); } From 813a9b05b5c51a43a0542f4a4e85ce82cb96e8ac Mon Sep 17 00:00:00 2001 From: John Blixt Date: Thu, 18 Aug 2016 15:07:07 -0600 Subject: [PATCH 08/69] Clean up and Chris check added the changes. --- tests/api.c | 203 ++++++++++++++++++++++++++++------------------------ 1 file changed, 109 insertions(+), 94 deletions(-) diff --git a/tests/api.c b/tests/api.c index 299800f252..54212a4a38 100644 --- a/tests/api.c +++ b/tests/api.c @@ -103,7 +103,7 @@ static int test_wolfSSL_Cleanup(void) } -/* Initialize the wolfcrypt state. +/* Initialize the wolfCrypt state. * POST: 0 success. */ static int test_wolfCrypt_Init(void) @@ -211,24 +211,30 @@ 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) { -#ifndef NO_CERTS - WOLFSSL_CTX* ctx; - int ret; - - printf(testingFmt, "wolfSSL_CTX_use_certificate_buffer()"); - AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); - #ifdef USE_CERT_BUFFERS_2048 - ret = wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048, + #if !defined(NO_CERTS) && defined(USE_CERT_BUFFERS_2048) + 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); + + return ret; + #else + return SSL_SUCCESS; #endif - printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); - - return ret; -#else - return; -#endif + } /*END test_wolfSSL_CTX_use_certificate_buffer*/ static void test_wolfSSL_CTX_use_PrivateKey_file(void) @@ -523,14 +529,20 @@ static void test_wolfSSL_SetTmpDH_buffer(void) } -/* Test function for wolfSSL_SetMinVersion +/* 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 ret; + int failFlag, itr; + + const char* versionsVar[] = { "retV1", "retV1_1", "retV1_2" }; + const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1, + WOLFSSL_TLSV1_2}; + failFlag = SSL_SUCCESS; AssertTrue(wolfSSL_Init()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); @@ -538,17 +550,19 @@ static int test_wolfSSL_SetMinVersion(void) printf(testingFmt, "wolfSSL_SetMinVersion()"); - ret = wolfSSL_SetMinVersion(ssl, 3); - - printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + for (itr = 0; itr < (int)(sizeof(versionsVar)/sizeof(char*)); 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()); - - if(ret != SSL_SUCCESS) { return SSL_FAILURE; } - - return SSL_SUCCESS; + + return failFlag; } /* END test_wolfSSL_SetMinVersion */ @@ -1894,29 +1908,38 @@ static void test_wolfSSL_X509_NAME_get_entry(void) #endif /* !NO_CERTS */ } -/* Testing function wolfSSL_CTX_SetMinVersion +/* 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 ret; + int failFlag, itr; + + const char* versionsVar[] = { "retV1", "retV1_1", "retV1_2" }; + const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1, + WOLFSSL_TLSV1_2 }; + + failFlag = SSL_SUCCESS; AssertTrue(wolfSSL_Init()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); printf(testingFmt, "wolfSSL_CTX_SetMinVersion()"); - ret = wolfSSL_CTX_SetMinVersion(ctx, 3); + for (itr = 0; itr < (int)(sizeof(versionsVar)/sizeof(char*)); itr++){ + if(wolfSSL_CTX_SetMinVersion(ctx, *(versions + itr)) != SSL_SUCCESS){ + failFlag = SSL_FAILURE; + } + } - printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + printf(resultFmt, failFlag == SSL_SUCCESS ? passed : failed); wolfSSL_CTX_free(ctx); AssertTrue(wolfSSL_Cleanup()); - if(ret != SSL_SUCCESS) { return SSL_FAILURE; } - - return SSL_SUCCESS; + return failFlag; } /* END test_wolfSSL_CTX_SetMinVersion */ @@ -1926,78 +1949,82 @@ static int test_wolfSSL_CTX_SetMinVersion(void) *----------------------------------------------------------------------------*/ -/* Testing wolfSSL_UseOCSPStapling function. +/* 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. */ -#if defined(HAVE_OCSP) - #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) static int test_wolfSSL_UseOCSPStapling(void) { - int ret; - WOLFSSL_CTX* ctx; - WOLFSSL* ssl; + #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_Init(); - ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); - ssl = wolfSSL_new(ctx); - printf(testingFmt, "wolfSSL_UseOCSPStapling()"); + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); - ret = wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR2_OCSP, - WOLFSSL_CSR2_OCSP_USE_NONCE); + if(ret != SSL_SUCCESS){ + wolfSSL_Cleanup(); + return SSL_FAILURE; + } - 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(); + return wolfSSL_Cleanup(); + #else + return SSL_SUCCESS; + #endif } /*END test_wolfSSL_UseOCSPStapling */ - #endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ - #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 +/* 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) { - int ret; - WOLFSSL_CTX* ctx; - WOLFSSL* ssl; + #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()"); + 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 ); + ret = wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP, + WOLFSSL_CSR2_OCSP_USE_NONCE ); - printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); - wolfSSL_free(ssl); - wolfSSL_CTX_free(ctx); + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); - if(ret != SSL_SUCCESS){ - wolfSSL_Cleanup(); - return SSL_FAILURE; - } + if(ret != SSL_SUCCESS){ + wolfSSL_Cleanup(); + return SSL_FAILURE; + } - return wolfSSL_Cleanup(); + return wolfSSL_Cleanup(); + #else + return SSL_SUCCESS; + #endif } /*END test_wolfSSL_UseOCSPStaplingV2*/ - #endif /* HAVE_CERTIFICATE_STATUS_REQUEST. */ -#endif /* HAVE_OCSP*/ - - - /*----------------------------------------------------------------------------* | Main @@ -2007,7 +2034,8 @@ void ApiTest(void) { printf(" Begin API Tests\n"); 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(); @@ -2026,33 +2054,20 @@ void ApiTest(void) AssertIntEQ(test_wolfSSL_SetMinVersion(), SSL_SUCCESS); AssertIntEQ(test_wolfSSL_CTX_SetMinVersion(), SSL_SUCCESS); - /* TLS extensions tests */ test_wolfSSL_UseSNI(); test_wolfSSL_UseMaxFragment(); test_wolfSSL_UseTruncatedHMAC(); test_wolfSSL_UseSupportedCurve(); test_wolfSSL_UseALPN(); + /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); - /* wolfcrypt initialization tests */ - AssertFalse(test_wolfCrypt_Init()); - /*OCSP Stapling. */ -#if defined(HAVE_OCSP) - #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) - AssertIntEQ(test_wolfSSL_UseOCSPStapling(), SSL_SUCCESS); - - #endif - #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - AssertIntEQ(test_wolfSSL_UseOCSPStaplingV2(), SSL_SUCCESS); - #endif -#endif /* HAVE_OCSP. */ - AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS); printf(" End API Tests\n"); From fa1989b72966266a47d241e88b135e5d370355e8 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 18 Aug 2016 17:51:25 -0700 Subject: [PATCH 09/69] fix building the new session ticket message for DTLS, take into account the additional header sizes --- src/internal.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/internal.c b/src/internal.c index 0fba76ab67..ba6fa3ad97 100755 --- a/src/internal.c +++ b/src/internal.c @@ -18200,13 +18200,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 +18208,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 +18236,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; From a9935cbc285d3420d7ab12309111c07ffdda46b1 Mon Sep 17 00:00:00 2001 From: John Blixt Date: Fri, 19 Aug 2016 10:23:55 -0600 Subject: [PATCH 10/69] Made changes found by Jenkins. --- tests/api.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/tests/api.c b/tests/api.c index 54212a4a38..b2dfdfbe6c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -218,7 +218,7 @@ static void test_wolfSSL_CTX_use_certificate_file(void) */ static int test_wolfSSL_CTX_use_certificate_buffer(void) { - #if !defined(NO_CERTS) && defined(USE_CERT_BUFFERS_2048) + #if !defined(NO_CERTS) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA) WOLFSSL_CTX* ctx; int ret; @@ -229,6 +229,7 @@ static int test_wolfSSL_CTX_use_certificate_buffer(void) sizeof_server_cert_der_2048, SSL_FILETYPE_ASN1); printf(resultFmt, ret == SSL_SUCCESS ? passed : failed); + wolfSSL_CTX_free(ctx); return ret; #else @@ -538,10 +539,13 @@ static int test_wolfSSL_SetMinVersion(void) WOLFSSL_CTX* ctx; WOLFSSL* ssl; int failFlag, itr; - - const char* versionsVar[] = { "retV1", "retV1_1", "retV1_2" }; - const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1, + + #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()); @@ -550,18 +554,18 @@ static int test_wolfSSL_SetMinVersion(void) printf(testingFmt, "wolfSSL_SetMinVersion()"); - for (itr = 0; itr < (int)(sizeof(versionsVar)/sizeof(char*)); itr++){ + 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 */ @@ -1916,10 +1920,13 @@ static int test_wolfSSL_CTX_SetMinVersion(void) { WOLFSSL_CTX* ctx; int failFlag, itr; - - const char* versionsVar[] = { "retV1", "retV1_1", "retV1_2" }; - const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1, + + #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; @@ -1928,10 +1935,10 @@ static int test_wolfSSL_CTX_SetMinVersion(void) printf(testingFmt, "wolfSSL_CTX_SetMinVersion()"); - for (itr = 0; itr < (int)(sizeof(versionsVar)/sizeof(char*)); itr++){ + 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); From 1a94c0bbdd462ef3c195fe84a155486c1b175f07 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 22 Aug 2016 10:00:37 -0600 Subject: [PATCH 11/69] add distro build option --- configure.ac | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/configure.ac b/configure.ac index ed283b5efb..106157df80 100644 --- a/configure.ac +++ b/configure.ac @@ -125,6 +125,73 @@ 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_sniffer=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_arc4=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)], @@ -2986,6 +3053,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" From 45c8ed143660f30626bda57a8e74fbf9f8681335 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 22 Aug 2016 14:18:35 -0600 Subject: [PATCH 12/69] remove -X from ocsp stapling tests that are not external --- scripts/ocsp-stapling.test | 4 ++-- scripts/ocsp-stapling2.test | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) 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 From 91ccf1bd8672917070bf52de78158d62c77f8019 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 22 Aug 2016 15:33:45 -0600 Subject: [PATCH 13/69] do not enable ARC4 or sniffer in distro build --- configure.ac | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure.ac b/configure.ac index 106157df80..09f387adb1 100644 --- a/configure.ac +++ b/configure.ac @@ -142,7 +142,6 @@ then enable_savecert=yes enable_atomicuser=yes enable_pkcallbacks=yes - enable_sniffer=yes enable_aesgcm=yes enable_aesccm=yes enable_camellia=yes @@ -164,7 +163,6 @@ then enable_eccencrypt=yes enable_psk=yes enable_idea=yes - enable_arc4=yes enable_cmac=yes enable_webserver=yes enable_hc128=yes From a9278fe492547bb553f36a5cf86dd40e1059ce4b Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 23 Aug 2016 11:31:15 -0700 Subject: [PATCH 14/69] Added check for GetLength result in asn GetIntRsa function. Fixed return code in random.c for "wolfAsync_DevCtxInit" due to copy/paste error. Added RSA wc_RsaCleanup to make sure allocated tmp buffer is always free'd. Eliminated invalid RSA key type checks and "RSA_CHECK_KEYTYPE". --- wolfcrypt/src/asn.c | 11 +++++--- wolfcrypt/src/random.c | 2 +- wolfcrypt/src/rsa.c | 57 ++++++++++++++++++----------------------- wolfssl/wolfcrypt/rsa.h | 3 ++- 4 files changed, 35 insertions(+), 38 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 59d89b8825..884e66ae50 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -692,10 +692,13 @@ static int GetIntRsa(RsaKey* key, mp_int* mpi, const byte* input, if (GetLength(input, &i, &length, maxIdx) < 0) return ASN_PARSE_E; - if ( (b = input[i++]) == 0x00) - length--; - else - i--; + 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) { diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index efcd3a5705..75ba61a8f2 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -810,7 +810,7 @@ int wc_InitRng(WC_RNG* rng) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM) ret = wolfAsync_DevCtxInit(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG, INVALID_DEVID); - if (ret != 0) return -2007; + if (ret != 0) return ret; #endif #ifdef WOLFSSL_SMALL_STACK diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index f5f65541fe..e7fa4b9f49 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -38,7 +38,7 @@ Possible RSA enable options: * 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_CHECK_KEYTYPE: RSA check key type default: off + */ /* @@ -165,6 +165,23 @@ enum { 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; @@ -180,6 +197,7 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) key->heap = heap; key->tmp = NULL; key->tmpLen = 0; + key->tmpIsAlloc = 0; #ifdef WOLFSSL_ASYNC_CRYPT if (devId != INVALID_DEVID) { @@ -227,6 +245,8 @@ int wc_FreeRsaKey(RsaKey* key) return BAD_FUNC_ARG; } + wc_RsaCleanup(key); + #ifdef WOLFSSL_ASYNC_CRYPT if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { ret = FreeAsyncRsaKey(key); @@ -791,13 +811,13 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out, switch (padType) { case WC_RSA_PKCSV15_PAD: - //WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding"); + WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding"); ret = RsaUnPad(pkcsBlock, pkcsBlockLen, out, padValue); break; #ifndef WC_NO_RSA_OAEP case WC_RSA_OAEP_PAD: - //WOLFSSL_MSG("wolfSSL Using RSA OAEP padding"); + WOLFSSL_MSG("wolfSSL Using RSA OAEP padding"); ret = RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out, hType, mgf, optLabel, labelLen, heap); break; @@ -1159,16 +1179,6 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, return RSA_BUFFER_E; } - /* Optional key type check (disabled by default) */ - /* Note: internal tests allow private to be used as public */ -#ifdef RSA_CHECK_KEYTYPE - if ((rsa_type == RSA_PUBLIC_ENCRYPT && key->type != RSA_PUBLIC) || - (rsa_type == RSA_PRIVATE_ENCRYPT && key->type != RSA_PRIVATE)) { - WOLFSSL_MSG("Wrong RSA Encrypt key type"); - return RSA_WRONG_TYPE_E; - } -#endif - switch (key->state) { case RSA_STATE_NONE: case RSA_STATE_ENCRYPT_PAD: @@ -1251,16 +1261,6 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, return ret; } - /* Optional key type check (disabled by default) */ - /* Note: internal tests allow private to be used as public */ -#ifdef RSA_CHECK_KEYTYPE - if ((rsa_type == RSA_PUBLIC_DECRYPT && key->type != RSA_PUBLIC) || - (rsa_type == RSA_PRIVATE_DECRYPT && key->type != RSA_PRIVATE)) { - WOLFSSL_MSG("Wrong RSA Decrypt key type"); - return RSA_WRONG_TYPE_E; - } -#endif - switch (key->state) { case RSA_STATE_NONE: case RSA_STATE_DECRYPT_EXPTMOD: @@ -1296,6 +1296,7 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, 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); } @@ -1353,15 +1354,7 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, done: key->state = RSA_STATE_NONE; - if (key->tmp) { - /* if not inline */ - if (outPtr == NULL) { - ForceZero(key->tmp, key->tmpLen); - XFREE(key->tmp, key->heap, DYNAMIC_TYPE_RSA); - } - key->tmp = NULL; - key->tmpLen = 0; - } + wc_RsaCleanup(key); return ret; } diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 4916920578..79b7870141 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -82,8 +82,9 @@ typedef struct RsaKey { int type; /* public or private */ void* heap; /* for user memory overrides */ int state; - byte* tmp; + byte* tmp; /* temp buffer for async RSA */ word32 tmpLen; + byte tmpIsAlloc; #ifdef WC_RSA_BLINDING WC_RNG* rng; /* for PrivateDecrypt blinding */ #endif From dd7f9b618de868c6a8158c50d750f9edb91dec38 Mon Sep 17 00:00:00 2001 From: toddouska Date: Thu, 25 Aug 2016 12:23:57 -0700 Subject: [PATCH 15/69] make sure static analysis realizes err_sys does exit() --- wolfssl/test.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wolfssl/test.h b/wolfssl/test.h index 360d3e9087..cac07f7dab 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -358,8 +358,7 @@ static const word16 wolfSSLPort = 11111; static INLINE void err_sys(const char* msg) { printf("wolfSSL error: %s\n", msg); - if (msg) - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } From 86e889a7fa842e0cba848fa9fd2805943f41e1db Mon Sep 17 00:00:00 2001 From: toddouska Date: Fri, 26 Aug 2016 10:20:58 -0700 Subject: [PATCH 16/69] only force exit() in all cases with gcc since we know noreturn attribute there --- wolfssl/test.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/wolfssl/test.h b/wolfssl/test.h index cac07f7dab..f23748ee47 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -355,10 +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); - exit(EXIT_FAILURE); + +#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); + } } From 925e5e34841539b1d0e1a2fad8b2f7779f680677 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 26 Aug 2016 10:33:01 -0700 Subject: [PATCH 17/69] Fixes typo issue with heap in hmac and small stack enabled. Fixed "never read" scan-build warnings with typeH and verify when RSA is disabled. --- src/internal.c | 45 ++++++++++++++++++++++++++------------------ wolfcrypt/src/hmac.c | 6 +++--- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/internal.c b/src/internal.c index e2fa3feac3..81910b8a97 100755 --- a/src/internal.c +++ b/src/internal.c @@ -13300,7 +13300,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, 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; @@ -13310,7 +13312,6 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, (void)output; (void)sigSz; - (void)typeH; WOLFSSL_ENTER("DoServerKeyExchange"); @@ -13332,7 +13333,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, 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; @@ -13410,7 +13413,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ERROR_OUT(DH_KEY_SIZE_E, exit_dske); } - ssl->buffers.serverDH_P.buffer = + 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; @@ -13436,7 +13439,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ERROR_OUT(BUFFER_ERROR, exit_dske); } - ssl->buffers.serverDH_G.buffer = + 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; @@ -13808,7 +13811,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ERROR_OUT(ALGO_ID_E, exit_dske); #endif } + #ifndef NO_RSA typeH = wc_HashGetOID(hashType); + #endif /* signature */ if ((idx - begin) + OPAQUE16_LEN > size) { @@ -13840,7 +13845,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, } /* build message to hash */ - XMEMCPY(ssl->buffers.sig.buffer, + XMEMCPY(ssl->buffers.sig.buffer, ssl->arrays->clientRandom, RAN_LEN); XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN); @@ -13920,7 +13925,8 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, } if (verifySig == NULL) { - verifySig = (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + verifySig = (byte*)XMALLOC(length, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); if (!verifySig) { ERROR_OUT(MEMORY_E, exit_dske); } @@ -14040,8 +14046,8 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, encSigSz = wc_EncodeSignature(encodedSig, ssl->buffers.digest.buffer, ssl->buffers.digest.length, typeH); - if (encSigSz != sigSz || !output || - XMEMCMP(output, encodedSig, + if (encSigSz != sigSz || !output || + XMEMCMP(output, encodedSig, min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) { ret = VERIFY_SIGN_ERROR; } @@ -14101,7 +14107,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, idx += OPAQUE16_LEN; if (name == TLSX_QUANTUM_SAFE_HYBRID) { - /* if qshSz is larger than 0 it is the length of + /* if qshSz is larger than 0 it is the length of buffer used */ if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + idx, size, 0)) < 0) { @@ -14152,7 +14158,9 @@ exit_dske: ssl->async.length = length; ssl->async.output = output; ssl->async.sigSz = sigSz; + #ifndef NO_RSA ssl->async.hashAlgo = typeH; + #endif ssl->async.sigAlgo = sigAlgo; #if !defined(NO_DH) || defined(HAVE_ECC) ssl->async.data = verifySig; @@ -15037,7 +15045,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { - ecc_key* peerKey = (ssl->specs.static_ecdh) ? + ecc_key* peerKey = (ssl->specs.static_ecdh) ? ssl->peerEccDsaKey : ssl->peerEccKey; ret = EccSharedSecret(ssl, (ecc_key*)ssl->sigKey, peerKey, @@ -15548,7 +15556,7 @@ int SendCertificateVerify(WOLFSSL* ssl) 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) ? @@ -15617,9 +15625,6 @@ int SendCertificateVerify(WOLFSSL* ssl) case KEYSHARE_DO: { - /* restore verify pointer */ - verify = &output[idx]; - #ifdef HAVE_ECC if (ssl->sigType == DYNAMIC_TYPE_ECC) { ret = EccSign(ssl, @@ -15638,6 +15643,9 @@ int SendCertificateVerify(WOLFSSL* ssl) #endif /* HAVE_ECC */ #ifndef NO_RSA if (ssl->sigType == DYNAMIC_TYPE_RSA) { + /* restore verify pointer */ + verify = &output[idx]; + ret = RsaSign(ssl, ssl->buffers.sig.buffer, ssl->buffers.sig.length, verify + extraSz + VERIFY_HEADER, &ssl->sigLen, @@ -15683,7 +15691,8 @@ int SendCertificateVerify(WOLFSSL* ssl) if (verifySig == NULL) { ERROR_OUT(MEMORY_E, exit_scv); } - XMEMCPY(verifySig, verify + extraSz + VERIFY_HEADER, ssl->sigLen); + XMEMCPY(verifySig, verify + extraSz + VERIFY_HEADER, + ssl->sigLen); } /* check for signature faults */ @@ -15822,7 +15831,7 @@ exit_scv: return ret; } - + #endif /* NO_CERTS */ @@ -19219,7 +19228,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->peerEccKeyPresent = 1; ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); - + if (ret != 0) { goto exit_dcke; } @@ -19375,7 +19384,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Advance state and proceed */ ssl->options.keyShareState = KEYSHARE_DO; } /* KEYSHARE_BUILD */ - + case KEYSHARE_DO: { switch (ssl->specs.kea) { @@ -19671,7 +19680,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } /* switch(ssl->options.keyShareState) */ exit_dcke: - + WOLFSSL_LEAVE("DoClientKeyExchange", ret); /* Handle cleanup for stack variables here */ diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 2a26d26634..5312b28601 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -739,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, hmac->heap, 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, hmac->heap, DYNAMIC_TYPE_TMP_BUFFER); + prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, myHmac.heap, DYNAMIC_TYPE_TMP_BUFFER); if (prk == NULL) { - XFREE(tmp, hmac->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, myHmac.heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #endif From bf23b2f9d1fc55b6b93d7db32e1628076b87b7e2 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 26 Aug 2016 12:35:47 -0700 Subject: [PATCH 18/69] Fix issue with "wc_ecc_set_custom_curve" function not setting index as "ECC_CUSTOM_IDX". Cleanup of the ECC tests to return actual error code (when available) and make sure keys are free'd. Some trailing whitespace cleanup. --- wolfcrypt/src/ecc.c | 22 ++++++------ wolfcrypt/test/test.c | 83 +++++++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 7fc45faa39..ec324308bb 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,7 +1871,7 @@ 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 */ @@ -1979,7 +1979,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; } @@ -3786,7 +3786,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; @@ -6615,7 +6615,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; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index a9c2088ff2..99354741d6 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6679,7 +6679,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]; @@ -6692,22 +6692,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) @@ -6791,7 +6793,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) @@ -6904,7 +6906,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]; @@ -6917,46 +6919,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"); @@ -6964,17 +6969,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, @@ -7010,28 +7017,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); @@ -7044,18 +7050,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); @@ -7066,19 +7072,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); @@ -7097,16 +7103,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 Date: Fri, 26 Aug 2016 13:47:53 -0700 Subject: [PATCH 19/69] fix normal math 16bit digit_bit for all ecc sizes --- wolfssl/wolfcrypt/integer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 3c8a0020a1..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) */ From 2d9b6cf27a46f67b5ad3ce53ecba8e15d6f6f3a8 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 1 Aug 2016 07:51:42 -0700 Subject: [PATCH 20/69] added SCTP to configure.ac --- configure.ac | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/configure.ac b/configure.ac index fbb1481a02..0d1e704051 100644 --- a/configure.ac +++ b/configure.ac @@ -221,6 +221,13 @@ 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]) + + # OpenSSH compatibility Build AC_ARG_ENABLE([openssh], [AS_HELP_STRING([--enable-openssh],[Enable OpenSSH compatibility build (default: disabled)])], @@ -2886,6 +2893,12 @@ 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.])]) +# 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 @@ -3147,6 +3160,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" From ebbf5ec72bbb5f003adcdf90b609b1aba11f67ff Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 3 Aug 2016 08:12:55 -0700 Subject: [PATCH 21/69] add new options and accessors for SCTP --- src/ssl.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ wolfssl/internal.h | 7 ++++ wolfssl/ssl.h | 6 ++++ 3 files changed, 98 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 2fb0d17ed6..f9a459c109 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -547,6 +547,91 @@ int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz) return SSL_NOT_IMPLEMENTED; #endif } + + +int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, unsigned int newMtu) +{ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + if (ssl == NULL) + return SSL_FAILURE; + + if (newMtu > MAX_RECORD_SIZE) { + ssl->error = BAD_FUNC_ARG; + return SSL_FAILURE; + } + + return SSL_SUCCESS; +#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ + (void)ssl; + (void)newMtu; + return SSL_NOT_IMPLEMENTED; +#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ +} + + +int wolfSSL_dtls_enable_retransmission(WOLFSSL* ssl, unsigned int options) +{ + (void)options; + +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + if (ssl == NULL) + return SSL_FAILURE; + + ssl->options.dtlsRetxEnable = 1; + return SSL_SUCCESS; +#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ + (void)ssl; + return SSL_NOT_IMPLEMENTED; +#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ +} + + +int wolfSSL_dtls_disable_retransmission(WOLFSSL* ssl) +{ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + if (ssl == NULL) + return SSL_FAILURE; + + ssl->options.dtlsRetxEnable = 0; + return SSL_SUCCESS; +#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ + (void)ssl; + return SSL_NOT_IMPLEMENTED; +#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ +} + + +int wolfSSL_dtls_enable_replay_detection(WOLFSSL* ssl, unsigned int options) +{ + (void)options; + +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + if (ssl == NULL) + return SSL_FAILURE; + + ssl->options.dtlsReplayEnable = 1; + return SSL_SUCCESS; +#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ + (void)ssl; + return SSL_NOT_IMPLEMENTED; +#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ +} + + +int wolfSSL_dtls_disable_replay_detection(WOLFSSL* ssl) +{ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + if (ssl == NULL) + return SSL_FAILURE; + + ssl->options.dtlsReplayEnable = 0; + return SSL_SUCCESS; +#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ + (void)ssl; + return SSL_NOT_IMPLEMENTED; +#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ +} + #endif /* WOLFSSL_LEANPSK */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 3a3e006356..65ca2b5b83 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2405,6 +2405,10 @@ typedef struct Options { #endif #ifdef WOLFSSL_DTLS word16 dtlsHsRetain:1; /* DTLS retaining HS data */ +#ifdef WOLFSSL_SCTP + word16 dtlsRetxEnable:1; /* DTLS HS retransmission enable */ + word16 dtlsReplayEnable:1; /* DTLS Replay detection enable */ +#endif /* WOLFSSL_SCTP */ #endif /* need full byte values for this section */ @@ -2744,6 +2748,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 + word32 mtu_size; +#endif /* WOLFSSL_SCTP */ #endif #ifdef WOLFSSL_CALLBACKS HandShakeInfo handShakeInfo; /* info saved during handshake */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2af2dfffa0..63373d15a0 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -409,6 +409,12 @@ 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_dtls_set_mtu(WOLFSSL*, unsigned int); +WOLFSSL_API int wolfSSL_dtls_enable_retransmission(WOLFSSL*, unsigned int); +WOLFSSL_API int wolfSSL_dtls_disable_retransmission(WOLFSSL*); +WOLFSSL_API int wolfSSL_dtls_enable_replay_detection(WOLFSSL*, unsigned int); +WOLFSSL_API int wolfSSL_dtls_disable_replay_detection(WOLFSSL*); + 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, From b7a35eabd203adbe0b5c8142df97a67960a91c4e Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 18 Aug 2016 17:02:54 -0700 Subject: [PATCH 22/69] Add simple SCTP example tools --- .gitignore | 4 ++ configure.ac | 2 + examples/include.am | 1 + examples/sctp/include.am | 38 ++++++++++ examples/sctp/sctp-client-dtls.c | 105 ++++++++++++++++++++++++++++ examples/sctp/sctp-client.c | 64 +++++++++++++++++ examples/sctp/sctp-server-dtls.c | 115 +++++++++++++++++++++++++++++++ examples/sctp/sctp-server.c | 70 +++++++++++++++++++ 8 files changed, 399 insertions(+) create mode 100644 examples/sctp/include.am create mode 100644 examples/sctp/sctp-client-dtls.c create mode 100644 examples/sctp/sctp-client.c create mode 100644 examples/sctp/sctp-server-dtls.c create mode 100644 examples/sctp/sctp-server.c diff --git a/.gitignore b/.gitignore index ab22d786e5..dd4247fcca 100644 --- a/.gitignore +++ b/.gitignore @@ -51,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/configure.ac b/configure.ac index 0d1e704051..eeccde13bb 100644 --- a/configure.ac +++ b/configure.ac @@ -227,6 +227,8 @@ AC_ARG_ENABLE([sctp], [ENABLED_SCTP=$enableval], [ENABLED_SCTP=no]) +AM_CONDITIONAL([BUILD_SCTP], [test "x$ENABLED_SCTP" = "xyes"]) + # OpenSSH compatibility Build AC_ARG_ENABLE([openssh], 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..c1708d451e --- /dev/null +++ b/examples/sctp/sctp-client-dtls.c @@ -0,0 +1,105 @@ +/* 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_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, strlen(response)); + int got = wolfSSL_read(ssl, buffer, sizeof(buffer)); + if (got > 0) { + buffer[got] = 0; + printf("server said: %s\n", buffer); + } + + 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..dece6cc88d --- /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 = 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..d255c733cf --- /dev/null +++ b/examples/sctp/sctp-server-dtls.c @@ -0,0 +1,115 @@ +/* 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_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, strlen(response)); + + 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..4228efbaa6 --- /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 = 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; +} From c1970434d16db1ec9c5199c65fc1b9322cd08d7f Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 22 Aug 2016 08:49:10 -0700 Subject: [PATCH 23/69] simplify the SCTP options --- src/internal.c | 32 ++++++++++---- src/ssl.c | 101 ++++++++++++++++++--------------------------- wolfssl/internal.h | 9 ++-- wolfssl/ssl.h | 7 ++-- 4 files changed, 74 insertions(+), 75 deletions(-) diff --git a/src/internal.c b/src/internal.c index 81910b8a97..3f14858ea9 100755 --- a/src/internal.c +++ b/src/internal.c @@ -195,6 +195,20 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) } +#ifdef WOLFSSL_DTLS +/* If SCTP is not enabled returns the state of the dtls option. + * If SCTP is enabled returns dtls && sctp. */ +static INLINE int IsDtlsSctpMode(WOLFSSL* ssl) +{ +#ifdef WOLFSSL_SCTP + return ssl->options.dtls && ssl->options.dtlsSctp; +#else + return ssl->options.dtls; +#endif +} +#endif + + #ifdef HAVE_QSH /* free all structs that where used with QSH */ static int QSH_FreeAll(WOLFSSL* ssl) @@ -1373,6 +1387,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->devId = INVALID_DEVID; +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + ctx->dtlsMtuSz = MAX_MTU; +#endif + #ifndef NO_CERTS ctx->cm = wolfSSL_CertManagerNew_ex(heap); if (ctx->cm == NULL) { @@ -3336,9 +3354,13 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) ssl->options.processReply = doProcessInit; #ifdef WOLFSSL_DTLS + #ifdef WOLFSSL_SCTP + ssl->options.dtlsSctp = ctx->dtlsSctp; + #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 @@ -3348,10 +3370,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #endif -#ifdef WOLFSSL_DTLS - ssl->buffers.dtlsCtx.fd = -1; -#endif - ssl->cipher.ssl = ssl; #ifdef HAVE_TLS_EXTENSIONS @@ -5055,7 +5073,7 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls && + if (IsDtlsSctpMode(ssl) && (!DtlsCheckWindow(&ssl->keys.dtls_state) || (ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) { return SEQUENCE_ERROR; @@ -9282,11 +9300,11 @@ int ProcessReply(WOLFSSL* ssl) ssl->keys.decryptedCur = 1; } - if (ssl->options.dtls) { #ifdef WOLFSSL_DTLS + if (IsDtlsSctpMode(ssl)) { DtlsUpdateWindow(&ssl->keys.dtls_state); - #endif /* WOLFSSL_DTLS */ } + #endif /* WOLFSSL_DTLS */ WOLFSSL_MSG("received record layer msg"); diff --git a/src/ssl.c b/src/ssl.c index f9a459c109..4e7346940e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -549,11 +549,42 @@ int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz) } -int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, unsigned int newMtu) -{ #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) + +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 SSL_FAILURE; + return BAD_FUNC_ARG; + + ssl->options.dtlsSctp = 1; + return SSL_SUCCESS; +} + + +/* wolfSSL_dtls_set_mtu + * Sets the DTLS MTU size. For the deafult MTU of 1500, set to 1500. + * The maximum allowed value is 16384, the maximum record size. The MTU + * needs to be larger than 200, need to be able to fit in the IP/UDP/DTLS + * headers. + */ +int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word32 newMtu) +{ + if (ctx == NULL) + return BAD_FUNC_ARG; if (newMtu > MAX_RECORD_SIZE) { ssl->error = BAD_FUNC_ARG; @@ -561,76 +592,24 @@ int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, unsigned int newMtu) } return SSL_SUCCESS; -#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ - (void)ssl; - (void)newMtu; - return SSL_NOT_IMPLEMENTED; -#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ } -int wolfSSL_dtls_enable_retransmission(WOLFSSL* ssl, unsigned int options) +int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word32 newMtu) { - (void)options; - -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) if (ssl == NULL) + return BAD_FUNC_ARG; + + if (newMtu > MAX_RECORD_SIZE) { + ssl->error = BAD_FUNC_ARG; return SSL_FAILURE; + } - ssl->options.dtlsRetxEnable = 1; return SSL_SUCCESS; -#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ - (void)ssl; - return SSL_NOT_IMPLEMENTED; -#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ } -int wolfSSL_dtls_disable_retransmission(WOLFSSL* ssl) -{ -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) - if (ssl == NULL) - return SSL_FAILURE; - - ssl->options.dtlsRetxEnable = 0; - return SSL_SUCCESS; -#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ - (void)ssl; - return SSL_NOT_IMPLEMENTED; #endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ -} - - -int wolfSSL_dtls_enable_replay_detection(WOLFSSL* ssl, unsigned int options) -{ - (void)options; - -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) - if (ssl == NULL) - return SSL_FAILURE; - - ssl->options.dtlsReplayEnable = 1; - return SSL_SUCCESS; -#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ - (void)ssl; - return SSL_NOT_IMPLEMENTED; -#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ -} - - -int wolfSSL_dtls_disable_replay_detection(WOLFSSL* ssl) -{ -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) - if (ssl == NULL) - return SSL_FAILURE; - - ssl->options.dtlsReplayEnable = 0; - return SSL_SUCCESS; -#else /* WOLFSSL_DTLS && WOLFSSL_SCTP */ - (void)ssl; - return SSL_NOT_IMPLEMENTED; -#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */ -} #endif /* WOLFSSL_LEANPSK */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 65ca2b5b83..31cbf32d78 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1940,6 +1940,10 @@ struct WOLFSSL_CTX { byte quietShutdown; /* don't send close notify */ byte groupMessages; /* group handshake messages before sending */ byte minDowngrade; /* minimum downgrade version */ +#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 @@ -2406,9 +2410,8 @@ typedef struct Options { #ifdef WOLFSSL_DTLS word16 dtlsHsRetain:1; /* DTLS retaining HS data */ #ifdef WOLFSSL_SCTP - word16 dtlsRetxEnable:1; /* DTLS HS retransmission enable */ - word16 dtlsReplayEnable:1; /* DTLS Replay detection enable */ -#endif /* WOLFSSL_SCTP */ + word16 dtlsSctp:1; /* DTLS-over-SCTP mode */ +#endif #endif /* need full byte values for this section */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 63373d15a0..7cd34b34f9 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -409,11 +409,10 @@ 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 int); WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned int); -WOLFSSL_API int wolfSSL_dtls_enable_retransmission(WOLFSSL*, unsigned int); -WOLFSSL_API int wolfSSL_dtls_disable_retransmission(WOLFSSL*); -WOLFSSL_API int wolfSSL_dtls_enable_replay_detection(WOLFSSL*, unsigned int); -WOLFSSL_API int wolfSSL_dtls_disable_replay_detection(WOLFSSL*); WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err); WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*); From 7b3255b5bbd3607d98a1baa3531afe833d21480f Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 22 Aug 2016 13:25:05 -0700 Subject: [PATCH 24/69] 1. Simplified the IsDtlsSctpMode() check. 2. Checked IsDtlsSctpMode() to skip saving messages to retransmit and skip retransmissions. --- src/internal.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/internal.c b/src/internal.c index 3f14858ea9..f47ad10c2b 100755 --- a/src/internal.c +++ b/src/internal.c @@ -200,11 +200,15 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) * If SCTP is enabled returns dtls && sctp. */ static INLINE int IsDtlsSctpMode(WOLFSSL* ssl) { + int result = ssl->options.dtls; + + if (result) { #ifdef WOLFSSL_SCTP - return ssl->options.dtls && ssl->options.dtlsSctp; -#else - return ssl->options.dtls; + result = ssl->options.dtlsSctp; #endif + } + + return result; } #endif @@ -4800,6 +4804,7 @@ retry: if (ssl->options.dtls) { #ifdef WOLFSSL_DTLS if (!ssl->options.handShakeDone && + IsDtlsSctpMode(ssl) && DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0) { @@ -7808,7 +7813,8 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, } *inOutIdx += ssl->keys.padSz; } - ret = DtlsPoolSend(ssl); + if (IsDtlsSctpMode(ssl)) + ret = DtlsPoolSend(ssl); } else if (fragSz < size) { /* Since this branch is in order, but fragmented, dtls_msg_list will be @@ -9198,7 +9204,7 @@ int ProcessReply(WOLFSSL* ssl) ssl->buffers.inputBuffer.length = 0; ssl->buffers.inputBuffer.idx = 0; - if (ssl->options.dtlsHsRetain) { + if (ssl->options.dtlsHsRetain && IsDtlsSctpMode(ssl)) { ret = DtlsPoolSend(ssl); if (ret != 0) return ret; @@ -9357,9 +9363,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 (IsDtlsSctpMode(ssl)) { + ret = DtlsPoolSend(ssl); + if (ret != 0) + return ret; + } if (ssl->curSize != 1) { WOLFSSL_MSG("Malicious or corrupted" @@ -9550,7 +9558,7 @@ int SendChangeCipher(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -9989,7 +9997,7 @@ int SendFinished(WOLFSSL* ssl) #endif #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, input, headerSz + finishedSz)) != 0) return ret; } @@ -10235,7 +10243,7 @@ int SendCertificate(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -10330,7 +10338,7 @@ int SendCertificateRequest(WOLFSSL* ssl) i += REQ_HEADER_SZ; */ #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -10429,7 +10437,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 && IsDtlsSctpMode(ssl)) ret = DtlsPoolSave(ssl, output, sendSz); #endif @@ -12836,7 +12844,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -15292,7 +15300,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { goto exit_scke; } @@ -15769,7 +15777,7 @@ int SendCertificateVerify(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { ret = DtlsPoolSave(ssl, output, sendSz); } #endif @@ -16046,7 +16054,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->buffers.outputBuffer.length += sendSz; #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -17370,7 +17378,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif /* HAVE_ECC */ #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { goto exit_sske; } @@ -18553,7 +18561,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, AddHeaders(output, 0, server_hello_done, ssl); #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return 0; } From f3dca48e99ba261fec9097ac97fad8f2d36be639 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 23 Aug 2016 08:53:38 -0700 Subject: [PATCH 25/69] Fix polarity on the DTLS-SCTP check. --- src/internal.c | 54 ++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/internal.c b/src/internal.c index f47ad10c2b..0df817e2d2 100755 --- a/src/internal.c +++ b/src/internal.c @@ -197,14 +197,14 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) #ifdef WOLFSSL_DTLS /* If SCTP is not enabled returns the state of the dtls option. - * If SCTP is enabled returns dtls && sctp. */ -static INLINE int IsDtlsSctpMode(WOLFSSL* ssl) + * 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; + result = !ssl->options.dtlsSctp; #endif } @@ -4801,17 +4801,15 @@ retry: return -1; case WOLFSSL_CBIO_ERR_TIMEOUT: - if (ssl->options.dtls) { -#ifdef WOLFSSL_DTLS - if (!ssl->options.handShakeDone && - IsDtlsSctpMode(ssl) && - 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: @@ -5078,7 +5076,7 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl) && + if (IsDtlsNotSctpMode(ssl) && (!DtlsCheckWindow(&ssl->keys.dtls_state) || (ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) { return SEQUENCE_ERROR; @@ -7813,7 +7811,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, } *inOutIdx += ssl->keys.padSz; } - if (IsDtlsSctpMode(ssl)) + if (IsDtlsNotSctpMode(ssl)) ret = DtlsPoolSend(ssl); } else if (fragSz < size) { @@ -9204,7 +9202,7 @@ int ProcessReply(WOLFSSL* ssl) ssl->buffers.inputBuffer.length = 0; ssl->buffers.inputBuffer.idx = 0; - if (ssl->options.dtlsHsRetain && IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl) && ssl->options.dtlsHsRetain) { ret = DtlsPoolSend(ssl); if (ret != 0) return ret; @@ -9307,7 +9305,7 @@ int ProcessReply(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { DtlsUpdateWindow(&ssl->keys.dtls_state); } #endif /* WOLFSSL_DTLS */ @@ -9363,7 +9361,7 @@ int ProcessReply(WOLFSSL* ssl) if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E) return ret; - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { ret = DtlsPoolSend(ssl); if (ret != 0) return ret; @@ -9558,7 +9556,7 @@ int SendChangeCipher(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -9997,7 +9995,7 @@ int SendFinished(WOLFSSL* ssl) #endif #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, input, headerSz + finishedSz)) != 0) return ret; } @@ -10243,7 +10241,7 @@ int SendCertificate(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -10338,7 +10336,7 @@ int SendCertificateRequest(WOLFSSL* ssl) i += REQ_HEADER_SZ; */ #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -10437,7 +10435,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, ret = HashOutput(ssl, output, sendSz, 0); #ifdef WOLFSSL_DTLS - if (ret == 0 && IsDtlsSctpMode(ssl)) + if (ret == 0 && IsDtlsNotSctpMode(ssl)) ret = DtlsPoolSave(ssl, output, sendSz); #endif @@ -12844,7 +12842,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, } #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -15300,7 +15298,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { goto exit_scke; } @@ -15777,7 +15775,7 @@ int SendCertificateVerify(WOLFSSL* ssl) } #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { ret = DtlsPoolSave(ssl, output, sendSz); } #endif @@ -16054,7 +16052,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->buffers.outputBuffer.length += sendSz; #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return ret; } @@ -17378,7 +17376,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif /* HAVE_ECC */ #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { goto exit_sske; } @@ -18561,7 +18559,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, AddHeaders(output, 0, server_hello_done, ssl); #ifdef WOLFSSL_DTLS - if (IsDtlsSctpMode(ssl)) { + if (IsDtlsNotSctpMode(ssl)) { if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) return 0; } From 52e2f1a7aba921d400eec7bff6404b0b84980207 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 23 Aug 2016 09:27:37 -0700 Subject: [PATCH 26/69] typecasts to clear static analysis warnings on SCTP examples --- examples/sctp/sctp-client-dtls.c | 2 +- examples/sctp/sctp-client.c | 2 +- examples/sctp/sctp-server-dtls.c | 2 +- examples/sctp/sctp-server.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/sctp/sctp-client-dtls.c b/examples/sctp/sctp-client-dtls.c index c1708d451e..d90fe2b4b2 100644 --- a/examples/sctp/sctp-client-dtls.c +++ b/examples/sctp/sctp-client-dtls.c @@ -88,7 +88,7 @@ int main() printf("Cipher Suite is %s\n", wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl))); - wolfSSL_write(ssl, response, strlen(response)); + wolfSSL_write(ssl, response, (int)strlen(response)); int got = wolfSSL_read(ssl, buffer, sizeof(buffer)); if (got > 0) { buffer[got] = 0; diff --git a/examples/sctp/sctp-client.c b/examples/sctp/sctp-client.c index dece6cc88d..b601fa4031 100644 --- a/examples/sctp/sctp-client.c +++ b/examples/sctp/sctp-client.c @@ -52,7 +52,7 @@ int main() char buffer[80]; send(sd, msg, strlen(msg), 0); - int got = recv(sd, buffer, sizeof(buffer), 0); + int got = (int)recv(sd, buffer, sizeof(buffer), 0); if (got > 0) { buffer[got] = 0; printf("server said: %s\n", buffer); diff --git a/examples/sctp/sctp-server-dtls.c b/examples/sctp/sctp-server-dtls.c index d255c733cf..8bf90cda37 100644 --- a/examples/sctp/sctp-server-dtls.c +++ b/examples/sctp/sctp-server-dtls.c @@ -103,7 +103,7 @@ int main() buffer[got] = 0; printf("client said: %s\n", buffer); } - wolfSSL_write(ssl, response, strlen(response)); + wolfSSL_write(ssl, response, (int)strlen(response)); wolfSSL_shutdown(ssl); wolfSSL_free(ssl); diff --git a/examples/sctp/sctp-server.c b/examples/sctp/sctp-server.c index 4228efbaa6..fc0439d364 100644 --- a/examples/sctp/sctp-server.c +++ b/examples/sctp/sctp-server.c @@ -56,7 +56,7 @@ int main() const char* response = "hi there"; char buffer[80]; - int got = recv(client_sd, buffer, sizeof(buffer), 0); + int got = (int)recv(client_sd, buffer, sizeof(buffer), 0); if (got > 0) { buffer[got] = 0; printf("client said: %s\n", buffer); From a6c0d4fed75fe332a1279747e6e5757727765415 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 24 Aug 2016 13:17:38 -0700 Subject: [PATCH 27/69] 1. Added missing -DWOLFSSL_SCTP to configure.ac. 2. Don't do hello verify requests in SCTP mode. 3. Implemented the SCTP MTU size changes. 4. Simplified the MAX_FRAGMENT size when calling ReceiveData(). --- configure.ac | 3 +++ src/internal.c | 24 +++++++++---------- src/ssl.c | 59 +++++++++++++++++++++++++++------------------- wolfssl/internal.h | 2 +- wolfssl/ssl.h | 4 ++-- 5 files changed, 53 insertions(+), 39 deletions(-) diff --git a/configure.ac b/configure.ac index eeccde13bb..3f6b858fa3 100644 --- a/configure.ac +++ b/configure.ac @@ -2895,6 +2895,9 @@ 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"], diff --git a/src/internal.c b/src/internal.c index 0df817e2d2..991c391605 100755 --- a/src/internal.c +++ b/src/internal.c @@ -195,7 +195,6 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend) } -#ifdef WOLFSSL_DTLS /* 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) @@ -210,7 +209,6 @@ static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl) return result; } -#endif #ifdef HAVE_QSH @@ -1392,7 +1390,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->devId = INVALID_DEVID; #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) - ctx->dtlsMtuSz = MAX_MTU; + ctx->dtlsMtuSz = MAX_RECORD_SIZE; #endif #ifndef NO_CERTS @@ -3346,9 +3344,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; @@ -3360,6 +3355,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #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; @@ -7448,7 +7447,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; @@ -17843,7 +17843,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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" @@ -17920,7 +17920,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* 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; } @@ -17953,7 +17953,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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; } @@ -18007,7 +18007,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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); @@ -18024,7 +18024,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return BUFFER_ERROR; #ifdef WOLFSSL_DTLS - if (ssl->options.dtls) { + if (IsDtlsNotSctpMode(ssl)) { byte newCookie[MAX_COOKIE_LEN]; int ret; diff --git a/src/ssl.c b/src/ssl.c index 4e7346940e..4d5fbfbde9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -549,7 +549,7 @@ int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz) } -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP) +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx) { @@ -575,27 +575,17 @@ int wolfSSL_dtls_set_sctp(WOLFSSL* ssl) } -/* wolfSSL_dtls_set_mtu - * Sets the DTLS MTU size. For the deafult MTU of 1500, set to 1500. - * The maximum allowed value is 16384, the maximum record size. The MTU - * needs to be larger than 200, need to be able to fit in the IP/UDP/DTLS - * headers. - */ -int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word32 newMtu) +int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu) { - if (ctx == NULL) + if (ctx == NULL || newMtu > MAX_RECORD_SIZE) return BAD_FUNC_ARG; - if (newMtu > MAX_RECORD_SIZE) { - ssl->error = BAD_FUNC_ARG; - return SSL_FAILURE; - } - + ctx->dtlsMtuSz = newMtu; return SSL_SUCCESS; } -int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word32 newMtu) +int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu) { if (ssl == NULL) return BAD_FUNC_ARG; @@ -605,6 +595,7 @@ int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word32 newMtu) return SSL_FAILURE; } + ssl->dtlsMtuSz = newMtu; return SSL_SUCCESS; } @@ -1117,17 +1108,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); @@ -6850,6 +6846,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) { @@ -6919,7 +6930,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 */ @@ -6931,7 +6942,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; @@ -6946,7 +6957,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); @@ -6991,7 +7002,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; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 31cbf32d78..ec72fe6ead 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2752,7 +2752,7 @@ struct WOLFSSL { word32 dtls_expected_rx; wc_dtls_export dtls_export; /* export function for session */ #ifdef WOLFSSL_SCTP - word32 mtu_size; + word16 dtlsMtuSz; #endif /* WOLFSSL_SCTP */ #endif #ifdef WOLFSSL_CALLBACKS diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 7cd34b34f9..4f234b058b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -411,8 +411,8 @@ 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 int); -WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned int); +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*); From bab071f961d7508ab449c7a13e5b3723ac41e7a6 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 24 Aug 2016 18:26:17 -0700 Subject: [PATCH 28/69] 1. Implemented the SCTP MTU size changes for transmit. 2. Simplified the MAX_FRAGMENT size when calling SendData(). --- src/internal.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/internal.c b/src/internal.c index 991c391605..7e619daf9f 100755 --- a/src/internal.c +++ b/src/internal.c @@ -10834,14 +10834,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]; @@ -10849,12 +10845,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; From 6d5df3928ff8fd57bb67e944f19c39c4aebc38ea Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 25 Aug 2016 09:25:12 -0700 Subject: [PATCH 29/69] SCTP-DTLS examples 1. Added the set SCTP mode command to client and server. 2. Added a 4K buffer test case. --- examples/sctp/sctp-client-dtls.c | 20 ++++++++++++++++++++ examples/sctp/sctp-server-dtls.c | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/examples/sctp/sctp-client-dtls.c b/examples/sctp/sctp-client-dtls.c index d90fe2b4b2..f07051795f 100644 --- a/examples/sctp/sctp-client-dtls.c +++ b/examples/sctp/sctp-client-dtls.c @@ -70,6 +70,10 @@ int main() 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"); @@ -95,6 +99,22 @@ int main() 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); diff --git a/examples/sctp/sctp-server-dtls.c b/examples/sctp/sctp-server-dtls.c index 8bf90cda37..7a58bf18e4 100644 --- a/examples/sctp/sctp-server-dtls.c +++ b/examples/sctp/sctp-server-dtls.c @@ -76,6 +76,10 @@ int main() 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"); @@ -105,6 +109,11 @@ int main() } wolfSSL_write(ssl, response, (int)strlen(response)); + unsigned char bigBuf[4096]; + + got = wolfSSL_read(ssl, bigBuf, sizeof(bigBuf)); + wolfSSL_write(ssl, bigBuf, sizeof(bigBuf)); + wolfSSL_shutdown(ssl); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); From 46e92e0211f2b4ff201c08170d9025b2970f6a7d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 25 Aug 2016 22:20:35 -0700 Subject: [PATCH 30/69] DTLS-SCTP example client and server 1. Update the example client and server to test DTLS-SCTP. 2. Modify the test.h functions for setting up connections to allow for a SCTP option. 3. Update other examples to use the new test.h functions. 4. Removed some prototypes in the client header file were some functions that should have been static to the client.c file and made them static. --- examples/client/client.c | 53 ++++++++++++++++++++++---------- examples/client/client.h | 15 --------- examples/echoclient/echoclient.c | 2 +- examples/echoserver/echoserver.c | 4 +-- examples/server/server.c | 36 ++++++++++++++++++---- tests/api.c | 15 +++++---- wolfssl/test.h | 44 ++++++++++++++++---------- 7 files changed, 107 insertions(+), 62 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index f814c0d4e7..67ae69cd87 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -156,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; @@ -180,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) @@ -215,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; @@ -227,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"); } @@ -343,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]; @@ -399,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]; @@ -461,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"); @@ -551,6 +560,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; @@ -640,7 +651,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:ToO:aB:W:E:M:q:")) != -1) { switch (ch) { case '?' : @@ -670,7 +681,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' : @@ -1212,14 +1231,16 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) 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); } @@ -1305,7 +1326,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"); } @@ -1484,7 +1505,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 */ @@ -1498,7 +1519,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) @@ -1507,7 +1528,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"); } 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 6cb836e6a9..1c06efa83b 100644 --- a/examples/echoclient/echoclient.c +++ b/examples/echoclient/echoclient.c @@ -180,7 +180,7 @@ void echoclient_test(void* args) #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) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index d917c946bf..432525806c 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -136,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(); @@ -373,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 } diff --git a/examples/server/server.c b/examples/server/server.c index 74feccc0b7..3dd98554e4 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -219,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"); @@ -275,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; @@ -370,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(); @@ -404,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' : @@ -563,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) @@ -689,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 @@ -821,13 +845,13 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) 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)) { @@ -908,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) { @@ -923,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; @@ -1039,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 */ diff --git a/tests/api.c b/tests/api.c index a249416986..11605d1ce5 100644 --- a/tests/api.c +++ b/tests/api.c @@ -672,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) { @@ -800,7 +800,8 @@ 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; @@ -919,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); } @@ -1051,10 +1052,12 @@ 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)); diff --git a/wolfssl/test.h b/wolfssl/test.h index f23748ee47..c0197d5908 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -564,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"); @@ -628,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'; @@ -649,10 +659,12 @@ 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); + else if (sctp) + *sockfd = socket(AF_INET_V, SOCK_STREAM, 0); else *sockfd = socket(AF_INET_V, SOCK_STREAM, 0); @@ -677,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); @@ -690,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) @@ -757,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) @@ -826,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) \ @@ -879,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); @@ -893,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 */ From aed68e1c691c687ee42ad3f4349d343f427b82a4 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 26 Aug 2016 10:47:01 -0700 Subject: [PATCH 31/69] 1. Needed to tell the client to use sctp. 2. Creating the example sockets needed the IPPROTO type. --- examples/client/client.c | 5 +++++ wolfssl/test.h | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 67ae69cd87..ae61c1a5f1 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1131,6 +1131,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 diff --git a/wolfssl/test.h b/wolfssl/test.h index c0197d5908..51be479e33 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -662,11 +662,11 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, 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, 0); + *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"); From 05a35a8332ea0c4db73c93fa8b6ee8520e32c435 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 26 Aug 2016 20:33:05 -0700 Subject: [PATCH 32/69] fix scan-build warning on the simple SCTP example server --- examples/sctp/sctp-server-dtls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sctp/sctp-server-dtls.c b/examples/sctp/sctp-server-dtls.c index 7a58bf18e4..e64c888db5 100644 --- a/examples/sctp/sctp-server-dtls.c +++ b/examples/sctp/sctp-server-dtls.c @@ -111,7 +111,7 @@ int main() unsigned char bigBuf[4096]; - got = wolfSSL_read(ssl, bigBuf, sizeof(bigBuf)); + wolfSSL_read(ssl, bigBuf, sizeof(bigBuf)); wolfSSL_write(ssl, bigBuf, sizeof(bigBuf)); wolfSSL_shutdown(ssl); From 2ecd80ce2340c046d227839a8828b0ee32e4fd56 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 29 Aug 2016 10:38:06 -0700 Subject: [PATCH 33/69] Added support for static memory with wolfCrypt. Adds new "wc_LoadStaticMemory" function and moves "wolfSSL_init_memory_heap" into wolfCrypt layer. Enhanced wolfCrypt test and benchmark to use the static memory tool if enabled. Added support for static memory with "WOLFSSL_DEBUG_MEMORY" defined. Fixed issue with have-iopool and XMALLOC/XFREE. Added check to prevent using WOLFSSL_STATIC_MEMORY with HAVE_IO_POOL, XMALLOC_USER or NO_WOLFSSL_MEMORY defined. --- examples/server/server.c | 2 +- src/ssl.c | 51 +- wolfcrypt/benchmark/benchmark.c | 51 +- wolfcrypt/src/memory.c | 123 ++++- wolfcrypt/test/test.c | 848 ++++++++++++++++---------------- wolfssl/wolfcrypt/memory.h | 67 +-- wolfssl/wolfcrypt/settings.h | 5 + wolfssl/wolfcrypt/types.h | 46 +- 8 files changed, 655 insertions(+), 538 deletions(-) diff --git a/examples/server/server.c b/examples/server/server.c index 74feccc0b7..792fa5bfbe 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -659,7 +659,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"); diff --git a/src/ssl.c b/src/ssl.c index 2fb0d17ed6..ccda3ef249 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -638,32 +638,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 +658,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 +734,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 +753,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 */ diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index e535d0b728..76ad20797b 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 @@ -85,8 +92,8 @@ #ifdef WOLFSSL_ASYNC_CRYPT #include - static int devId = INVALID_DEVID; #endif +static int devId = INVALID_DEVID; #ifdef HAVE_WNR const char* wnrConfigFile = "wnr-example.conf"; @@ -249,6 +256,20 @@ 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 @@ -1406,7 +1427,7 @@ void bench_rsa(void) #error "need a cert buffer size" #endif /* USE_CERT_BUFFERS */ - if ((ret = wc_InitRsaKey(&rsaKey, 0)) < 0) { + if ((ret = wc_InitRsaKey(&rsaKey, HEAP_HINT)) < 0) { printf("InitRsaKey failed! %d\n", ret); return; } @@ -1440,7 +1461,7 @@ void bench_rsa(void) wc_RsaSetRNG(&rsaKey, &rng); #endif start = current_time(1); - + /* capture resulting encrypt length */ idx = ret; @@ -1509,7 +1530,7 @@ void bench_rsa_async(void) /* 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], 0, devId)) < 0) { + if ((ret = wc_InitRsaKey_ex(&rsaKey[i], HEAP_HINT, devId)) < 0) { goto done; } #ifdef WC_RSA_BLINDING @@ -1538,7 +1559,7 @@ void bench_rsa_async(void) /* 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 && + if (events[evtNum].done || (events[evtNum].pending == 0 && (i + asyncPend) < ntimes)) { /* check for event error */ @@ -1592,7 +1613,7 @@ void bench_rsa_async(void) /* begin private async RSA */ start = current_time(1); - + /* capture resulting encrypt length */ idx = sizeof(enc); /* fixed at 2048 bit */ @@ -1602,7 +1623,7 @@ void bench_rsa_async(void) /* 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 && + if (events[evtNum].done || (events[evtNum].pending == 0 && (i + asyncPend) < ntimes)) { /* check for event error */ @@ -1772,7 +1793,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); } @@ -1788,7 +1809,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); } @@ -2045,7 +2066,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); } @@ -2071,8 +2092,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) { @@ -2158,8 +2179,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); @@ -2449,7 +2470,7 @@ void bench_ed25519KeySign(void) } #elif defined(WOLFSSL_EMBOS) - + #include "RTOS.h" double current_time(int reset) 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/test/test.c b/wolfcrypt/test/test.c index 99354741d6..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 @@ -297,11 +282,22 @@ 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 */ -#if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) - wolfSSL_Debugging_ON(); +#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) @@ -4094,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; @@ -4105,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; } @@ -4156,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; } @@ -4210,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; } @@ -4255,7 +4251,7 @@ 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; } @@ -4284,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; @@ -4300,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; } @@ -4310,17 +4306,17 @@ int rsa_test(void) 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; } @@ -4333,7 +4329,7 @@ int rsa_test(void) } } 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; } @@ -4342,7 +4338,7 @@ int rsa_test(void) 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; @@ -4359,12 +4355,12 @@ int rsa_test(void) } } 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; } @@ -4377,7 +4373,7 @@ int rsa_test(void) } } 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; } @@ -4392,12 +4388,12 @@ int rsa_test(void) } } 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; } @@ -4418,7 +4414,7 @@ int rsa_test(void) } } 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; } @@ -4433,12 +4429,12 @@ int rsa_test(void) } } 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 */ @@ -4455,7 +4451,7 @@ int rsa_test(void) } } 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; } @@ -4470,12 +4466,12 @@ int rsa_test(void) } } 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; } @@ -4491,7 +4487,7 @@ int rsa_test(void) } } 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; } @@ -4506,7 +4502,7 @@ int rsa_test(void) } } 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; @@ -4523,7 +4519,7 @@ int rsa_test(void) } } 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; } @@ -4538,12 +4534,12 @@ int rsa_test(void) } } 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; } @@ -4560,7 +4556,7 @@ int rsa_test(void) } } 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; } @@ -4575,7 +4571,7 @@ int rsa_test(void) } } 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; @@ -4599,7 +4595,7 @@ int rsa_test(void) } } 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; } @@ -4614,12 +4610,12 @@ int rsa_test(void) } } 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; } } @@ -4637,7 +4633,7 @@ int rsa_test(void) } } 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; } @@ -4652,12 +4648,12 @@ int rsa_test(void) } } 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 */ @@ -4676,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; } @@ -4715,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; } @@ -4725,14 +4721,14 @@ int rsa_test(void) 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; } @@ -4751,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; } @@ -4788,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; } @@ -4819,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; @@ -4856,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 */ @@ -4875,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; } @@ -4910,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; } @@ -4945,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); @@ -4959,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; } @@ -4987,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 */ { @@ -5020,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; } @@ -5047,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; } @@ -5083,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; } @@ -5127,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; } @@ -5138,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; } @@ -5153,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; } @@ -5184,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 @@ -5225,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; } @@ -5253,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; } @@ -5281,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; } @@ -5292,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; } @@ -5329,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; } @@ -5368,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; } @@ -5383,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; } @@ -5414,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; } @@ -5451,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; } @@ -5475,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; } @@ -5485,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; } @@ -5495,27 +5491,27 @@ 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; } @@ -5524,16 +5520,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 -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; } @@ -5553,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; } @@ -5600,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; } @@ -5611,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 @@ -5686,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; } @@ -5715,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; } @@ -5762,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; } @@ -5783,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 */ @@ -5807,8 +5803,10 @@ int rsa_test(void) #ifdef WOLFSSL_CERT_EXT wc_FreeRsaKey(&keypub); #endif - - TEST_XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef HAVE_CAVIUM + wc_RsaFreeCavium(&key); +#endif + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRng(&rng); return 0; @@ -5994,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; } @@ -6019,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; } @@ -6047,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; } @@ -6065,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; @@ -6074,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 */ @@ -8391,8 +8389,8 @@ int compress_test(void) byte *c = NULL; byte *d = NULL; - c = TEST_XMALLOC(cSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - d = TEST_XMALLOC(dSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + c = XMALLOC(cSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + d = XMALLOC(dSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); /* follow calloc and initialize to 0 */ XMEMSET(c, 0, cSz); @@ -8415,8 +8413,8 @@ int compress_test(void) if (ret == 0 && XMEMCMP(d, sample_text, dSz)) ret = -303; - if (c) TEST_XFREE(c, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (d) TEST_XFREE(d, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (c) XFREE(c, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (d) XFREE(d, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return ret; } @@ -8450,20 +8448,20 @@ int pkcs7enveloped_test(void) }; /* read client cert and key in DER format */ - cert = (byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + cert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cert == NULL) return -201; - privKey =(byte*)TEST_XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + privKey =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (privKey == NULL) { - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -202; } certFile = fopen(clientCert, "rb"); if (!certFile) { - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); err_sys("can't open ./certs/client-cert.der, " "Please run from wolfSSL home dir", -42); return -42; @@ -8474,8 +8472,8 @@ int pkcs7enveloped_test(void) keyFile = fopen(clientKey, "rb"); if (!keyFile) { - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -43); return -43; @@ -8496,8 +8494,8 @@ int pkcs7enveloped_test(void) envelopedSz = wc_PKCS7_EncodeEnvelopedData(&pkcs7, enveloped, sizeof(enveloped)); if (envelopedSz <= 0) { - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -203; } @@ -8505,31 +8503,31 @@ int pkcs7enveloped_test(void) decodedSz = wc_PKCS7_DecodeEnvelopedData(&pkcs7, enveloped, envelopedSz, decoded, sizeof(decoded)); if (decodedSz <= 0) { - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -204; } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -205; } /* output pkcs7 envelopedData for external testing */ pkcs7File = fopen(pkcs7OutFile, "wb"); if (!pkcs7File) { - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return -206; } ret = (int)fwrite(enveloped, envelopedSz, 1, pkcs7File); fclose(pkcs7File); - TEST_XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - TEST_XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&pkcs7); if (ret > 0) @@ -8577,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; @@ -8607,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; @@ -8619,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; } @@ -8630,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; } @@ -8656,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); @@ -8670,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; } @@ -8682,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; } @@ -8703,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/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/settings.h b/wolfssl/wolfcrypt/settings.h index 55de9030f6..880109e72e 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1251,6 +1251,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 @@ -1258,6 +1261,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/types.h b/wolfssl/wolfcrypt/types.h index b6e91b8aaa..fee056a907 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -171,24 +171,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 +194,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 From 6a704035476ccabca21b18e2f82024f7177f573c Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 29 Aug 2016 11:01:16 -0700 Subject: [PATCH 34/69] Fix for "not used" devId in benchmark. --- wolfcrypt/benchmark/benchmark.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 76ad20797b..091b3e1e65 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -93,7 +93,9 @@ #ifdef WOLFSSL_ASYNC_CRYPT #include #endif -static int devId = INVALID_DEVID; +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(HAVE_ECC) + static int devId = INVALID_DEVID; +#endif #ifdef HAVE_WNR const char* wnrConfigFile = "wnr-example.conf"; From ddff90ea2604c1a03a7dd8ebd97a3f3a4d711336 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 29 Aug 2016 11:50:43 -0700 Subject: [PATCH 35/69] Fix duplicate declaration of "wolfSSL_init_memory_heap" (errors after rebase). --- wolfssl/internal.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 3a3e006356..9ff1241ddd 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1897,10 +1897,6 @@ WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name); #endif /* HAVE_QSH */ -#ifdef WOLFSSL_STATIC_MEMORY -WOLFSSL_LOCAL int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap); -#endif - /* wolfSSL context type */ struct WOLFSSL_CTX { WOLFSSL_METHOD* method; From e0a035a0631ca82b73c91e5a1ef6773bc2e3f1f6 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 29 Aug 2016 15:15:59 -0700 Subject: [PATCH 36/69] DTLS-SCTP Tests 1. Added a check to configure for SCTP availablility. 2. Added DTLS-SCTP to the cipher suite test. --- configure.ac | 14 + tests/suites.c | 10 + tests/test-sctp.conf | 1111 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1135 insertions(+) create mode 100644 tests/test-sctp.conf diff --git a/configure.ac b/configure.ac index 3f6b858fa3..2908f99e70 100644 --- a/configure.ac +++ b/configure.ac @@ -229,6 +229,20 @@ AC_ARG_ENABLE([sctp], 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], diff --git a/tests/suites.c b/tests/suites.c index c3864bd89a..bc700d00ed 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -513,6 +513,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 + From 963b9d4c4df692daad93917ef3aa14ffdbfb545e Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 1 Sep 2016 09:58:34 -0700 Subject: [PATCH 37/69] OCSP Fixes 1. When using Cert Manager OCSP lookup, the issuer key hash wasn't being set correctly. This could lead to unknown responses from lookup. 2. Default OCSP lookup callback could get blocked waiting for server to close socket. --- src/io.c | 4 ++-- src/ssl.c | 4 ++-- wolfcrypt/src/asn.c | 37 ++++++++++++++++++++----------------- wolfssl/wolfcrypt/asn.h | 6 ++++-- 4 files changed, 28 insertions(+), 23 deletions(-) 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/ssl.c b/src/ssl.c index 61bd2d4f8a..391488162b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4570,7 +4570,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) { @@ -5046,7 +5046,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) { diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 884e66ae50..545b32d951 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5074,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) @@ -5099,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 */ 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 From 41912b92c6296e54e51cf4b173f92441e4589a10 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 22 Jul 2016 15:49:15 +0000 Subject: [PATCH 38/69] initial ARMv8 instructions --- configure.ac | 19 + src/include.am | 7 +- wolfcrypt/benchmark/benchmark.c | 29 ++ wolfcrypt/src/aes.c | 472 +++++++++++++++++++- wolfcrypt/src/include.am | 3 +- wolfcrypt/src/port/arm/armv8-sha256.c | 608 ++++++++++++++++++++++++++ wolfssl/wolfcrypt/sha256.h | 20 +- 7 files changed, 1151 insertions(+), 7 deletions(-) create mode 100644 wolfcrypt/src/port/arm/armv8-sha256.c diff --git a/configure.ac b/configure.ac index 2908f99e70..bc1be8374b 100644 --- a/configure.ac +++ b/configure.ac @@ -542,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)])], @@ -3213,6 +3231,7 @@ 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/src/include.am b/src/include.am index 8dc391ce85..9e874eaf75 100644 --- a/src/include.am +++ b/src/include.am @@ -62,9 +62,14 @@ 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 diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 091b3e1e65..c0ea08f0a8 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -110,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 @@ -277,6 +305,7 @@ int benchmark_test(void *args) #endif wolfCrypt_Init(); + INIT_CYCLE_COUNTER #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) wolfSSL_Debugging_ON(); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index e13ae49a2d..9eaaa9b542 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -344,7 +344,160 @@ void wc_AesAsyncFree(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; + byte out[AES_BLOCK_SIZE]; + byte* output = out; + byte* input = (byte*)inBlock; + + /* + AESE exor's input with round key + shift rows of exor'ed result + sub bytes for shifted rows + */ + + __asm__ __volatile__ ( + "LD1 {v0.16b}, [%[CtrIn]], #16 \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" (output), "=r" (keyPt), "=r" (rounds) + :[Key] "1" (keyPt), [R] "2" (rounds), [CtrIn] "r" (input), "0" (output) + : "cc", "memory", "w12" + ); + + XMEMCPY(outBlock, out, AES_BLOCK_SIZE); + + 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; + byte out[AES_BLOCK_SIZE]; + byte* output = out; + byte* input = (byte*)inBlock; + + /* + AESE exor's input with round key + shift rows of exor'ed result + sub bytes for shifted rows + */ + + __asm__ __volatile__ ( + "LD1 {v0.16b}, [%[CtrIn]], #16 \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" (output), "=r" (keyPt), "=r" (rounds), "=r" (input) + :[Key] "1" (keyPt), [R] "2" (rounds), [CtrIn] "3" (input), "0" (output) + : "cc", "memory", "w12" + ); + + XMEMCPY(outBlock, out, AES_BLOCK_SIZE); + + return 0; +} + #endif /* HAVE_AES_DECRYPT */ #else /* using wolfCrypt software AES implementation */ @@ -1533,7 +1686,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 */ @@ -1678,6 +1830,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) @@ -2859,7 +3201,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) { @@ -2943,6 +3285,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 */ @@ -3379,8 +3735,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]; diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 983b63b4f3..b1fae4d3e2 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -44,7 +44,8 @@ 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 diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c new file mode 100644 index 0000000000..5a7a9d2e42 --- /dev/null +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -0,0 +1,608 @@ +/* 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) +{ + + /* do block size increments */ + byte* local = (byte*)sha256->buffer; + + while (len) { + word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); + XMEMCPY(&local[sha256->buffLen], data, add); + + sha256->buffLen += add; + data += add; + len -= add; + + if (sha256->buffLen == SHA256_BLOCK_SIZE) { + word32* Kpt = (word32*)K; + word32* bufferPt = sha256->buffer; + word32* digestPt = sha256->digest; + + __asm__ volatile ( + "#load in message and schedual updates \n" + "LD1 {v4.16b-v7.16b}, [%[buffer]] \n" + "MOV v0.16b, v4.16b \n" + "MOV v1.16b, v5.16b \n" + "REV32 v0.16b, v0.16b \n" + "MOV v2.16b, v6.16b \n" + "REV32 v1.16b, v1.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" + "SHA256SU0 v4.4s, v1.4s \n" + "SHA256SU1 v4.4s, v2.4s, v3.4s \n" + "MOV v6.16b, v2.16b \n" + "SHA256SU0 v5.4s, v2.4s \n" + "SHA256SU1 v5.4s, v3.4s, v4.4s \n" + "MOV v7.16b, v3.16b \n" + "SHA256SU0 v6.4s, v3.4s \n" + "SHA256SU1 v6.4s, v4.4s, v5.4s \n" + "MOV v8.16b, v4.16b \n" + "SHA256SU0 v7.4s, v4.4s \n" + "SHA256SU1 v7.4s, v5.4s, v6.4s \n" + "MOV v9.16b, v5.16b \n" + "SHA256SU0 v8.4s, v5.4s \n" + "SHA256SU1 v8.4s, v6.4s, v7.4s \n" + "MOV v10.16b, v6.16b \n" + "SHA256SU0 v9.4s, v6.4s \n" + "SHA256SU1 v9.4s, v7.4s, v8.4s \n" + "MOV v11.16b, v7.16b \n" + "SHA256SU0 v10.4s, v7.4s \n" + "SHA256SU1 v10.4s, v8.4s, v9.4s \n" + "MOV v12.16b, v8.16b \n" + "SHA256SU0 v11.4s, v8.4s \n" + "SHA256SU1 v11.4s, v9.4s, v10.4s \n" + "MOV v13.16b, v9.16b \n" + "SHA256SU0 v12.4s, v9.4s \n" + "SHA256SU1 v12.4s, v10.4s, v11.4s \n" + "MOV v14.16b, v10.16b \n" + "SHA256SU0 v13.4s, v10.4s \n" + "SHA256SU1 v13.4s, v11.4s, v12.4s \n" + "MOV v15.16b, v11.16b \n" + "SHA256SU0 v14.4s, v11.4s \n" + "SHA256SU1 v14.4s, v12.4s, v13.4s \n" + "SHA256SU0 v15.4s, v12.4s \n" + "SHA256SU1 v15.4s, v13.4s, v14.4s \n" + + "#Add K values to message \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v0.4s, v0.4s, v16.4s \n" + "ADD v1.4s, v1.4s, v17.4s \n" + "ADD v2.4s, v2.4s, v18.4s \n" + "ADD v3.4s, v3.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v4.4s, v4.4s, v16.4s \n" + "ADD v5.4s, v5.4s, v17.4s \n" + "ADD v6.4s, v6.4s, v18.4s \n" + "ADD v7.4s, v7.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v8.4s, v8.4s, v16.4s \n" + "ADD v9.4s, v9.4s, v17.4s \n" + "ADD v10.4s, v10.4s, v18.4s \n" + "ADD v11.4s, v11.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]] \n" + "ADD v12.4s, v12.4s, v16.4s \n" + "ADD v13.4s, v13.4s, v17.4s \n" + "LD1 {v20.4s-v21.4s}, [%[digest]] \n" + "ADD v14.4s, v14.4s, v18.4s \n" + "ADD v15.4s, v15.4s, v19.4s \n" + + "#SHA256 operation on updated message \n" + "MOV v16.16b, v20.16b \n" + "MOV v17.16b, v21.16b \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v0.4s \n" + "SHA256H2 q17, q18, v0.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v1.4s \n" + "SHA256H2 q17, q18, v1.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v2.4s \n" + "SHA256H2 q17, q18, v2.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v3.4s \n" + "SHA256H2 q17, q18, v3.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v4.4s \n" + "SHA256H2 q17, q18, v4.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v5.4s \n" + "SHA256H2 q17, q18, v5.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v6.4s \n" + "SHA256H2 q17, q18, v6.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v7.4s \n" + "SHA256H2 q17, q18, v7.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v8.4s \n" + "SHA256H2 q17, q18, v8.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v9.4s \n" + "SHA256H2 q17, q18, v9.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v10.4s \n" + "SHA256H2 q17, q18, v10.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v11.4s \n" + "SHA256H2 q17, q18, v11.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v12.4s \n" + "SHA256H2 q17, q18, v12.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v13.4s \n" + "SHA256H2 q17, q18, v13.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v14.4s \n" + "SHA256H2 q17, q18, v14.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" + : "=r" (Kpt), [out] "=r" (digestPt), "=r" (bufferPt) + : [k] "0" (Kpt), [digest] "1" (digestPt), [buffer] "2" (bufferPt) + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", + "v15", "v16", "v17", "v18", "v19", "v20", "v21" + ); + + AddLength(sha256, SHA256_BLOCK_SIZE); + sha256->buffLen = 0; + } + } + + return 0; +} + + +int wc_Sha256Final(Sha256* sha256, byte* hash) +{ + byte* local = (byte*)sha256->buffer; + word32* Kpt = (word32*)K; + word32* bufferPt = sha256->buffer; + word32* digestPt = sha256->digest; + word32* hashPt = (word32*)hash; + + 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; + bufferPt = sha256->buffer; + digestPt = sha256->digest; + Kpt = (word32*)K; + __asm__ volatile ( + "#load in message and schedual updates \n" + "LD1 {v4.16b-v7.16b}, [%[buffer]] \n" + "MOV v0.16b, v4.16b \n" + "MOV v1.16b, v5.16b \n" + "REV32 v0.16b, v0.16b \n" + "MOV v2.16b, v6.16b \n" + "REV32 v1.16b, v1.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" + "SHA256SU0 v4.4s, v1.4s \n" + "SHA256SU1 v4.4s, v2.4s, v3.4s \n" + "MOV v6.16b, v2.16b \n" + "SHA256SU0 v5.4s, v2.4s \n" + "SHA256SU1 v5.4s, v3.4s, v4.4s \n" + "MOV v7.16b, v3.16b \n" + "SHA256SU0 v6.4s, v3.4s \n" + "SHA256SU1 v6.4s, v4.4s, v5.4s \n" + "MOV v8.16b, v4.16b \n" + "SHA256SU0 v7.4s, v4.4s \n" + "SHA256SU1 v7.4s, v5.4s, v6.4s \n" + "MOV v9.16b, v5.16b \n" + "SHA256SU0 v8.4s, v5.4s \n" + "SHA256SU1 v8.4s, v6.4s, v7.4s \n" + "MOV v10.16b, v6.16b \n" + "SHA256SU0 v9.4s, v6.4s \n" + "SHA256SU1 v9.4s, v7.4s, v8.4s \n" + "MOV v11.16b, v7.16b \n" + "SHA256SU0 v10.4s, v7.4s \n" + "SHA256SU1 v10.4s, v8.4s, v9.4s \n" + "MOV v12.16b, v8.16b \n" + "SHA256SU0 v11.4s, v8.4s \n" + "SHA256SU1 v11.4s, v9.4s, v10.4s \n" + "MOV v13.16b, v9.16b \n" + "SHA256SU0 v12.4s, v9.4s \n" + "SHA256SU1 v12.4s, v10.4s, v11.4s \n" + "MOV v14.16b, v10.16b \n" + "SHA256SU0 v13.4s, v10.4s \n" + "SHA256SU1 v13.4s, v11.4s, v12.4s \n" + "MOV v15.16b, v11.16b \n" + "SHA256SU0 v14.4s, v11.4s \n" + "SHA256SU1 v14.4s, v12.4s, v13.4s \n" + "SHA256SU0 v15.4s, v12.4s \n" + "SHA256SU1 v15.4s, v13.4s, v14.4s \n" + + "#Add K values to message \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v0.4s, v0.4s, v16.4s \n" + "ADD v1.4s, v1.4s, v17.4s \n" + "ADD v2.4s, v2.4s, v18.4s \n" + "ADD v3.4s, v3.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v4.4s, v4.4s, v16.4s \n" + "ADD v5.4s, v5.4s, v17.4s \n" + "ADD v6.4s, v6.4s, v18.4s \n" + "ADD v7.4s, v7.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v8.4s, v8.4s, v16.4s \n" + "ADD v9.4s, v9.4s, v17.4s \n" + "ADD v10.4s, v10.4s, v18.4s \n" + "ADD v11.4s, v11.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]] \n" + "ADD v12.4s, v12.4s, v16.4s \n" + "ADD v13.4s, v13.4s, v17.4s \n" + "LD1 {v20.4s-v21.4s}, [%[digest]] \n" + "ADD v14.4s, v14.4s, v18.4s \n" + "ADD v15.4s, v15.4s, v19.4s \n" + + "#SHA256 operation on updated message \n" + "MOV v16.16b, v20.16b \n" + "MOV v17.16b, v21.16b \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v0.4s \n" + "SHA256H2 q17, q18, v0.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v1.4s \n" + "SHA256H2 q17, q18, v1.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v2.4s \n" + "SHA256H2 q17, q18, v2.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v3.4s \n" + "SHA256H2 q17, q18, v3.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v4.4s \n" + "SHA256H2 q17, q18, v4.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v5.4s \n" + "SHA256H2 q17, q18, v5.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v6.4s \n" + "SHA256H2 q17, q18, v6.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v7.4s \n" + "SHA256H2 q17, q18, v7.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v8.4s \n" + "SHA256H2 q17, q18, v8.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v9.4s \n" + "SHA256H2 q17, q18, v9.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v10.4s \n" + "SHA256H2 q17, q18, v10.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v11.4s \n" + "SHA256H2 q17, q18, v11.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v12.4s \n" + "SHA256H2 q17, q18, v12.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v13.4s \n" + "SHA256H2 q17, q18, v13.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v14.4s \n" + "SHA256H2 q17, q18, v14.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" + : "=r" (Kpt), [out] "=r" (digestPt), "=r" (bufferPt) + : [k] "0" (Kpt), [digest] "1" (digestPt), [buffer] "2" (bufferPt) + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", + "v15", "v16", "v17", "v18", "v19", "v20", "v21" + ); + + 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) + bufferPt = sha256->buffer; + __asm__ volatile ( + "LD1 {v0.16b}, [%[in]] \n" + "REV32 v0.16b, v0.16b \n" + "ST1 {v0.16b}, [%[out]], #16 \n" + "LD1 {v0.16b}, [%[in]] \n" + "REV32 v0.16b, v0.16b \n" + "ST1 {v0.16b}, [%[out]], #16 \n" + "LD1 {v0.16b}, [%[in]] \n" + "REV32 v0.16b, v0.16b \n" + "ST1 {v0.16b}, [%[out]], #16 \n" + "LD1 {v0.16b}, [%[in]] \n" + "REV32 v0.16b, v0.16b \n" + "ST1 {v0.16b}, [%[out]] \n" + : [out] "=r" (bufferPt) + : [in] "0" (bufferPt) + : "cc" + ); + #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)); + + bufferPt = sha256->buffer; + digestPt = sha256->digest; + Kpt = (word32*)K; + __asm__ volatile ( + "#load in message and schedual updates \n" + "LD1 {v4.16b-v7.16b}, [%[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" + "SHA256SU0 v4.4s, v1.4s \n" + "SHA256SU1 v4.4s, v2.4s, v3.4s \n" + "MOV v6.16b, v2.16b \n" + "SHA256SU0 v5.4s, v2.4s \n" + "SHA256SU1 v5.4s, v3.4s, v4.4s \n" + "MOV v7.16b, v3.16b \n" + "SHA256SU0 v6.4s, v3.4s \n" + "SHA256SU1 v6.4s, v4.4s, v5.4s \n" + "MOV v8.16b, v4.16b \n" + "SHA256SU0 v7.4s, v4.4s \n" + "SHA256SU1 v7.4s, v5.4s, v6.4s \n" + "MOV v9.16b, v5.16b \n" + "SHA256SU0 v8.4s, v5.4s \n" + "SHA256SU1 v8.4s, v6.4s, v7.4s \n" + "MOV v10.16b, v6.16b \n" + "SHA256SU0 v9.4s, v6.4s \n" + "SHA256SU1 v9.4s, v7.4s, v8.4s \n" + "MOV v11.16b, v7.16b \n" + "SHA256SU0 v10.4s, v7.4s \n" + "SHA256SU1 v10.4s, v8.4s, v9.4s \n" + "MOV v12.16b, v8.16b \n" + "SHA256SU0 v11.4s, v8.4s \n" + "SHA256SU1 v11.4s, v9.4s, v10.4s \n" + "MOV v13.16b, v9.16b \n" + "SHA256SU0 v12.4s, v9.4s \n" + "SHA256SU1 v12.4s, v10.4s, v11.4s \n" + "MOV v14.16b, v10.16b \n" + "SHA256SU0 v13.4s, v10.4s \n" + "SHA256SU1 v13.4s, v11.4s, v12.4s \n" + "MOV v15.16b, v11.16b \n" + "SHA256SU0 v14.4s, v11.4s \n" + "SHA256SU1 v14.4s, v12.4s, v13.4s \n" + "SHA256SU0 v15.4s, v12.4s \n" + "SHA256SU1 v15.4s, v13.4s, v14.4s \n" + + "#Add K values to message \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v0.4s, v0.4s, v16.4s \n" + "ADD v1.4s, v1.4s, v17.4s \n" + "ADD v2.4s, v2.4s, v18.4s \n" + "ADD v3.4s, v3.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v4.4s, v4.4s, v16.4s \n" + "ADD v5.4s, v5.4s, v17.4s \n" + "ADD v6.4s, v6.4s, v18.4s \n" + "ADD v7.4s, v7.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" + "ADD v8.4s, v8.4s, v16.4s \n" + "ADD v9.4s, v9.4s, v17.4s \n" + "ADD v10.4s, v10.4s, v18.4s \n" + "ADD v11.4s, v11.4s, v19.4s \n" + "LD1 {v16.16b-v19.16b}, [%[k]] \n" + "ADD v12.4s, v12.4s, v16.4s \n" + "ADD v13.4s, v13.4s, v17.4s \n" + "LD1 {v20.4s-v21.4s}, [%[digest]] \n" + "ADD v14.4s, v14.4s, v18.4s \n" + "ADD v15.4s, v15.4s, v19.4s \n" + + "#SHA256 operation on updated message \n" + "MOV v16.16b, v20.16b \n" + "MOV v17.16b, v21.16b \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v0.4s \n" + "SHA256H2 q17, q18, v0.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v1.4s \n" + "SHA256H2 q17, q18, v1.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v2.4s \n" + "SHA256H2 q17, q18, v2.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v3.4s \n" + "SHA256H2 q17, q18, v3.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v4.4s \n" + "SHA256H2 q17, q18, v4.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v5.4s \n" + "SHA256H2 q17, q18, v5.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v6.4s \n" + "SHA256H2 q17, q18, v6.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v7.4s \n" + "SHA256H2 q17, q18, v7.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v8.4s \n" + "SHA256H2 q17, q18, v8.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v9.4s \n" + "SHA256H2 q17, q18, v9.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v10.4s \n" + "SHA256H2 q17, q18, v10.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v11.4s \n" + "SHA256H2 q17, q18, v11.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v12.4s \n" + "SHA256H2 q17, q18, v12.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v13.4s \n" + "SHA256H2 q17, q18, v13.4s \n" + "MOV v18.16b, v16.16b \n" + "SHA256H q16, q17, v14.4s \n" + "SHA256H2 q17, q18, v14.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" + + "#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" + : "=r" (Kpt), [out] "=r" (digestPt), "=r" (bufferPt), + [hashOut] "=r" (hashPt) + : [k] "0" (Kpt), [digest] "1" (digestPt), [buffer] "2" (bufferPt), "3" (hashPt) + : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", + "v15", "v16", "v17", "v18", "v19", "v20", "v21" + ); + + return wc_InitSha256(sha256); /* reset state */ +} + +#endif /* NO_SHA256 and WOLFSSL_ARMASM */ + diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 93b515ee37..faaa4a196a 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -54,13 +54,29 @@ enum { #ifndef WOLFSSL_TI_HASH +#ifdef WOLFSSL_ARMASM /* slight performance increase with aligned memory */ +#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 /* not using ARM ASM*/ + #define ALIGN16 +#endif /* WOLFSSL_ARMASM */ + /* Sha256 digest */ 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 From 5bf880665586a580d7adaec25780f85489f99a43 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 1 Sep 2016 15:05:27 -0600 Subject: [PATCH 39/69] add wc_Sha384/512GetHash() functions --- wolfcrypt/src/hash.c | 30 ++++++++++++++++++++++++++++++ wolfssl/wolfcrypt/hash.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 28d04e76b0..7cda03024d 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -324,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; @@ -357,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/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index a2d2eca920..1296c56f57 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -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) */ From e4f527a3327cfebc9fa712a97da136a89624cc7e Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 1 Sep 2016 15:12:54 -0600 Subject: [PATCH 40/69] initial extended master secret support --- configure.ac | 16 ++++- src/internal.c | 14 +++++ src/ssl.c | 23 +++++++ src/tls.c | 144 +++++++++++++++++++++++++++++++++++++++++--- wolfssl/error-ssl.h | 1 + wolfssl/internal.h | 14 +++++ wolfssl/ssl.h | 16 +++++ 7 files changed, 217 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 2908f99e70..853e71a0ba 100644 --- a/configure.ac +++ b/configure.ac @@ -1957,6 +1957,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: disabled)])], + [ ENABLED_EXTENDED_MASTER=$enableval ], + [ ENABLED_EXTENDED_MASTER=no ] + ) + +if test "x$ENABLED_EXTENDED_MASTER" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_EXTENDED_MASTER" +fi + # TLS Extensions AC_ARG_ENABLE([tlsx], [ --enable-tlsx Enable all TLS Extensions (default: disabled)], @@ -1971,7 +1983,8 @@ then ENABLED_TRUNCATED_HMAC=yes ENABLED_SUPPORTED_CURVES=yes ENABLED_ALPN=yes - AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN" + ENABLED_EXTENDED_MASTER=yes + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN -DHAVE_EXTENDED_MASTER" fi # PKCS7 @@ -3199,6 +3212,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" diff --git a/src/internal.c b/src/internal.c index 7e619daf9f..e9556a1424 100755 --- a/src/internal.c +++ b/src/internal.c @@ -11432,6 +11432,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"; } @@ -18185,6 +18188,17 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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) { + ssl->options.resuming = 0; + } + /* if old sess used EMS, but new doesn't, MUST abort */ + else if (session->haveEMS && !ssl->options.haveEMS) { + return EXT_MASTER_SECRET_NEEDED_E; + } + } else { if (MatchSuite(ssl, &clSuites) < 0) { WOLFSSL_MSG("Unsupported cipher suite, ClientHello"); diff --git a/src/ssl.c b/src/ssl.c index 61bd2d4f8a..2e99b5b6ec 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1749,6 +1749,28 @@ WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl, } #endif +#ifdef HAVE_EXTENDED_MASTER +#ifndef NO_WOLFSSL_CLIENT + +int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + return TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap); +} + +int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx) +{ + if (ctx == NULL) + return BAD_FUNC_ARG; + + return TLSX_UseExtendedMasterSecret(&ctx->extensions, ctx->heap); +} + +#endif /* NO_WOLFSSL_CLIENT */ +#endif /* HAVE_EXTENDED_MASTER */ + #ifndef WOLFSSL_LEANPSK int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags) @@ -7847,6 +7869,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; diff --git a/src/tls.c b/src/tls.c index e13ae88a1e..4e6511d384 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, @@ -3888,6 +3942,58 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, #endif /* HAVE_QSH */ +/******************************************************************************/ +/* TLS Extended Master Secret */ +/******************************************************************************/ + +#ifdef HAVE_EXTENDED_MASTER + +static int TLSX_EMS_Parse(WOLFSSL* ssl, byte* input, word16 length, + byte isRequest) +{ + (void)isRequest; + + if (length != 0 || input == NULL) + return BUFFER_ERROR; + +#ifndef NO_WOLFSSL_SERVER + if (isRequest) { + int r = TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap); + + if (r != SSL_SUCCESS) + return r; /* throw error */ + + TLSX_SetResponse(ssl, TLSX_EXTENDED_MASTER_SECRET); + } +#endif + + ssl->options.haveEMS = 1; + + return 0; +} + +int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap) +{ + int ret = 0; + + if (extensions == NULL) + return BAD_FUNC_ARG; + + if ((ret = TLSX_Push(extensions, TLSX_EXTENDED_MASTER_SECRET, NULL, + heap)) != 0) + return ret; + + return SSL_SUCCESS; +} + +#define EMS_PARSE TLSX_EMS_Parse + +#else + +#define EMS_PARSE(a, b, c, d) 0 + +#endif /* HAVE_EXTENDED_MASTER */ + /******************************************************************************/ /* TLS Extensions Framework */ /******************************************************************************/ @@ -3937,6 +4043,10 @@ void TLSX_FreeAll(TLSX* list, void* heap) CSR2_FREE_ALL(extension->data, heap); break; + case TLSX_EXTENDED_MASTER_SECRET: + /* Nothing to do. */ + break; + case TLSX_RENEGOTIATION_INFO: SCR_FREE_ALL(extension->data, heap); break; @@ -4014,6 +4124,10 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) length += CSR2_GET_SIZE(extension->data, isRequest); break; + case TLSX_EXTENDED_MASTER_SECRET: + /* always empty. */ + break; + case TLSX_RENEGOTIATION_INFO: length += SCR_GET_SIZE(extension->data, isRequest); break; @@ -4093,6 +4207,10 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, isRequest); break; + case TLSX_EXTENDED_MASTER_SECRET: + /* always empty. */ + break; + case TLSX_RENEGOTIATION_INFO: offset += SCR_WRITE(extension->data, output + offset, isRequest); @@ -4606,6 +4724,12 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, ret = CSR2_PARSE(ssl, input + offset, size, isRequest); break; + case TLSX_EXTENDED_MASTER_SECRET: + WOLFSSL_MSG("Extended Master Secret extension received"); + + ret = EMS_PARSE(ssl, input + offset, size, isRequest); + break; + case TLSX_RENEGOTIATION_INFO: WOLFSSL_MSG("Secure Renegotiation extension received"); diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index bdf8f5bab0..f42afc263f 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -149,6 +149,7 @@ 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 */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c79dcdf0f0..49ca058210 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -963,6 +963,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 */ @@ -1644,6 +1645,7 @@ typedef enum { TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */ TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */ TLSX_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stapling v2 */ + TLSX_EXTENDED_MASTER_SECRET = 0x0017, TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */ TLSX_SESSION_TICKET = 0x0023, TLSX_RENEGOTIATION_INFO = 0xff01 @@ -1897,6 +1899,14 @@ WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name); #endif /* HAVE_QSH */ +/* TLS Extended Master Secret, RFC 7627 */ +#ifdef HAVE_EXTENDED_MASTER + +WOLFSSL_LOCAL int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap); + +#endif + + /* wolfSSL context type */ struct WOLFSSL_CTX { WOLFSSL_METHOD* method; @@ -2225,6 +2235,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 */ @@ -2409,6 +2420,7 @@ typedef struct Options { 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 */ @@ -3028,6 +3040,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); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 4f234b058b..be86237ea5 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1704,6 +1704,16 @@ WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name); #endif #endif +/* TLS Extended Master Secret Extension */ +#ifdef HAVE_EXTENDED_MASTER +#ifndef NO_WOLFSSL_CLIENT + +WOLFSSL_API int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx); + +#endif /* NO_WOLFSSL_CLIENT */ +#endif /* HAVE_EXTENDED_MASTER */ + #define WOLFSSL_CRL_MONITOR 0x01 /* monitor this dir flag */ #define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */ @@ -1725,6 +1735,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, From 88fab67804bbe507d246e1cc46a161f59005e9ae Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 1 Sep 2016 15:15:17 -0600 Subject: [PATCH 41/69] add extended master unit tests --- tests/api.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/api.c b/tests/api.c index 11605d1ce5..ef8f982f2f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1927,6 +1927,28 @@ static void test_wolfSSL_UseALPN(void) #endif } +static void test_wolfSSL_UseExtendedMasterSecret(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_UseExtendedMasterSecret(NULL)); + AssertIntNE(SSL_SUCCESS, wolfSSL_UseExtendedMasterSecret(NULL)); + + /* success cases */ + AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseExtendedMasterSecret(ctx)); + AssertIntEQ(SSL_SUCCESS, wolfSSL_UseExtendedMasterSecret(ssl)); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); +#endif +} + /*----------------------------------------------------------------------------* | X509 Tests *----------------------------------------------------------------------------*/ @@ -2129,6 +2151,7 @@ void ApiTest(void) test_wolfSSL_UseTruncatedHMAC(); test_wolfSSL_UseSupportedCurve(); test_wolfSSL_UseALPN(); + test_wolfSSL_UseExtendedMasterSecret(); /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); From 0f0e0ca9a5b2712a1e08b354a2d753695a387f8e Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 1 Sep 2016 15:17:46 -0600 Subject: [PATCH 42/69] add extended master to example client --- examples/client/client.c | 45 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/examples/client/client.c b/examples/client/client.c index ae61c1a5f1..2129f02476 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -494,6 +494,9 @@ static void Usage(void) #ifdef HAVE_TRUNCATED_HMAC printf("-T Use Truncated HMAC\n"); #endif +#ifdef HAVE_EXTENDED_MASTER + printf("-n Use 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"); @@ -609,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 extMasterSecret = 0; +#endif #ifdef HAVE_OCSP @@ -651,7 +657,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef WOLFSSL_VXWORKS while ((ch = mygetopt(argc, argv, - "?gdeDuGsmNrwRitfxXUPCVh: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 '?' : @@ -857,6 +863,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif break; + case 'n' : + #ifdef HAVE_EXTENDED_MASTER + extMasterSecret = 1; + #endif + break; + case 'W' : #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) @@ -1233,6 +1245,11 @@ 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 (extMasterSecret) + if (wolfSSL_CTX_UseExtendedMasterSecret(ctx) != SSL_SUCCESS) + err_sys("UseExtendedMasterSecret failed"); +#endif if (benchmark) { ((func_args*)args)->return_code = @@ -1555,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) { From 8e4ccd355cab105ceb8505592327e515fba60927 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 1 Sep 2016 21:24:03 +0000 Subject: [PATCH 43/69] refactor ALIGN16 macro to types.h --- wolfssl/wolfcrypt/aes.h | 15 --------------- wolfssl/wolfcrypt/sha256.h | 16 ---------------- wolfssl/wolfcrypt/types.h | 20 ++++++++++++++++++++ 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 8d91f43673..c812741eb2 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -46,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 diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index faaa4a196a..503db7f2a9 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -54,22 +54,6 @@ enum { #ifndef WOLFSSL_TI_HASH -#ifdef WOLFSSL_ARMASM /* slight performance increase with aligned memory */ -#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 /* not using ARM ASM*/ - #define ALIGN16 -#endif /* WOLFSSL_ARMASM */ - /* Sha256 digest */ typedef struct Sha256 { word32 buffLen; /* in bytes */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index fee056a907..d674536017 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -386,6 +386,26 @@ #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" */ #endif From 09b29cb1d45a074a518cc9386680578a5685fcdb Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Sat, 3 Sep 2016 03:49:20 +0000 Subject: [PATCH 44/69] ARMv8 AES: remove extra memcpy during encrypt/decrypt --- wolfcrypt/src/aes.c | 83 +++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 9eaaa9b542..501bd430ec 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -347,12 +347,8 @@ void wc_AesAsyncFree(Aes* aes) #elif defined(WOLFSSL_ARMASM) static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) { - byte* keyPt = (byte*)aes->key; + byte* keyPt = (byte*)aes->key; word32 rounds = aes->rounds; - byte out[AES_BLOCK_SIZE]; - byte* output = out; - byte* input = (byte*)inBlock; - /* AESE exor's input with round key @@ -361,7 +357,7 @@ void wc_AesAsyncFree(Aes* aes) */ __asm__ __volatile__ ( - "LD1 {v0.16b}, [%[CtrIn]], #16 \n" + "LD1 {v0.16b}, [%[CtrIn]] \n" "LD1 {v1.16b-v4.16b}, [%[Key]], #64 \n" "AESE v0.16b, v1.16b \n" @@ -386,12 +382,12 @@ void wc_AesAsyncFree(Aes* aes) "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" + "AESE v0.16b, v2.16b \n" "#subtract rounds done so far and see if should continue\n" - "MOV w12, %w[R] \n" + "MOV w12, %w[R] \n" "SUB w12, w12, #10 \n" - "CBZ w12, final \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" @@ -399,7 +395,7 @@ void wc_AesAsyncFree(Aes* aes) "AESE v0.16b, v2.16b \n" "SUB w12, w12, #2 \n" - "CBZ w12, final \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" @@ -408,27 +404,24 @@ void wc_AesAsyncFree(Aes* aes) "#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" + "LD1 {v1.16b}, [%[Key]], #16 \n" + "EOR v0.16b, v0.16b, v1.16b \n" + "ST1 {v0.16b}, [%[CtrOut]] \n" - :[CtrOut] "=r" (output), "=r" (keyPt), "=r" (rounds) - :[Key] "1" (keyPt), [R] "2" (rounds), [CtrIn] "r" (input), "0" (output) + :[CtrOut] "=r" (outBlock), "=r" (keyPt), "=r" (rounds), + "=r" (inBlock) + :"0" (outBlock), [Key] "1" (keyPt), [R] "2" (rounds), + [CtrIn] "3" (inBlock) : "cc", "memory", "w12" ); - XMEMCPY(outBlock, out, AES_BLOCK_SIZE); - return 0; } #ifdef HAVE_AES_DECRYPT static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { - byte* keyPt = (byte*)aes->key; + byte* keyPt = (byte*)aes->key; word32 rounds = aes->rounds; - byte out[AES_BLOCK_SIZE]; - byte* output = out; - byte* input = (byte*)inBlock; /* AESE exor's input with round key @@ -437,64 +430,64 @@ void wc_AesAsyncFree(Aes* aes) */ __asm__ __volatile__ ( - "LD1 {v0.16b}, [%[CtrIn]], #16 \n" + "LD1 {v0.16b}, [%[CtrIn]] \n" "LD1 {v1.16b-v4.16b}, [%[Key]], #64 \n" - "AESD v0.16b, v1.16b \n" + "AESD v0.16b, v1.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v2.16b \n" + "AESD v0.16b, v2.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v3.16b \n" + "AESD v0.16b, v3.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v4.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" + "AESD v0.16b, v1.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v2.16b \n" + "AESD v0.16b, v2.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v3.16b \n" + "AESD v0.16b, v3.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v4.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" + "AESD v0.16b, v1.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v2.16b \n" + "AESD v0.16b, v2.16b \n" "#subtract rounds done so far and see if should continue\n" - "MOV w12, %w[R] \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" + "AESD v0.16b, v1.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v2.16b \n" + "AESD v0.16b, v2.16b \n" - "SUB w12, w12, #2 \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" + "AESD v0.16b, v1.16b \n" "AESIMC v0.16b, v0.16b \n" - "AESD v0.16b, v2.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" + "LD1 {v1.16b}, [%[Key]], #16 \n" + "EOR v0.16b, v0.16b, v1.16b \n" + "ST1 {v0.4s}, [%[CtrOut]] \n" - :[CtrOut] "=r" (output), "=r" (keyPt), "=r" (rounds), "=r" (input) - :[Key] "1" (keyPt), [R] "2" (rounds), [CtrIn] "3" (input), "0" (output) + :[CtrOut] "=r" (outBlock), "=r" (keyPt), "=r" (rounds), + "=r" (inBlock) + :"0" (outBlock), [Key] "1" (keyPt), [R] "2" (rounds), + [CtrIn] "3" (inBlock) : "cc", "memory", "w12" ); - XMEMCPY(outBlock, out, AES_BLOCK_SIZE); - return 0; } #endif /* HAVE_AES_DECRYPT */ From 8d6ea61a4f4185a274943145d75b5662f4578107 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 6 Sep 2016 16:42:53 -0700 Subject: [PATCH 45/69] Fix to allow disabling P-RNG and SHA256 when CUSTOM_RAND_GENERATE_BLOCK is used. Added inline documentation to describe RNG source options. Example: ./configure --enable-cryptonly --disable-hashdrbg CFLAGS="-DNO_SHA256 -DCUSTOM_RAND_GENERATE_BLOCK" --- wolfssl/wolfcrypt/random.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 64889f15ef..29d3a9385f 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 && !SHA256 (default). Uses SHA256 based P-RNG + * seeded via wc_GenerateSeed. + * 3. !HAVE_HASHDRBG && 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 From a5db13cd017893344ed403711f849e7aab078174 Mon Sep 17 00:00:00 2001 From: toddouska Date: Wed, 7 Sep 2016 09:17:14 -0700 Subject: [PATCH 46/69] detect server forcing compression on client w/o support --- src/internal.c | 8 ++++++++ wolfssl/error-ssl.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 7e619daf9f..79e212febb 100755 --- a/src/internal.c +++ b/src/internal.c @@ -11162,6 +11162,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"; @@ -13048,6 +13051,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 */ diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index bdf8f5bab0..6b55170d2a 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -153,7 +153,8 @@ enum wolfSSL_ErrorCodes { /* 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 !!!!! */ From f6b786cfb52cf8f4240f235587f907d37753ba6d Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 7 Sep 2016 09:23:43 -0700 Subject: [PATCH 47/69] Updated the random.h source inline comments to clarify SHA256 and RC4. --- wolfssl/wolfcrypt/random.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 29d3a9385f..1669a6e267 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -48,9 +48,9 @@ /* 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 && !SHA256 (default). Uses SHA256 based P-RNG - * seeded via wc_GenerateSeed. - * 3. !HAVE_HASHDRBG && RC4 enabled. Uses RC4 + * 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) From 3aefc42f049275c645ab5ad3988c23d92efdf8e6 Mon Sep 17 00:00:00 2001 From: toddouska Date: Wed, 7 Sep 2016 15:28:30 -0700 Subject: [PATCH 48/69] have TLS server side verify no compression is in list if not using compression --- src/internal.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/internal.c b/src/internal.c index 79e212febb..80cb9f9ef4 100755 --- a/src/internal.c +++ b/src/internal.c @@ -18071,23 +18071,34 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #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; From 79af4d30e075d282747c636e29b246e8429c5d60 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 8 Sep 2016 18:00:24 +0000 Subject: [PATCH 49/69] ARMv8 : increase performance with SHA256 --- wolfcrypt/src/port/arm/armv8-sha256.c | 810 ++++++++++++++------------ 1 file changed, 436 insertions(+), 374 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 5a7a9d2e42..d306433bd6 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -110,159 +110,204 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) { /* do block size increments */ - byte* local = (byte*)sha256->buffer; + word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); + word32 numBlocks; - while (len) { - word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); - XMEMCPY(&local[sha256->buffLen], data, add); + /* fill leftover buffer with data */ + XMEMCPY((byte*)(sha256->buffer) + sha256->buffLen, data, add); + sha256->buffLen += add; + data += add; + len -= add; - sha256->buffLen += add; - data += add; - len -= add; + /* number of blocks in a row to complete */ + numBlocks = (len + sha256->buffLen)/SHA256_BLOCK_SIZE; - if (sha256->buffLen == SHA256_BLOCK_SIZE) { - word32* Kpt = (word32*)K; - word32* bufferPt = sha256->buffer; - word32* digestPt = sha256->digest; + if (numBlocks > 0) { + word32* bufferPt = sha256->buffer; + word32* digestPt = sha256->digest; - __asm__ volatile ( - "#load in message and schedual updates \n" - "LD1 {v4.16b-v7.16b}, [%[buffer]] \n" - "MOV v0.16b, v4.16b \n" - "MOV v1.16b, v5.16b \n" - "REV32 v0.16b, v0.16b \n" - "MOV v2.16b, v6.16b \n" - "REV32 v1.16b, v1.16b \n" - "MOV v3.16b, v7.16b \n" - "REV32 v2.16b, v2.16b \n" - "REV32 v3.16b, v3.16b \n" + /* 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" - "MOV v4.16b, v0.16b \n" - "MOV v5.16b, v1.16b \n" - "SHA256SU0 v4.4s, v1.4s \n" - "SHA256SU1 v4.4s, v2.4s, v3.4s \n" - "MOV v6.16b, v2.16b \n" - "SHA256SU0 v5.4s, v2.4s \n" - "SHA256SU1 v5.4s, v3.4s, v4.4s \n" - "MOV v7.16b, v3.16b \n" - "SHA256SU0 v6.4s, v3.4s \n" - "SHA256SU1 v6.4s, v4.4s, v5.4s \n" - "MOV v8.16b, v4.16b \n" - "SHA256SU0 v7.4s, v4.4s \n" - "SHA256SU1 v7.4s, v5.4s, v6.4s \n" - "MOV v9.16b, v5.16b \n" - "SHA256SU0 v8.4s, v5.4s \n" - "SHA256SU1 v8.4s, v6.4s, v7.4s \n" - "MOV v10.16b, v6.16b \n" - "SHA256SU0 v9.4s, v6.4s \n" - "SHA256SU1 v9.4s, v7.4s, v8.4s \n" - "MOV v11.16b, v7.16b \n" - "SHA256SU0 v10.4s, v7.4s \n" - "SHA256SU1 v10.4s, v8.4s, v9.4s \n" - "MOV v12.16b, v8.16b \n" - "SHA256SU0 v11.4s, v8.4s \n" - "SHA256SU1 v11.4s, v9.4s, v10.4s \n" - "MOV v13.16b, v9.16b \n" - "SHA256SU0 v12.4s, v9.4s \n" - "SHA256SU1 v12.4s, v10.4s, v11.4s \n" - "MOV v14.16b, v10.16b \n" - "SHA256SU0 v13.4s, v10.4s \n" - "SHA256SU1 v13.4s, v11.4s, v12.4s \n" - "MOV v15.16b, v11.16b \n" - "SHA256SU0 v14.4s, v11.4s \n" - "SHA256SU1 v14.4s, v12.4s, v13.4s \n" - "SHA256SU0 v15.4s, v12.4s \n" - "SHA256SU1 v15.4s, v13.4s, v14.4s \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" - "#Add K values to message \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v0.4s, v0.4s, v16.4s \n" - "ADD v1.4s, v1.4s, v17.4s \n" - "ADD v2.4s, v2.4s, v18.4s \n" - "ADD v3.4s, v3.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v4.4s, v4.4s, v16.4s \n" - "ADD v5.4s, v5.4s, v17.4s \n" - "ADD v6.4s, v6.4s, v18.4s \n" - "ADD v7.4s, v7.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v8.4s, v8.4s, v16.4s \n" - "ADD v9.4s, v9.4s, v17.4s \n" - "ADD v10.4s, v10.4s, v18.4s \n" - "ADD v11.4s, v11.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]] \n" - "ADD v12.4s, v12.4s, v16.4s \n" - "ADD v13.4s, v13.4s, v17.4s \n" - "LD1 {v20.4s-v21.4s}, [%[digest]] \n" - "ADD v14.4s, v14.4s, v18.4s \n" - "ADD v15.4s, v15.4s, v19.4s \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" - "#SHA256 operation on updated message \n" - "MOV v16.16b, v20.16b \n" - "MOV v17.16b, v21.16b \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v0.4s \n" - "SHA256H2 q17, q18, v0.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v1.4s \n" - "SHA256H2 q17, q18, v1.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v2.4s \n" - "SHA256H2 q17, q18, v2.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v3.4s \n" - "SHA256H2 q17, q18, v3.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v4.4s \n" - "SHA256H2 q17, q18, v4.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v5.4s \n" - "SHA256H2 q17, q18, v5.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v6.4s \n" - "SHA256H2 q17, q18, v6.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v7.4s \n" - "SHA256H2 q17, q18, v7.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v8.4s \n" - "SHA256H2 q17, q18, v8.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v9.4s \n" - "SHA256H2 q17, q18, v9.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v10.4s \n" - "SHA256H2 q17, q18, v10.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v11.4s \n" - "SHA256H2 q17, q18, v11.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v12.4s \n" - "SHA256H2 q17, q18, v12.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v13.4s \n" - "SHA256H2 q17, q18, v13.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v14.4s \n" - "SHA256H2 q17, q18, v14.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v15.4s \n" - "SHA256H2 q17, q18, v15.4s \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 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" - : "=r" (Kpt), [out] "=r" (digestPt), "=r" (bufferPt) - : [k] "0" (Kpt), [digest] "1" (digestPt), [buffer] "2" (bufferPt) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v8", "v9", "v10", "v11", "v12", "v13", "v14", - "v15", "v16", "v17", "v18", "v19", "v20", "v21" + "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] "=r" (digestPt), "=r" (bufferPt), "=r" (numBlocks), + "=r" (data) + : [k] "r" (K), [digest] "0" (digestPt), [buffer] "1" (bufferPt), + [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); - sha256->buffLen = 0; - } + AddLength(sha256, SHA256_BLOCK_SIZE * numBlocks); + + /* copy over any remaining data leftover */ + XMEMCPY(sha256->buffer, data, add); + sha256->buffLen = add; } return 0; @@ -272,10 +317,8 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) int wc_Sha256Final(Sha256* sha256, byte* hash) { byte* local = (byte*)sha256->buffer; - word32* Kpt = (word32*)K; word32* bufferPt = sha256->buffer; word32* digestPt = sha256->digest; - word32* hashPt = (word32*)hash; AddLength(sha256, sha256->buffLen); /* before adding pads */ @@ -285,143 +328,152 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) if (sha256->buffLen > SHA256_PAD_SIZE) { XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); - sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; - bufferPt = sha256->buffer; - digestPt = sha256->digest; - Kpt = (word32*)K; __asm__ volatile ( - "#load in message and schedual updates \n" "LD1 {v4.16b-v7.16b}, [%[buffer]] \n" "MOV v0.16b, v4.16b \n" "MOV v1.16b, v5.16b \n" "REV32 v0.16b, v0.16b \n" - "MOV v2.16b, v6.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" - "SHA256SU0 v4.4s, v1.4s \n" - "SHA256SU1 v4.4s, v2.4s, v3.4s \n" - "MOV v6.16b, v2.16b \n" - "SHA256SU0 v5.4s, v2.4s \n" - "SHA256SU1 v5.4s, v3.4s, v4.4s \n" - "MOV v7.16b, v3.16b \n" - "SHA256SU0 v6.4s, v3.4s \n" - "SHA256SU1 v6.4s, v4.4s, v5.4s \n" - "MOV v8.16b, v4.16b \n" - "SHA256SU0 v7.4s, v4.4s \n" - "SHA256SU1 v7.4s, v5.4s, v6.4s \n" - "MOV v9.16b, v5.16b \n" - "SHA256SU0 v8.4s, v5.4s \n" - "SHA256SU1 v8.4s, v6.4s, v7.4s \n" - "MOV v10.16b, v6.16b \n" - "SHA256SU0 v9.4s, v6.4s \n" - "SHA256SU1 v9.4s, v7.4s, v8.4s \n" - "MOV v11.16b, v7.16b \n" - "SHA256SU0 v10.4s, v7.4s \n" - "SHA256SU1 v10.4s, v8.4s, v9.4s \n" - "MOV v12.16b, v8.16b \n" - "SHA256SU0 v11.4s, v8.4s \n" - "SHA256SU1 v11.4s, v9.4s, v10.4s \n" - "MOV v13.16b, v9.16b \n" - "SHA256SU0 v12.4s, v9.4s \n" - "SHA256SU1 v12.4s, v10.4s, v11.4s \n" - "MOV v14.16b, v10.16b \n" - "SHA256SU0 v13.4s, v10.4s \n" - "SHA256SU1 v13.4s, v11.4s, v12.4s \n" - "MOV v15.16b, v11.16b \n" - "SHA256SU0 v14.4s, v11.4s \n" - "SHA256SU1 v14.4s, v12.4s, v13.4s \n" - "SHA256SU0 v15.4s, v12.4s \n" - "SHA256SU1 v15.4s, v13.4s, v14.4s \n" - - "#Add K values to message \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v0.4s, v0.4s, v16.4s \n" - "ADD v1.4s, v1.4s, v17.4s \n" - "ADD v2.4s, v2.4s, v18.4s \n" - "ADD v3.4s, v3.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v4.4s, v4.4s, v16.4s \n" - "ADD v5.4s, v5.4s, v17.4s \n" - "ADD v6.4s, v6.4s, v18.4s \n" - "ADD v7.4s, v7.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v8.4s, v8.4s, v16.4s \n" - "ADD v9.4s, v9.4s, v17.4s \n" - "ADD v10.4s, v10.4s, v18.4s \n" - "ADD v11.4s, v11.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]] \n" - "ADD v12.4s, v12.4s, v16.4s \n" - "ADD v13.4s, v13.4s, v17.4s \n" "LD1 {v20.4s-v21.4s}, [%[digest]] \n" - "ADD v14.4s, v14.4s, v18.4s \n" - "ADD v15.4s, v15.4s, v19.4s \n" "#SHA256 operation on updated message \n" "MOV v16.16b, v20.16b \n" "MOV v17.16b, v21.16b \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v0.4s \n" - "SHA256H2 q17, q18, v0.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v1.4s \n" - "SHA256H2 q17, q18, v1.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v2.4s \n" - "SHA256H2 q17, q18, v2.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v3.4s \n" - "SHA256H2 q17, q18, v3.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v4.4s \n" - "SHA256H2 q17, q18, v4.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v5.4s \n" - "SHA256H2 q17, q18, v5.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v6.4s \n" - "SHA256H2 q17, q18, v6.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v7.4s \n" - "SHA256H2 q17, q18, v7.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v8.4s \n" - "SHA256H2 q17, q18, v8.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v9.4s \n" - "SHA256H2 q17, q18, v9.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v10.4s \n" - "SHA256H2 q17, q18, v10.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v11.4s \n" - "SHA256H2 q17, q18, v11.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v12.4s \n" - "SHA256H2 q17, q18, v12.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v13.4s \n" - "SHA256H2 q17, q18, v13.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v14.4s \n" - "SHA256H2 q17, q18, v14.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v15.4s \n" - "SHA256H2 q17, q18, v15.4s \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" - : "=r" (Kpt), [out] "=r" (digestPt), "=r" (bufferPt) - : [k] "0" (Kpt), [digest] "1" (digestPt), [buffer] "2" (bufferPt) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v8", "v9", "v10", "v11", "v12", "v13", "v14", - "v15", "v16", "v17", "v18", "v19", "v20", "v21" + : [out] "=r" (digestPt) + : [k] "r" (K), [digest] "0" (digestPt), [buffer] "r" (bufferPt) + : "cc", "memory", "v0", "v1", "v2", "v3", "v8", "v9", "v10", "v11" + , "v12", "v13", "v14", "v15", "v16", "v17", "v18" ); sha256->buffLen = 0; @@ -435,7 +487,6 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) /* store lengths */ #if defined(LITTLE_ENDIAN_ORDER) - bufferPt = sha256->buffer; __asm__ volatile ( "LD1 {v0.16b}, [%[in]] \n" "REV32 v0.16b, v0.16b \n" @@ -451,7 +502,7 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "ST1 {v0.16b}, [%[out]] \n" : [out] "=r" (bufferPt) : [in] "0" (bufferPt) - : "cc" + : "cc", "memory" ); #endif /* ! length ordering dependent on digest endian type ! */ @@ -459,9 +510,9 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, sizeof(word32)); + /* pointer needs reset because of little endian asm above advancing when + * placing values back into buffer as an output */ bufferPt = sha256->buffer; - digestPt = sha256->digest; - Kpt = (word32*)K; __asm__ volatile ( "#load in message and schedual updates \n" "LD1 {v4.16b-v7.16b}, [%[buffer]] \n" @@ -469,120 +520,131 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "MOV v1.16b, v5.16b \n" "MOV v2.16b, v6.16b \n" "MOV v3.16b, v7.16b \n" - "SHA256SU0 v4.4s, v1.4s \n" - "SHA256SU1 v4.4s, v2.4s, v3.4s \n" - "MOV v6.16b, v2.16b \n" - "SHA256SU0 v5.4s, v2.4s \n" - "SHA256SU1 v5.4s, v3.4s, v4.4s \n" - "MOV v7.16b, v3.16b \n" - "SHA256SU0 v6.4s, v3.4s \n" - "SHA256SU1 v6.4s, v4.4s, v5.4s \n" - "MOV v8.16b, v4.16b \n" - "SHA256SU0 v7.4s, v4.4s \n" - "SHA256SU1 v7.4s, v5.4s, v6.4s \n" - "MOV v9.16b, v5.16b \n" - "SHA256SU0 v8.4s, v5.4s \n" - "SHA256SU1 v8.4s, v6.4s, v7.4s \n" - "MOV v10.16b, v6.16b \n" - "SHA256SU0 v9.4s, v6.4s \n" - "SHA256SU1 v9.4s, v7.4s, v8.4s \n" - "MOV v11.16b, v7.16b \n" - "SHA256SU0 v10.4s, v7.4s \n" - "SHA256SU1 v10.4s, v8.4s, v9.4s \n" - "MOV v12.16b, v8.16b \n" - "SHA256SU0 v11.4s, v8.4s \n" - "SHA256SU1 v11.4s, v9.4s, v10.4s \n" - "MOV v13.16b, v9.16b \n" - "SHA256SU0 v12.4s, v9.4s \n" - "SHA256SU1 v12.4s, v10.4s, v11.4s \n" - "MOV v14.16b, v10.16b \n" - "SHA256SU0 v13.4s, v10.4s \n" - "SHA256SU1 v13.4s, v11.4s, v12.4s \n" - "MOV v15.16b, v11.16b \n" - "SHA256SU0 v14.4s, v11.4s \n" - "SHA256SU1 v14.4s, v12.4s, v13.4s \n" - "SHA256SU0 v15.4s, v12.4s \n" - "SHA256SU1 v15.4s, v13.4s, v14.4s \n" - - "#Add K values to message \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v0.4s, v0.4s, v16.4s \n" - "ADD v1.4s, v1.4s, v17.4s \n" - "ADD v2.4s, v2.4s, v18.4s \n" - "ADD v3.4s, v3.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v4.4s, v4.4s, v16.4s \n" - "ADD v5.4s, v5.4s, v17.4s \n" - "ADD v6.4s, v6.4s, v18.4s \n" - "ADD v7.4s, v7.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]], #64 \n" - "ADD v8.4s, v8.4s, v16.4s \n" - "ADD v9.4s, v9.4s, v17.4s \n" - "ADD v10.4s, v10.4s, v18.4s \n" - "ADD v11.4s, v11.4s, v19.4s \n" - "LD1 {v16.16b-v19.16b}, [%[k]] \n" - "ADD v12.4s, v12.4s, v16.4s \n" - "ADD v13.4s, v13.4s, v17.4s \n" "LD1 {v20.4s-v21.4s}, [%[digest]] \n" - "ADD v14.4s, v14.4s, v18.4s \n" - "ADD v15.4s, v15.4s, v19.4s \n" - "#SHA256 operation on updated message \n" "MOV v16.16b, v20.16b \n" "MOV v17.16b, v21.16b \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v0.4s \n" - "SHA256H2 q17, q18, v0.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v1.4s \n" - "SHA256H2 q17, q18, v1.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v2.4s \n" - "SHA256H2 q17, q18, v2.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v3.4s \n" - "SHA256H2 q17, q18, v3.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v4.4s \n" - "SHA256H2 q17, q18, v4.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v5.4s \n" - "SHA256H2 q17, q18, v5.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v6.4s \n" - "SHA256H2 q17, q18, v6.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v7.4s \n" - "SHA256H2 q17, q18, v7.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v8.4s \n" - "SHA256H2 q17, q18, v8.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v9.4s \n" - "SHA256H2 q17, q18, v9.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v10.4s \n" - "SHA256H2 q17, q18, v10.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v11.4s \n" - "SHA256H2 q17, q18, v11.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v12.4s \n" - "SHA256H2 q17, q18, v12.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v13.4s \n" - "SHA256H2 q17, q18, v13.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v14.4s \n" - "SHA256H2 q17, q18, v14.4s \n" - "MOV v18.16b, v16.16b \n" - "SHA256H q16, q17, v15.4s \n" - "SHA256H2 q17, q18, v15.4s \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" - "STP q16, q17, [%[out]] \n" "#Store value as hash output \n" #if defined(LITTLE_ENDIAN_ORDER) @@ -593,12 +655,12 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "REV32 v17.16b, v17.16b \n" #endif "ST1 {v17.16b}, [%[hashOut]] \n" - : "=r" (Kpt), [out] "=r" (digestPt), "=r" (bufferPt), - [hashOut] "=r" (hashPt) - : [k] "0" (Kpt), [digest] "1" (digestPt), [buffer] "2" (bufferPt), "3" (hashPt) + : [hashOut] "=r" (hash) + : [k] "r" (K), [digest] "r" (digestPt), [buffer] "r" (bufferPt), + "0" (hash) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", - "v15", "v16", "v17", "v18", "v19", "v20", "v21" + "v15", "v16", "v17", "v18" ); return wc_InitSha256(sha256); /* reset state */ From 4fb1431727fa68963043e088a1da3349c8b8c893 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 8 Sep 2016 11:25:02 -0700 Subject: [PATCH 50/69] Added support for the extended master secret extension to the sniffer. --- src/sniffer.c | 226 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 223 insertions(+), 3 deletions(-) diff --git a/src/sniffer.c b/src/sniffer.c index 577d59110b..bcef1f9c5b 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 */ }; @@ -329,6 +330,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 +345,27 @@ 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 +#ifdef WOLFSSL_SHA512 + Sha512 hashSha512; +#endif +} HsHashes; + + /* Sniffer Session holds info for each client/server SSL/TLS session */ typedef struct SnifferSession { SnifferServer* context; /* server context */ @@ -363,6 +388,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 +511,9 @@ static void FreeSnifferSession(SnifferSession* session) FreePacketList(session->srvReassemblyList); free(session->ticketID); +#ifdef HAVE_EXTENDED_MASTER + free(session->hash); +#endif } free(session); } @@ -533,6 +564,102 @@ 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 +#ifdef WOLFSSL_SHA512 + if (ret == 0) + ret = wc_InitSha512(&hash->hashSha512); +#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 +#ifdef WOLFSSL_SHA512 + if (ret == 0) + ret = wc_Sha512Update(&hash->hashSha512, 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 +#ifdef WOLFSSL_SHA512 + XMEMCPY(&d->hashSha512, &s->hashSha512, sizeof(Sha512)); +#endif + + return 0; +} + +#endif + + /* Initialize a SnifferServer */ static void InitSnifferServer(SnifferServer* sniffer) { @@ -563,6 +690,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 +730,9 @@ static void InitSession(SnifferSession* session) InitFlags(&session->flags); InitFinCapture(&session->finCaputre); +#ifdef HAVE_EXTENDED_MASTER + session->hash = 0; +#endif } @@ -1483,13 +1616,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 +1685,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 +1951,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 +2076,11 @@ static int DoHandShake(const byte* input, int* sslBytes, return -1; } +#ifdef HAVE_EXTENDED_MASTER + if (session->hash) + HashUpdate(session->hash, input, size); +#endif + switch (type) { case hello_verify_request: Trace(GOT_HELLO_VERIFY_STR); @@ -1896,7 +2094,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,6 +2121,16 @@ static int DoHandShake(const byte* input, int* sslBytes, break; case client_key_exchange: Trace(GOT_CLIENT_KEY_EX_STR); +#ifdef HAVE_EXTENDED_MASTER + if (session->flags.expectEms && session->hash != NULL) { + HashCopy(session->sslServer->hsHashes, session->hash); + HashCopy(session->sslClient->hsHashes, session->hash); + session->sslServer->options.haveEMS = 1; + session->sslClient->options.haveEMS = 1; + free(session->hash); + session->hash = NULL; + } +#endif ret = ProcessClientKeyExchange(input, sslBytes, session, error); break; case certificate_verify: @@ -2135,6 +2343,18 @@ 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; + } + HashInit(newHash); + session->hash = newHash; + } +#endif session->server = ipInfo->dst; session->client = ipInfo->src; session->srvPort = (word16)tcpInfo->dstPort; From 0c21d76ce321fdb0494995263d989c3ac60f26a9 Mon Sep 17 00:00:00 2001 From: toddouska Date: Thu, 8 Sep 2016 12:06:22 -0700 Subject: [PATCH 51/69] detect client not sending any compression types --- src/internal.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/internal.c b/src/internal.c index 80cb9f9ef4..d134b9aafc 100755 --- a/src/internal.c +++ b/src/internal.c @@ -18032,6 +18032,11 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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 (IsDtlsNotSctpMode(ssl)) { byte newCookie[MAX_COOKIE_LEN]; From f4e604dec36b3adeed57b647e1bd1acf9e51aac8 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 8 Sep 2016 15:32:09 -0600 Subject: [PATCH 52/69] verify case with unexpected input --- wolfcrypt/src/signature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, From 3ec66dd6629fc04627ea820ed1d34514d17d7a11 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 9 Sep 2016 00:27:40 +0000 Subject: [PATCH 53/69] ARMv8 : sanity checks and change constraint type --- wolfcrypt/src/port/arm/armv8-sha256.c | 72 +++++++++++++-------------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index d306433bd6..8813d82df5 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -108,12 +108,15 @@ static INLINE void AddLength(Sha256* sha256, word32 len) /* ARMv8 hardware accleration */ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) { - - /* do block size increments */ - word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); + 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; @@ -123,17 +126,14 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) numBlocks = (len + sha256->buffLen)/SHA256_BLOCK_SIZE; if (numBlocks > 0) { - word32* bufferPt = sha256->buffer; - word32* digestPt = sha256->digest; - /* 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" + "LD1 {v0.2d-v3.2d}, %[buffer] \n" "#load current digest\n" - "LD1 {v12.2d-v13.2d}, [%[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" @@ -292,11 +292,11 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) "B sha256Start \n" /* do another block */ "sha256End:\n" - "STP q12, q13, [%[out]] \n" + "STP q12, q13, %[out] \n" - : [out] "=r" (digestPt), "=r" (bufferPt), "=r" (numBlocks), + : [out] "=m" (sha256->digest), "=m" (sha256->buffer), "=r" (numBlocks), "=r" (data) - : [k] "r" (K), [digest] "0" (digestPt), [buffer] "1" (bufferPt), + : [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", @@ -316,10 +316,13 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) int wc_Sha256Final(Sha256* sha256, byte* hash) { - byte* local = (byte*)sha256->buffer; - word32* bufferPt = sha256->buffer; - word32* digestPt = sha256->digest; + 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 */ @@ -330,7 +333,7 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; __asm__ volatile ( - "LD1 {v4.16b-v7.16b}, [%[buffer]] \n" + "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" @@ -341,7 +344,7 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "REV32 v3.16b, v3.16b \n" "MOV v4.16b, v0.16b \n" "MOV v5.16b, v1.16b \n" - "LD1 {v20.4s-v21.4s}, [%[digest]] \n" + "LD1 {v20.2d-v21.2d}, %[digest] \n" "#SHA256 operation on updated message \n" "MOV v16.16b, v20.16b \n" @@ -469,9 +472,10 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "#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] "=r" (digestPt) - : [k] "r" (K), [digest] "0" (digestPt), [buffer] "r" (bufferPt) + "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" ); @@ -488,20 +492,14 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) /* store lengths */ #if defined(LITTLE_ENDIAN_ORDER) __asm__ volatile ( - "LD1 {v0.16b}, [%[in]] \n" + "LD1 {v0.2d-v3.2d}, %[in] \n" "REV32 v0.16b, v0.16b \n" - "ST1 {v0.16b}, [%[out]], #16 \n" - "LD1 {v0.16b}, [%[in]] \n" - "REV32 v0.16b, v0.16b \n" - "ST1 {v0.16b}, [%[out]], #16 \n" - "LD1 {v0.16b}, [%[in]] \n" - "REV32 v0.16b, v0.16b \n" - "ST1 {v0.16b}, [%[out]], #16 \n" - "LD1 {v0.16b}, [%[in]] \n" - "REV32 v0.16b, v0.16b \n" - "ST1 {v0.16b}, [%[out]] \n" - : [out] "=r" (bufferPt) - : [in] "0" (bufferPt) + "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 @@ -510,17 +508,14 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, sizeof(word32)); - /* pointer needs reset because of little endian asm above advancing when - * placing values back into buffer as an output */ - bufferPt = sha256->buffer; __asm__ volatile ( "#load in message and schedual updates \n" - "LD1 {v4.16b-v7.16b}, [%[buffer]] \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.4s-v21.4s}, [%[digest]] \n" + "LD1 {v20.2d-v21.2d}, %[digest] \n" "MOV v16.16b, v20.16b \n" "MOV v17.16b, v21.16b \n" @@ -656,7 +651,8 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) #endif "ST1 {v17.16b}, [%[hashOut]] \n" : [hashOut] "=r" (hash) - : [k] "r" (K), [digest] "r" (digestPt), [buffer] "r" (bufferPt), + : [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", From a149d83bff7ebc9760d8d2eac68a2e6bd4a49f8a Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Fri, 9 Sep 2016 16:11:56 -0600 Subject: [PATCH 54/69] include MAX_RSA_INT_SZ in wc_RsaKeyToPublicDer(), for 4096-bit keys --- wolfcrypt/src/asn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 884e66ae50..2d203439d3 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5572,7 +5572,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 From b9942440110819bde928c11782cba1f7a069b80c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 9 Sep 2016 23:16:52 -0700 Subject: [PATCH 55/69] Revising the Extended Master Secret support. Removing the dynamic TLSX support for the extention and treating it like the Signature and Hash algorithms extension. It is to be enabled by default and the user can turn it off at run time or build time. --- configure.ac | 9 +-- examples/client/client.c | 12 +-- src/internal.c | 165 +++++++++++++++++++++++++++++++++------ src/sniffer.c | 4 + src/ssl.c | 31 +++++--- src/tls.c | 121 ++++++++++++---------------- tests/api.c | 12 +-- tests/suites.c | 38 +++++++-- wolfssl/internal.h | 17 ++-- wolfssl/ssl.h | 9 +-- 10 files changed, 271 insertions(+), 147 deletions(-) diff --git a/configure.ac b/configure.ac index 853e71a0ba..ba4d2f3ef1 100644 --- a/configure.ac +++ b/configure.ac @@ -1959,14 +1959,14 @@ fi # Extended Master Secret Extension AC_ARG_ENABLE([extended-master], - [AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: disabled)])], + [AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: enabled)])], [ ENABLED_EXTENDED_MASTER=$enableval ], - [ ENABLED_EXTENDED_MASTER=no ] + [ ENABLED_EXTENDED_MASTER=yes ] ) if test "x$ENABLED_EXTENDED_MASTER" = "xyes" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_EXTENDED_MASTER" + AM_CFLAGS="$AM_CFLAGS -DHAVE_EXTENDED_MASTER" fi # TLS Extensions @@ -1983,8 +1983,7 @@ then ENABLED_TRUNCATED_HMAC=yes ENABLED_SUPPORTED_CURVES=yes ENABLED_ALPN=yes - ENABLED_EXTENDED_MASTER=yes - AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN -DHAVE_EXTENDED_MASTER" + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN" fi # PKCS7 diff --git a/examples/client/client.c b/examples/client/client.c index 2129f02476..14ef262455 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -495,7 +495,7 @@ static void Usage(void) printf("-T Use Truncated HMAC\n"); #endif #ifdef HAVE_EXTENDED_MASTER - printf("-n Use Extended Master Secret\n"); + printf("-n Disable Extended Master Secret\n"); #endif #ifdef HAVE_OCSP printf("-o Perform OCSP lookup on peer certificate\n"); @@ -613,7 +613,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) byte statusRequest = 0; #endif #ifdef HAVE_EXTENDED_MASTER - byte extMasterSecret = 0; + byte disableExtMasterSecret = 0; #endif @@ -865,7 +865,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) case 'n' : #ifdef HAVE_EXTENDED_MASTER - extMasterSecret = 1; + disableExtMasterSecret = 1; #endif break; @@ -1246,9 +1246,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) err_sys("UseSessionTicket failed"); #endif #ifdef HAVE_EXTENDED_MASTER - if (extMasterSecret) - if (wolfSSL_CTX_UseExtendedMasterSecret(ctx) != SSL_SUCCESS) - err_sys("UseExtendedMasterSecret failed"); + if (disableExtMasterSecret) + if (wolfSSL_CTX_DisableExtendedMasterSecret(ctx) != SSL_SUCCESS) + err_sys("DisableExtendedMasterSecret failed"); #endif if (benchmark) { diff --git a/src/internal.c b/src/internal.c index e9556a1424..2c3895f16f 100755 --- a/src/internal.c +++ b/src/internal.c @@ -1401,6 +1401,20 @@ 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 @@ -3375,6 +3389,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) 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; @@ -12681,6 +12699,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"); @@ -12714,11 +12733,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; @@ -12803,24 +12830,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 @@ -13058,9 +13097,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; @@ -13082,9 +13120,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; @@ -15979,6 +16078,10 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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 */ @@ -16052,6 +16155,18 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* 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; + } +#endif #endif ssl->buffers.outputBuffer.length += sendSz; @@ -18155,6 +18270,10 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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; diff --git a/src/sniffer.c b/src/sniffer.c index bcef1f9c5b..d2d94e1a9b 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -2130,6 +2130,10 @@ static int DoHandShake(const byte* input, int* sslBytes, free(session->hash); session->hash = NULL; } + else { + session->sslServer->options.haveEMS = 0; + session->sslClient->options.haveEMS = 0; + } #endif ret = ProcessClientKeyExchange(input, sslBytes, session, error); break; diff --git a/src/ssl.c b/src/ssl.c index 2e99b5b6ec..c6cc0d6960 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1749,27 +1749,34 @@ WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl, } #endif + #ifdef HAVE_EXTENDED_MASTER #ifndef NO_WOLFSSL_CLIENT -int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl) -{ - if (ssl == NULL) - return BAD_FUNC_ARG; - - return TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap); -} - -int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx) +int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx) { if (ctx == NULL) return BAD_FUNC_ARG; - return TLSX_UseExtendedMasterSecret(&ctx->extensions, ctx->heap); + ctx->haveEMS = 0; + + return SSL_SUCCESS; } -#endif /* NO_WOLFSSL_CLIENT */ -#endif /* HAVE_EXTENDED_MASTER */ + +int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + ssl->options.haveEMS = 0; + + return SSL_SUCCESS; +} + +#endif +#endif + #ifndef WOLFSSL_LEANPSK diff --git a/src/tls.c b/src/tls.c index 4e6511d384..648147c2ac 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3942,58 +3942,6 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, #endif /* HAVE_QSH */ -/******************************************************************************/ -/* TLS Extended Master Secret */ -/******************************************************************************/ - -#ifdef HAVE_EXTENDED_MASTER - -static int TLSX_EMS_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) -{ - (void)isRequest; - - if (length != 0 || input == NULL) - return BUFFER_ERROR; - -#ifndef NO_WOLFSSL_SERVER - if (isRequest) { - int r = TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap); - - if (r != SSL_SUCCESS) - return r; /* throw error */ - - TLSX_SetResponse(ssl, TLSX_EXTENDED_MASTER_SECRET); - } -#endif - - ssl->options.haveEMS = 1; - - return 0; -} - -int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap) -{ - int ret = 0; - - if (extensions == NULL) - return BAD_FUNC_ARG; - - if ((ret = TLSX_Push(extensions, TLSX_EXTENDED_MASTER_SECRET, NULL, - heap)) != 0) - return ret; - - return SSL_SUCCESS; -} - -#define EMS_PARSE TLSX_EMS_Parse - -#else - -#define EMS_PARSE(a, b, c, d) 0 - -#endif /* HAVE_EXTENDED_MASTER */ - /******************************************************************************/ /* TLS Extensions Framework */ /******************************************************************************/ @@ -4043,10 +3991,6 @@ void TLSX_FreeAll(TLSX* list, void* heap) CSR2_FREE_ALL(extension->data, heap); break; - case TLSX_EXTENDED_MASTER_SECRET: - /* Nothing to do. */ - break; - case TLSX_RENEGOTIATION_INFO: SCR_FREE_ALL(extension->data, heap); break; @@ -4124,10 +4068,6 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) length += CSR2_GET_SIZE(extension->data, isRequest); break; - case TLSX_EXTENDED_MASTER_SECRET: - /* always empty. */ - break; - case TLSX_RENEGOTIATION_INFO: length += SCR_GET_SIZE(extension->data, isRequest); break; @@ -4207,10 +4147,6 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, isRequest); break; - case TLSX_EXTENDED_MASTER_SECRET: - /* always empty. */ - break; - case TLSX_RENEGOTIATION_INFO: offset += SCR_WRITE(extension->data, output + offset, isRequest); @@ -4552,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) @@ -4583,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 */ @@ -4603,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 */ } @@ -4629,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; } @@ -4652,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 */ } @@ -4667,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; @@ -4724,11 +4692,17 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, ret = CSR2_PARSE(ssl, input + offset, size, isRequest); break; - case TLSX_EXTENDED_MASTER_SECRET: +#ifdef HAVE_EXTENDED_MASTER + case HELLO_EXT_EXTMS: WOLFSSL_MSG("Extended Master Secret extension received"); - ret = EMS_PARSE(ssl, input + offset, size, isRequest); +#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"); @@ -4779,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 ef8f982f2f..b5d348ca07 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1927,7 +1927,7 @@ static void test_wolfSSL_UseALPN(void) #endif } -static void test_wolfSSL_UseExtendedMasterSecret(void) +static void test_wolfSSL_DisableExtendedMasterSecret(void) { #ifdef HAVE_EXTENDED_MASTER WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); @@ -1937,12 +1937,12 @@ static void test_wolfSSL_UseExtendedMasterSecret(void) AssertNotNull(ssl); /* error cases */ - AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseExtendedMasterSecret(NULL)); - AssertIntNE(SSL_SUCCESS, wolfSSL_UseExtendedMasterSecret(NULL)); + AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(NULL)); + AssertIntNE(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(NULL)); /* success cases */ - AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseExtendedMasterSecret(ctx)); - AssertIntEQ(SSL_SUCCESS, wolfSSL_UseExtendedMasterSecret(ssl)); + AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(ctx)); + AssertIntEQ(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(ssl)); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); @@ -2151,7 +2151,7 @@ void ApiTest(void) test_wolfSSL_UseTruncatedHMAC(); test_wolfSSL_UseSupportedCurve(); test_wolfSSL_UseALPN(); - test_wolfSSL_UseExtendedMasterSecret(); + test_wolfSSL_DisableExtendedMasterSecret(); /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); diff --git a/tests/suites.c b/tests/suites.c index bc700d00ed..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; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 49ca058210..5f67dc33eb 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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) */ @@ -1645,7 +1646,6 @@ typedef enum { TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */ TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */ TLSX_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stapling v2 */ - TLSX_EXTENDED_MASTER_SECRET = 0x0017, TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */ TLSX_SESSION_TICKET = 0x0023, TLSX_RENEGOTIATION_INFO = 0xff01 @@ -1899,14 +1899,6 @@ WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name); #endif /* HAVE_QSH */ -/* TLS Extended Master Secret, RFC 7627 */ -#ifdef HAVE_EXTENDED_MASTER - -WOLFSSL_LOCAL int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap); - -#endif - - /* wolfSSL context type */ struct WOLFSSL_CTX { WOLFSSL_METHOD* method; @@ -1946,6 +1938,7 @@ 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 */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index be86237ea5..e83749cd23 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1705,14 +1705,9 @@ WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name); #endif /* TLS Extended Master Secret Extension */ -#ifdef HAVE_EXTENDED_MASTER -#ifndef NO_WOLFSSL_CLIENT +WOLFSSL_API int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx); -WOLFSSL_API int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl); -WOLFSSL_API int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx); - -#endif /* NO_WOLFSSL_CLIENT */ -#endif /* HAVE_EXTENDED_MASTER */ #define WOLFSSL_CRL_MONITOR 0x01 /* monitor this dir flag */ #define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */ From c1136a30e9b70bebf681bf755d467d348ddd4e26 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 12 Sep 2016 09:42:42 -0700 Subject: [PATCH 56/69] 1. Enabled the extended master secret in the Windows IDE user_settings.h file by default. 2. Fixed scan-build warning about an assignment to a variable that isn't used again in the function. Commented out the line. --- IDE/WIN/user_settings.h | 1 + src/internal.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) 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/src/internal.c b/src/internal.c index 2c3895f16f..e9b6850cc2 100755 --- a/src/internal.c +++ b/src/internal.c @@ -16164,7 +16164,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, c16toa(HELLO_EXT_EXTMS, output + idx); idx += HELLO_EXT_TYPE_SZ; c16toa(0, output + idx); - idx += HELLO_EXT_SZ_SZ; + /*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 From 97a64bcc7cdfe3928e62136e6c8a23b5b94b2a8d Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 12 Sep 2016 12:03:37 -0700 Subject: [PATCH 57/69] remove unique aes last round Te table, pre fetch Te tables during software aes encrypt --- wolfcrypt/src/aes.c | 193 ++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 115 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 501bd430ec..8705c38b5e 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -507,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, @@ -771,72 +771,6 @@ 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, } }; @@ -1337,6 +1271,32 @@ 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) || (__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++) { + for (j = 0; j < 256; j += WC_CACHE_LINE_SZ) { + x &= Te[i][j]; + } + } + return x; +} + + static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) { word32 s0, s1, s2, s3; @@ -1411,6 +1371,8 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) s2 ^= rk[2]; s3 ^= rk[3]; + s0 |= PreFetchTe(); + /* * Nr - 1 full rounds: */ @@ -1478,28 +1440,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 */ @@ -1514,6 +1476,7 @@ 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 */ @@ -2055,10 +2018,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]; @@ -2077,10 +2040,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]; @@ -2100,10 +2063,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]; @@ -2112,10 +2075,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]; @@ -2147,25 +2110,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 */ From c6256211d66ad7bac3357326cb08fdeaddbc3b54 Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 12 Sep 2016 13:04:30 -0700 Subject: [PATCH 58/69] compress aes last round decrypt table, prefetch Td tables before aes decrypt rounds, prefecth compressed table before last round --- wolfcrypt/src/aes.c | 171 +++++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 83 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 8705c38b5e..65a5538cea 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -774,7 +774,7 @@ static const word32 Te[4][256] = { } }; -static const word32 Td[5][256] = { +static const word32 Td[4][256] = { { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, @@ -1039,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)))) @@ -1482,6 +1453,35 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) #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++) { + for (j = 0; j < 256; j += WC_CACHE_LINE_SZ) { + 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; @@ -1538,6 +1538,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) s2 ^= rk[2]; s3 ^= rk[3]; + s0 |= PreFetchTd(); + /* * Nr - 1 full rounds: */ @@ -1602,29 +1604,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 */ From 77cf7006571dbca1dac9a9ecbabcd050b649a920 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 12 Sep 2016 14:24:56 -0700 Subject: [PATCH 59/69] Update to allow resumption with session tickets and extended master secret. --- src/internal.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index e9b6850cc2..618c4f6ebd 100755 --- a/src/internal.c +++ b/src/internal.c @@ -18732,6 +18732,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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 */ @@ -18753,6 +18754,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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; @@ -18762,6 +18765,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, 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)); @@ -18853,8 +18857,10 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } /* 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); + ssl->session.haveEMS = it->haveEMS; + } return ret; } From 6ae1a14c9f24754cccfb5c0cd84851f9b6650375 Mon Sep 17 00:00:00 2001 From: toddouska Date: Mon, 12 Sep 2016 21:09:08 -0700 Subject: [PATCH 60/69] do aes cache line stride by bytes, not word32s --- wolfcrypt/src/aes.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 65a5538cea..bfd46ffde3 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -1260,7 +1260,8 @@ static INLINE word32 PreFetchTe(void) int i,j; for (i = 0; i < 4; i++) { - for (j = 0; j < 256; j += WC_CACHE_LINE_SZ) { + /* 256 elements, each one is 4 bytes */ + for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) { x &= Te[i][j]; } } @@ -1461,7 +1462,8 @@ static INLINE word32 PreFetchTd(void) int i,j; for (i = 0; i < 4; i++) { - for (j = 0; j < 256; j += WC_CACHE_LINE_SZ) { + /* 256 elements, each one is 4 bytes */ + for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) { x &= Td[i][j]; } } From 6ef9e79ff5ccd2b96fdfed404ada872fd29514be Mon Sep 17 00:00:00 2001 From: toddouska Date: Tue, 13 Sep 2016 09:13:39 -0700 Subject: [PATCH 61/69] switch timing resistant exptmod to use temp for square instead of leaking key bit to cache monitor --- wolfcrypt/src/tfm.c | 31 +++++++++++++++++++++++++++++-- wolfssl/wolfcrypt/types.h | 1 + 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 35364334ad..06a4846e43 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1035,13 +1035,29 @@ int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) #ifdef TFM_TIMING_RESISTANT +/* all off / all on pointer addresses for constant calculations */ +static const wolfssl_word 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 +}; + /* 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) { - fp_int R[2]; + fp_int R[3]; fp_digit buf, mp; int err, bitcnt, digidx, y; @@ -1052,6 +1068,7 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) fp_init(&R[0]); fp_init(&R[1]); + fp_init(&R[2]); /* now we need R mod m */ fp_montgomery_calc_normalization (&R[0], P); @@ -1092,7 +1109,17 @@ 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); - fp_sqr(&R[y], &R[y]); fp_montgomery_reduce(&R[y], P, mp); + + /* 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] & off_on_addr[(y^1)]) + + ((wolfssl_word)&R[1] & 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] & off_on_addr[(y^1)]) + + ((wolfssl_word)&R[1] & off_on_addr[y]) ) ); } fp_montgomery_reduce(&R[0], P, mp); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index d674536017..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 From 46a0ee8e690913a41a10f3c296cfab8345500218 Mon Sep 17 00:00:00 2001 From: toddouska Date: Tue, 13 Sep 2016 11:10:10 -0700 Subject: [PATCH 62/69] switch ecc timising resistant mulmod double to use temp instead of leaking key bit to cache monitor --- wolfcrypt/src/ecc.c | 57 ++++++++++++++++++++++++++++++++++++++++++++- wolfcrypt/src/tfm.c | 11 +++++---- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index ec324308bb..f4cc1e8314 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1876,6 +1876,27 @@ int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, #else /* ECC_TIMING_RESISTANT */ + +#if defined(TFM_TIMINING_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 + /** Perform a point multiplication (timing resistant) k The scalar to multiply by @@ -2013,8 +2034,42 @@ 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); + /* 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 = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp); + 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; } /* end for */ diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 06a4846e43..7c6a555182 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1036,7 +1036,8 @@ int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) #ifdef TFM_TIMING_RESISTANT /* all off / all on pointer addresses for constant calculations */ -static const wolfssl_word off_on_addr[2] = +/* ecc.c uses same table */ +const wolfssl_word wc_off_on_addr[2] = { #if defined(WC_64BIT_CPU) W64LIT(0x0000000000000000), @@ -1113,13 +1114,13 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) /* 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] & off_on_addr[(y^1)]) + - ((wolfssl_word)&R[1] & off_on_addr[y]) ), + 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] & off_on_addr[(y^1)]) + - ((wolfssl_word)&R[1] & off_on_addr[y]) ) ); + (fp_int*) ( ((wolfssl_word)&R[0] & wc_off_on_addr[y^1]) + + ((wolfssl_word)&R[1] & wc_off_on_addr[y]) ) ); } fp_montgomery_reduce(&R[0], P, mp); From 7b3fc558ec33901f23f4600fc861d9674feff618 Mon Sep 17 00:00:00 2001 From: toddouska Date: Tue, 13 Sep 2016 16:45:15 -0700 Subject: [PATCH 63/69] add WC_NO_CACHE_RESISTANT option for old code path --- wolfcrypt/src/ecc.c | 11 +++++++++-- wolfcrypt/src/tfm.c | 7 +++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index f4cc1e8314..19aeb2de04 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1877,7 +1877,8 @@ int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, #else /* ECC_TIMING_RESISTANT */ -#if defined(TFM_TIMINING_RESISTANT) && defined(USE_FAST_MATH) +#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 @@ -1895,7 +1896,8 @@ int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, 0xffffffffU #endif }; -#endif +#endif /* TFM_TIMING_RESISTANT && USE_FAST_MATH */ +#endif /* WC_NO_CACHE_RESISTANT */ /** Perform a point multiplication (timing resistant) @@ -2034,6 +2036,10 @@ 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 */ @@ -2072,6 +2078,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, ((wolfssl_word)&M[1]->z & wc_off_on_addr[i])) ); if (err != MP_OKAY) break; +#endif /* WC_NO_CACHE_RESISTANT */ } /* end for */ } diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 7c6a555182..c3da84b61b 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1035,6 +1035,7 @@ 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] = @@ -1052,6 +1053,8 @@ const wolfssl_word wc_off_on_addr[2] = #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 @@ -1111,6 +1114,9 @@ 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 */ @@ -1121,6 +1127,7 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) 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); From b6937626b436acf871f7d87ae3ecafab56cf68c5 Mon Sep 17 00:00:00 2001 From: toddouska Date: Tue, 13 Sep 2016 17:01:50 -0700 Subject: [PATCH 64/69] don't require uneeded temp with WC_NO_CACHE_RESISTANT --- wolfcrypt/src/tfm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index c3da84b61b..7079fb9f3b 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1061,7 +1061,11 @@ const wolfssl_word wc_off_on_addr[2] = */ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) { - fp_int R[3]; +#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; @@ -1072,7 +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); From 109642fef4e1f4f36464db9314dc43c35f248fad Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 14 Sep 2016 09:33:48 -0600 Subject: [PATCH 65/69] aes.c : check ILP32 macro defined --- wolfcrypt/src/aes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index bfd46ffde3..f832230f79 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -1244,7 +1244,8 @@ static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, #ifndef WC_CACHE_LINE_SZ - #if defined(__x86_64__) || defined(_M_X64) || (__ILP32__ >= 1) + #if defined(__x86_64__) || defined(_M_X64) || \ + (defined(__ILP32__) && (__ILP32__ >= 1)) #define WC_CACHE_LINE_SZ 64 #else /* default cache line size */ From 8b713adcfd7f0b03bf713498d29d2de9967b9b29 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 14 Sep 2016 13:43:02 -0700 Subject: [PATCH 66/69] Extended Master Secret Peer Review Changes 1. Checked the returns on the hash functions in the sniffer, return new error if any fail. 2. Removed the SHA-512 hash from the sniffer's collection of hashes. Never used in a cipher suite. 3. Added some logging messages in the EMS support in wolfSSL. --- src/internal.c | 7 ++++++ src/sniffer.c | 53 +++++++++++++++++++++++----------------- wolfssl/sniffer_error.h | 1 + wolfssl/sniffer_error.rc | 1 + 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/internal.c b/src/internal.c index 618c4f6ebd..c94b5c7fc8 100755 --- a/src/internal.c +++ b/src/internal.c @@ -18313,10 +18313,15 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* 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; } } @@ -18859,6 +18864,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* get master secret */ 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; } diff --git a/src/sniffer.c b/src/sniffer.c index d2d94e1a9b..49627960b6 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -254,7 +254,8 @@ static const char* const msgTable[] = "Clear ACK Fault", /* 81 */ - "Bad Decrypt Size" + "Bad Decrypt Size", + "Extended Master Secret Hash Error" }; @@ -360,9 +361,6 @@ typedef struct HsHashes { #ifdef WOLFSSL_SHA384 Sha384 hashSha384; #endif -#ifdef WOLFSSL_SHA512 - Sha512 hashSha512; -#endif } HsHashes; @@ -590,10 +588,6 @@ static int HashInit(HsHashes* hash) if (ret == 0) ret = wc_InitSha384(&hash->hashSha384); #endif -#ifdef WOLFSSL_SHA512 - if (ret == 0) - ret = wc_InitSha512(&hash->hashSha512); -#endif return ret; } @@ -624,10 +618,6 @@ static int HashUpdate(HsHashes* hash, const byte* input, int sz) if (ret == 0) ret = wc_Sha384Update(&hash->hashSha384, input, sz); #endif -#ifdef WOLFSSL_SHA512 - if (ret == 0) - ret = wc_Sha512Update(&hash->hashSha512, input, sz); -#endif return ret; } @@ -650,9 +640,6 @@ static int HashCopy(HS_Hashes* d, HsHashes* s) #ifdef WOLFSSL_SHA384 XMEMCPY(&d->hashSha384, &s->hashSha384, sizeof(Sha384)); #endif -#ifdef WOLFSSL_SHA512 - XMEMCPY(&d->hashSha512, &s->hashSha512, sizeof(Sha512)); -#endif return 0; } @@ -2077,8 +2064,13 @@ static int DoHandShake(const byte* input, int* sslBytes, } #ifdef HAVE_EXTENDED_MASTER - if (session->hash) - HashUpdate(session->hash, input, size); + 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) { @@ -2123,10 +2115,20 @@ static int DoHandShake(const byte* input, int* sslBytes, Trace(GOT_CLIENT_KEY_EX_STR); #ifdef HAVE_EXTENDED_MASTER if (session->flags.expectEms && session->hash != NULL) { - HashCopy(session->sslServer->hsHashes, session->hash); - HashCopy(session->sslClient->hsHashes, session->hash); - session->sslServer->options.haveEMS = 1; - session->sslClient->options.haveEMS = 1; + 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; } @@ -2135,7 +2137,8 @@ static int DoHandShake(const byte* input, int* sslBytes, session->sslClient->options.haveEMS = 0; } #endif - ret = ProcessClientKeyExchange(input, sslBytes, session, error); + if (ret == 0) + ret = ProcessClientKeyExchange(input, sslBytes, session, error); break; case certificate_verify: Trace(GOT_CERT_VER_STR); @@ -2355,7 +2358,11 @@ static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo, free(session); return 0; } - HashInit(newHash); + if (HashInit(newHash) != 0) { + SetError(EXTENDED_MASTER_HASH_STR, error, NULL, 0); + free(session); + return 0; + } session->hash = newHash; } #endif 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" } From dc337946d5d8257b49e22a4fb40fdce9eaad30cd Mon Sep 17 00:00:00 2001 From: toddouska Date: Wed, 14 Sep 2016 14:33:08 -0700 Subject: [PATCH 67/69] make sure rsa rng is null on init --- wolfcrypt/src/rsa.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index e7fa4b9f49..f960b67ec9 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -198,6 +198,9 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) 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) { From 9d49fae6007dc308373319a7938a71e05308442f Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 14 Sep 2016 16:53:06 -0600 Subject: [PATCH 68/69] Updates to make building for ARDUINO more intuitive NO_INLINE not necessary, update README --- IDE/ARDUINO/README.md | 10 ++++++++-- .../sketches/{ => wolfssl_client}/wolfssl_client.ino | 0 IDE/ARDUINO/wolfssl-arduino.sh | 2 +- wolfssl/wolfcrypt/settings.h | 2 ++ 4 files changed, 11 insertions(+), 3 deletions(-) rename IDE/ARDUINO/sketches/{ => wolfssl_client}/wolfssl_client.ino (100%) 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/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 880109e72e..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 */ From 19434e285a11bc6d77810645a8701e5ca22239c8 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 15 Sep 2016 10:13:31 -0700 Subject: [PATCH 69/69] Update the resume test to rerun itself with the "-n" option to disable extended master secret if the option is enabled. --- scripts/resume.test | 110 +++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 47 deletions(-) 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