diff --git a/.gitignore b/.gitignore
index 47c38e3f1..ab22d786e 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 74c1041ab..8575aeb9a 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 971878e33..7d5ffd856 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 ed283b5ef..79d44702e 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 8ad064f06..78ab33dcb 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 093d8465b..c99eb3cbd 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 674d96840..40719554e 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 b582395e3..505e44a7c 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 3c8a9f23b..ecb7de485 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 0469be812..f814c0d4e 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 2c5f10b2b..6cb836e6a 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 65ca4c46c..d917c946b 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 b5dc3de2d..74feccc0b 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 c8a99f579..d0216035d 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 8fe323631..3a6a87a6f 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 5044bd9a4..8dc391ce8 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 0fba76ab6..6f11389e3 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 dd3207c88..50e888521 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 11c313c45..2fb0d17ed 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 689100e68..a387a404d 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 4b64d1082..dd9846529 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 6d95d3199..f27e575a6 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 a510d61d7..e535d0b72 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 c12cd328b..e13ae49a2 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 a30d11117..6922089de 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 cc2a856dc..59d89b882 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 bac3e90a7..2f9bd34d0 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 3f7e88c2a..7fc45faa3 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 b4c617ce8..23a2afef6 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 7dd5fd507..28d04e76b 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 23b53b305..2a26d2663 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 28707ce21..983b63b4f 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 000000000..982a938b9
--- /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 000000000..1acc49644
--- /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 4e533cf93..efcd3a570 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 e34e17c85..cff7477a4 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 000000000..4da1b2b33
--- /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 9feda3ad6..a9c2088ff 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 72d2c610e..771982fa8 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 974789ce7..8beb6bf8c 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 b427e9c0a..a9f5c4577 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 4f484aa6b..bdf8f5bab 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 ac6f062f8..3a3e00635 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 1b84c4c80..2af2dfffa 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 d8922b223..360d3e908 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 125d63b94..8d91f4367 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 a97430632..752f1d062 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 370b52d44..07ddb1aaa 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 9e82cb111..70d67e481 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 f165f27f5..d52c55acf 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 37125cdcc..a2d2eca92 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 5311c92e0..46f0b6079 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 cdce81c61..43d9c227b 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 938fb2527..3c8a0020a 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 000000000..aed338f40
--- /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 e8d63257a..64889f15e 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 6e51e9fbe..491692057 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 ad95b6137..55de9030f 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 e44e7dbf3..4d1661f99 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 ff5d41e95..b6e91b8aa 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 000000000..5dbf16450
--- /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_ */