diff --git a/configure.ac b/configure.ac index c75bee31e..33fb74625 100644 --- a/configure.ac +++ b/configure.ac @@ -3882,6 +3882,39 @@ AC_ARG_WITH([cavium-v], ) +# Cavium Octeon +OCTEON_ROOT="" + +AC_ARG_WITH([octeon-sync], + [AS_HELP_STRING([--with-octeon-sync=PATH],[PATH to Cavium Octeon SDK dir (sync)])], + [ + AC_MSG_CHECKING([for octeon]) + + if test "x$withval" = "xyes" ; then + AC_MSG_ERROR([need a PATH for --with-octeon]) + fi + if test "x$withval" != "xno" ; then + OCTEON_ROOT=$withval + fi + + AM_CFLAGS="$AM_CFLAGS -DHAVE_CAVIUM_OCTEON_SYNC" + AM_CFLAGS="$AM_CFLAGS -DOCTEON_MODEL=$OCTEON_MODEL -DCVMX_BUILD_FOR_LINUX_HOST" + AM_CFLAGS="$AM_CFLAGS -I$OCTEON_ROOT/executive" + + #-I$OCTEON_ROOT/target/include + LDFLAGS="$LDFLAGS -lrt -Xlinker -T -Xlinker $OCTEON_ROOT/executive/cvmx-shared-linux.ld" + LIBS="$LIBS $OCTEON_ROOT/executive/obj-octeon3/libcvmx.a $OCTEON_ROOT/executive/obj-octeon3/libfdt.a" + + enable_shared=no + enable_static=yes + + ENABLED_OCTEON_SYNC=yes + AC_MSG_RESULT([yes]) + ], + [ENABLED_OCTEON_SYNC=no] +) + + # Intel QuickAssist QAT_DIR="" BUILD_INTEL_QAT_VERSION=2 @@ -4580,9 +4613,10 @@ AS_IF([test "x$ENABLED_OCSP" = "xyes" && \ test "x$ENABLED_ECC" = "xno"], [AC_MSG_ERROR([please enable rsa or ecc if enabling ocsp.])]) -# Sync Intel QA requires the crypto callback -AS_IF([test "x$ENABLED_CRYPTOCB" = "xno" && test "x$ENABLED_INTEL_QA_SYNC" = "xyes"], - [AC_MSG_ERROR([please enable the crypto callback support using --enable-cryptocb])]) +# Sync Intel QA and Sync Cavium Octeon require the crypto callback +AS_IF([test "x$ENABLED_INTEL_QA_SYNC" = "xyes" || test "x$ENABLED_OCTEON_SYNC" = "xyes"], + [AS_IF([test "x$ENABLED_CRYPTOCB" = "xno"], + [AC_MSG_ERROR([please enable the crypto callback support using --enable-cryptocb])])]) # checks for pkcs7 needed enables AS_IF([test "x$ENABLED_PKCS7" = "xyes" && \ @@ -4900,6 +4934,7 @@ AM_CONDITIONAL([BUILD_LIBZ],[test "x$ENABLED_LIBZ" = "xyes"]) AM_CONDITIONAL([BUILD_PKCS11],[test "x$ENABLED_PKCS11" = "xyes"]) AM_CONDITIONAL([BUILD_CAVIUM],[test "x$ENABLED_CAVIUM" = "xyes"]) AM_CONDITIONAL([BUILD_CAVIUM_V],[test "x$ENABLED_CAVIUM_V" = "xyes"]) +AM_CONDITIONAL([BUILD_OCTEON_SYNC],[test "x$ENABLED_OCTEON_SYNC" = "xyes"]) AM_CONDITIONAL([BUILD_INTEL_QA],[test "x$ENABLED_INTEL_QA" = "xyes"]) AM_CONDITIONAL([BUILD_INTEL_QA_SYNC],[test "x$ENABLED_INTEL_QA_SYNC" = "xyes"]) AM_CONDITIONAL([BUILD_SP],[test "x$ENABLED_SP" = "xyes"]) @@ -5191,16 +5226,17 @@ echo " * Single Precision: $ENABLED_SP" echo " * Async Crypto: $ENABLED_ASYNCCRYPT" echo " * PKCS#11: $ENABLED_PKCS11" echo " * PKCS#12: $ENABLED_PKCS12" -echo " * Cavium: $ENABLED_CAVIUM" +echo " * Cavium Nitox: $ENABLED_CAVIUM" +echo " * Cavium Octeon (Sync): $ENABLED_OCTEON_SYNC" +echo " * Intel Quick Assist: $ENABLED_INTEL_QA" echo " * ARM ASM: $ENABLED_ARMASM" echo " * AES Key Wrap: $ENABLED_AESKEYWRAP" echo " * Write duplicate: $ENABLED_WRITEDUP" -echo " * Intel Quick Assist: $ENABLED_INTEL_QA" echo " * Xilinx Hardware Acc.: $ENABLED_XILINX" echo " * Inline Code: $ENABLED_INLINE" echo " * Linux AF_ALG: $ENABLED_AFALG" echo " * Linux devcrypto: $ENABLED_DEVCRYPTO" -echo " * Crypto callback: $ENABLED_CRYPTOCB" +echo " * Crypto callbacks: $ENABLED_CRYPTOCB" echo "" echo "---" diff --git a/src/sniffer.c b/src/sniffer.c index bad212021..12fd113d8 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1457,7 +1457,8 @@ static int CreateWatchSnifferServer(char* error) return -1; } #ifdef WOLF_CRYPTO_CB - wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDevId); + if (CryptoDevId != INVALID_DEVID) + wolfSSL_CTX_SetDevId(sniffer->ctx, CryptoDevId); #endif ServerList = sniffer; diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 33e2bd536..2e13b27e4 100755 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -172,6 +172,13 @@ #include #include +#ifdef WOLF_CRYPTO_CB + #include + #ifdef HAVE_CAVIUM_OCTEON_SYNC + #include + #endif +#endif + #ifdef WOLFSSL_ASYNC_CRYPT #include #endif @@ -683,6 +690,10 @@ static const char* bench_result_words2[][5] = { /* Asynchronous helper macros */ static THREAD_LS_T int devId = INVALID_DEVID; +#if defined(WOLF_CRYPTO_CB) && defined(HAVE_INTEL_QA_SYNC) + static THREAD_LS_T IntelQaDev devQat; +#endif + #ifdef WOLFSSL_ASYNC_CRYPT static WOLF_EVENT_QUEUE eventQueue; @@ -1288,6 +1299,39 @@ static void* benchmarks_do(void* args) } #endif +#ifdef WOLF_CRYPTO_CB +#ifdef HAVE_INTEL_QA_SYNC + { + int rc; + devId = IntelQaInit(NULL); + if (devId == INVALID_DEVID) { + WOLFSSL_MSG("Couldn't init the Intel QA"); + } + rc = IntelQaOpen(&devQat, devId); + if (rc != 0) { + WOLFSSL_MSG("Couldn't open the device"); + } + rc = wc_CryptoCb_RegisterDevice(devId, + IntelQaSymSync_CryptoDevCb, &devQat); + if (rc != 0) { + WOLFSSL_MSG("Couldn't register the device"); + } + } +#endif +#ifdef HAVE_CAVIUM_OCTEON_SYNC + { + devId = wc_CryptoCb_GetDevIdOcteon(); + if (devId == INVALID_DEVID) { + printf("Couldn't get the Octeon device ID\n"); + } + if (wc_CryptoCb_InitOcteon() != 0) { + printf("Couldn't init the Cavium Octeon\n"); + devId = INVALID_DEVID; + } + } +#endif +#endif + #if defined(HAVE_LOCAL_RNG) { int rngRet; @@ -1356,7 +1400,8 @@ static void* benchmarks_do(void* args) #ifndef NO_SW_BENCH bench_aescbc(0); #endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) && \ + #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \ + defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC)) && \ !defined(NO_HW_BENCH) bench_aescbc(1); #endif @@ -1367,7 +1412,8 @@ static void* benchmarks_do(void* args) #ifndef NO_SW_BENCH bench_aesgcm(0); #endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) && \ + #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \ + defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC)) && \ !defined(NO_HW_BENCH) bench_aesgcm(1); #endif @@ -1438,7 +1484,8 @@ static void* benchmarks_do(void* args) #ifndef NO_SW_BENCH bench_des(0); #endif - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES) && \ + #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \ + defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC)) && \ !defined(NO_HW_BENCH) bench_des(1); #endif @@ -1775,6 +1822,17 @@ exit: XFREE(bench_iv, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT); #endif +#ifdef WOLF_CRYPTO_CB +#ifdef HAVE_INTEL_QA_SYNC + wc_CryptoCb_UnRegisterDevice(CryptoDeviceId); + IntelQaClose(&CryptoDevice); + IntelQaDeInit(CryptoDeviceId); +#endif +#ifdef HAVE_CAVIUM_OCTEON_SYNC + wc_CryptoCb_CleanupOcteon(); +#endif +#endif + #ifdef WOLFSSL_ASYNC_CRYPT /* free event queue */ wolfEventQueue_Free(&eventQueue); diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 5e7c8fb23..a9ba73007 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -44,7 +44,7 @@ typedef struct CryptoCb { CryptoDevCallbackFunc cb; void* ctx; } CryptoCb; -static CryptoCb gCryptoDev[MAX_CRYPTO_DEVID_CALLBACKS]; +static WOLFSSL_GLOBAL CryptoCb gCryptoDev[MAX_CRYPTO_DEVID_CALLBACKS]; static CryptoCb* wc_CryptoCb_FindDevice(int devId) { diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index eae62a108..67cc0003a 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -105,6 +105,11 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c endif EXTRA_DIST += wolfcrypt/src/port/cavium/README.md +if BUILD_OCTEON_SYNC +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_octeon_sync.c +endif +EXTRA_DIST += wolfcrypt/src/port/cavium/README_Octeon.md + if BUILD_INTEL_QA src_libwolfssl_la_SOURCES += wolfcrypt/src/port/intel/quickassist.c src_libwolfssl_la_SOURCES += wolfcrypt/src/port/intel/quickassist_mem.c diff --git a/wolfcrypt/src/port/cavium/README_Octeon.md b/wolfcrypt/src/port/cavium/README_Octeon.md new file mode 100644 index 000000000..093e675c1 --- /dev/null +++ b/wolfcrypt/src/port/cavium/README_Octeon.md @@ -0,0 +1,150 @@ +# Octeon III + +Guide for setting up wolfSSL on the Octeon III CN7300 + +## Octeon SDK + +```sh +sudo yum install libuuid-devel +sudo yum install perl-Env + +sudo rpm -i OCTEON-SDK-5.1.0-609.x86_64.rpm +``` + +The OCTEON-SDK package has been successfully installed under the +/usr/local/Cavium_Networks directory. + +The installation requires the OCTEON_MODEL environment variable +to be set. To set this environment variable, cd to the +/usr/local/Cavium_Networks/OCTEON-SDK directory, and invoke + + source env-setup + +script. Valid OCTEON_MODELs are listed in octeon-models.txt file +under OCTEON-SDK directory. + +You may want to copy the OCTEON-SDK package to your home directory to allow +modification without root privileges. + +For more information please refer to the online SDK documentation: +file:///usr/local/Cavium_Networks/OCTEON-SDK/docs/html/index.html + +```sh +sudo rpm -i OCTEON-CRYPTO-CORE-5.1.0-01.x86_64.rpm +``` + +The OCTEON-CRYPTO-CORE is installed under +/usr/local/Cavium_Networks/OCTEON-SDK/components/crypto-api/core directory. +This package installs the following sources. + * Crypto-Core API Sources + * Sample Crypto-Core Test Applications + +Please refer to following documentation under +/usr/local/Cavium_Networks/OCTEON-SDK/components/crypto-api/core directory + * README.txt - contains build instructions and other details + * Release_Notes.txt - contains change history + +```sh +sudo rpm -i OCTEON-LINUX-5.1.0-609.x86_64.rpm +``` + +The Linux Kernel has been successfully installed under the directory +/usr/local/Cavium_Networks/OCTEON-SDK/linux + +Please refer to file:///usr/local/Cavium_Networks/OCTEON-SDK/docs/html/linux.html +on how to use Linux on the OCTEON. + + +Final Setup: + +```sh +cp -r /usr/local/Cavium_Networks/OCTEON-SDK/ ~ +cd OCTEON-SDK +source env-setup OCTEON_CN73XX + +cd examples +make +``` + +Note: You must run `source env-setup OCTEON_CN73XX` anytime a new shell is opened to setup the build environment. + +## Building Linux (Busybox) + +```sh +cd $OCTEON_ROOT/linux +make clean +cd embedded_rootfs +make menuconfig +cd .. +make kernel +make strip + +cp ./kernel/linux/vmlinux.64 /run/media/dgarske/9016-4EF8/ +``` + +``` +telnet 192.168.0.114 9761 + +fatls mmc 0 +fatload mmc 0 $(loadaddr) vmlinux.64 +bootoctlinux $(loadaddr) coremask=0x1 root=/dev/sda2 mem=0 +``` + +Shortcut macro from U-Boot: + +``` +linux_mmc=fatload mmc 0 $(loadaddr) vmlinux.64;bootoctlinux $(loadaddr) coremask=0xffff root=/dev/sda2 mem=0 +run linux_mmc +``` + +## Building Linux Debian + +```sh +cd linux +make kernel-deb +cd debian +sudo -E make DISK=/dev/sdc compact-flash +``` +modprobe octeon-ethernet + + +## wolfSSL Building for Octeon + +```sh +cd examples +ln -s ../../wolfssl wolfssl +cd wolfssl +./autogen.sh +./configure --host=mips64 CC="mips64-octeon-linux-gnu-gcc -mabi=64" --with-octeon=/home/dgarske/OCTEON-SDK --enable-des3 --enable-cryptocb CFLAGS="-DWOLFSSL_AES_DIRECT" +make + +``` + +Installing to USB media for use on Octeon Board: + +```sh +cp -r src /run/media/dgarske/OCTEON/ +cp -r wolfcrypt/ /run/media/dgarske/OCTEON/ +cp -r wolfssl /run/media/dgarske/OCTEON/ +cp -r certs /run/media/dgarske/OCTEON/ +``` + + +## Remote Access + +### UART and Telnet + +Device ID (MAC): +EBB7304_DEFAULT D8-80-39-7D-6D-0B + +Telnet Ports: +telnet 192.168.0.114 9760 +telnet 192.168.0.114 9761 + +Setting Date: +date 070216502019 + + +## Support + +For questions please email wolfSSL at support@wolfssl.com diff --git a/wolfcrypt/src/port/cavium/cavium_octeon_sync.c b/wolfcrypt/src/port/cavium/cavium_octeon_sync.c new file mode 100644 index 000000000..dc7577111 --- /dev/null +++ b/wolfcrypt/src/port/cavium/cavium_octeon_sync.c @@ -0,0 +1,995 @@ +/* cavium_octeon.c + * + * Copyright(C) 2006-2019 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 3 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 +#include +#include + +#ifdef HAVE_CAVIUM_OCTEON_SYNC + +/* Setting NO_MAIN_DRIVER here because this file ends up building + * in the library sources which doesn't have NO_MAIN_DRIVER set, + * as the library expects main to be somehwere else. */ +#undef NO_MAIN_DRIVER +#define NO_MAIN_DRIVER + +#include + +static int devId = 1234; + +#ifndef NO_DES3 +int Octeon_Des3_CbcEncrypt(Des3* des3, uint64_t *inp64, uint64_t *outp64, size_t inl) +{ + register uint64_t i0, r0; + uint64_t *key, *iv; + + if (des3 == NULL || inp64 == NULL || outp64 == NULL) + return BAD_FUNC_ARG; + + /* expects 64-bit aligned value */ + key = (uint64_t*)des3->devKey; + CVMX_MT_3DES_KEY(key[0], 0); + CVMX_MT_3DES_KEY(key[1], 1); + CVMX_MT_3DES_KEY(key[2], 2); + iv = (uint64_t*)des3->reg; + CVMX_MT_3DES_IV(iv[0]); + + CVMX_PREFETCH0(inp64); + + i0 = *inp64; + + /* DES3 assembly can handle 16-byte chunks */ + if (inl >= 16) { + CVMX_MT_3DES_ENC_CBC(i0); + inl -= 8; + inp64++; + outp64++; + + if (inl >= 8) { + i0 = inp64[0]; + CVMX_MF_3DES_RESULT(r0); + CVMX_MT_3DES_ENC_CBC(i0); + + for (;;) { + outp64[-1] = r0; + inl -= 8; + inp64++; + outp64++; + i0 = *inp64; + + if (inl < 8) + break; + + CVMX_PREFETCH(inp64, 64); + CVMX_MF_3DES_RESULT(r0); + CVMX_MT_3DES_ENC_CBC(i0); + } + } + CVMX_MF_3DES_RESULT(r0); + outp64[-1] = r0; + } + /* remainder */ + if (inl > 0) { + uint64_t r = 0; + if (inl <= 8) { + XMEMCPY(&r, inp64, inl); + CVMX_MT_3DES_ENC_CBC(r); + CVMX_MF_3DES_RESULT(*outp64); + } + else { + i0 = *inp64; + CVMX_MT_3DES_ENC_CBC(i0); + CVMX_MF_3DES_RESULT(*outp64); + inp64++, outp64++; + + XMEMCPY(&r, inp64, inl); + CVMX_MT_3DES_ENC_CBC(r); + CVMX_MF_3DES_RESULT(*outp64); + } + } + + CVMX_MT_3DES_IV(iv[0]); + + return 0; +} + +int Octeon_Des3_CbcDecrypt(Des3* des3, uint64_t *inp64, uint64_t *outp64, size_t inl) +{ + register uint64_t i0, r0; + uint64_t *key, *iv; + + if (des3 == NULL || inp64 == NULL || outp64 == NULL) + return BAD_FUNC_ARG; + + /* expects 64-bit aligned value */ + key = (uint64_t*)des3->devKey; + CVMX_MT_3DES_KEY(key[0], 0); + CVMX_MT_3DES_KEY(key[1], 1); + CVMX_MT_3DES_KEY(key[2], 2); + + iv = (uint64_t*)des3->reg; + CVMX_MT_3DES_IV(iv[0]); + + CVMX_PREFETCH0(inp64); + + i0 = *inp64; + + /* DES3 assembly can handle 16-byte chunks */ + if (inl >= 16) { + CVMX_MT_3DES_DEC_CBC(i0); + inl -= 8; + inp64++; + outp64++; + + if (inl >= 8) { + i0 = inp64[0]; + CVMX_MF_3DES_RESULT(r0); + CVMX_MT_3DES_DEC_CBC(i0); + + for (;;) { + outp64[-1] = r0; + inl -= 8; + inp64++; + outp64++; + i0 = *inp64; + + if (inl < 8) + break; + + CVMX_PREFETCH(inp64, 64); + CVMX_MF_3DES_RESULT(r0); + CVMX_MT_3DES_DEC_CBC(i0); + } + } + + CVMX_MF_3DES_RESULT(r0); + outp64[-1] = r0; + } + /* remainder */ + if (inl > 0) { + if (inl <= 8) { + uint64_t r = 0; + XMEMCPY(&r, inp64, inl); + CVMX_MT_3DES_DEC_CBC(r); + CVMX_MF_3DES_RESULT(*outp64); + } + else { + uint64_t r = 0; + i0 = *inp64; + CVMX_MT_3DES_DEC_CBC(i0); + CVMX_MF_3DES_RESULT(*outp64); + inp64++, outp64++; + + XMEMCPY(&r, inp64, inl); + CVMX_MT_3DES_DEC_CBC(r); + CVMX_MF_3DES_RESULT(*outp64); + } + } + + CVMX_MT_3DES_IV(iv[0]); + + return 0; +} +#endif /* !NO_DES3 */ + + +#ifndef NO_AES + +#ifdef WOLFSSL_AES_DIRECT +/* Perform Single Block ECB Encrypt */ +int Octeon_AesEcb_Encrypt(Aes* aes, const unsigned char *in, unsigned char *out) +{ + uint64_t *in64, *out64, *key; + + if (aes == NULL || in == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + + key = (uint64_t*)aes->devKey; + CVMX_MT_AES_KEY(key[0], 0); + CVMX_MT_AES_KEY(key[1], 1); + CVMX_MT_AES_KEY(key[2], 2); + CVMX_MT_AES_KEY(key[3], 3); + CVMX_MT_AES_KEYLENGTH(aes->keylen/8 - 1); + + in64 = (uint64_t*)in; + out64 = (uint64_t*)out; + + CVMX_MT_AES_ENC0(in64[0]); + CVMX_MT_AES_ENC1(in64[1]); + CVMX_MF_AES_RESULT(out64[0],0); + CVMX_MF_AES_RESULT(out64[1],1); + + return 0; +} + +/* Perform Single Block ECB Decrypt */ +int Octeon_AesEcb_Decrypt(Aes* aes, const unsigned char *in, unsigned char *out) +{ + uint64_t *in64, *out64, *key; + + if (aes == NULL || in == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + + key = (uint64_t*)aes->devKey; + CVMX_MT_AES_KEY(key[0], 0); + CVMX_MT_AES_KEY(key[1], 1); + CVMX_MT_AES_KEY(key[2], 2); + CVMX_MT_AES_KEY(key[3], 3); + CVMX_MT_AES_KEYLENGTH(aes->keylen/8 - 1); + + in64 = (uint64_t*)in; + out64 = (uint64_t*)out; + CVMX_MT_AES_DEC0(in64[0]); + CVMX_MT_AES_DEC1(in64[1]); + CVMX_MF_AES_RESULT(out64[0],0); + CVMX_MF_AES_RESULT(out64[1],1); + + return 0; +} +#endif /* WOLFSSL_AES_DIRECT */ + +#ifdef HAVE_AES_CBC +int Octeon_AesCbc_Encrypt(Aes *aes, uint64_t *inp64, uint64_t *outp64, size_t inl) +{ + register uint64_t i0, i1, r0, r1; + uint64_t *key, *iv; + + if (aes == NULL || inp64 == NULL || outp64 == NULL) { + return BAD_FUNC_ARG; + } + + iv = (uint64_t*)aes->reg; + CVMX_MT_AES_IV(iv[0], 0); + CVMX_MT_AES_IV(iv[1], 1); + + key = (uint64_t*)aes->devKey; + CVMX_MT_AES_KEY(key[0], 0); + CVMX_MT_AES_KEY(key[1], 1); + CVMX_MT_AES_KEY(key[2], 2); + CVMX_MT_AES_KEY(key[3], 3); + + CVMX_MT_AES_KEYLENGTH(aes->keylen/8 - 1); + + CVMX_PREFETCH0(inp64); + + i0 = inp64[0]; + i1 = inp64[1]; + + /* AES assembly can handle 32-byte chunks */ + if (inl >= 32) { + CVMX_MT_AES_ENC_CBC0(i0); + CVMX_MT_AES_ENC_CBC1(i1); + inl -= 16; + inp64 += 2; + outp64 += 2; + + if (inl >= 16) { + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + i0 = inp64[0]; + i1 = inp64[1]; + CVMX_MT_AES_ENC_CBC0(i0); + CVMX_MT_AES_ENC_CBC1(i1); + + for (;;) { + outp64[-2] = r0; + outp64[-1] = r1; + outp64 += 2; + inp64 += 2; + inl -= 16; + i0 = inp64[0]; + i1 = inp64[1]; + + if (inl < 16) + break; + + CVMX_PREFETCH(inp64, 64); + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + CVMX_MT_AES_ENC_CBC0(i0); + CVMX_MT_AES_ENC_CBC1(i1); + } + } + + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + outp64[-2] = r0; + outp64[-1] = r1; + } + /* remainder */ + if (inl > 0) { + uint64_t in64[2] = { 0, 0 }; + if (inl <= 16) { + XMEMCPY(in64, inp64, inl); + CVMX_MT_AES_ENC_CBC0(in64[0]); + CVMX_MT_AES_ENC_CBC1(in64[1]); + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + outp64[0] = r0; + outp64[1] = r1; + } + else { + CVMX_MT_AES_ENC_CBC0(i0); + CVMX_MT_AES_ENC_CBC1(i1); + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + inl -= 16; + outp64[0] = r0; + outp64[1] = r1; + inp64 += 2; + outp64 += 2; + XMEMCPY(in64, inp64, inl); + CVMX_MT_AES_ENC_CBC0(in64[0]); + CVMX_MT_AES_ENC_CBC1(in64[1]); + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + outp64[0] = r0; + outp64[1] = r1; + } + } + + CVMX_MF_AES_IV(iv[0], 0); + CVMX_MF_AES_IV(iv[1], 1); + + return 0; +} + +int Octeon_AesCbc_Decrypt(Aes *aes, uint64_t *inp64, uint64_t *outp64, size_t inl) +{ + register uint64_t i0, i1, r0, r1; + uint64_t *key, *iv; + + if (aes == NULL || inp64 == NULL || outp64 == NULL) { + return BAD_FUNC_ARG; + } + + iv = (uint64_t*)aes->reg; + key = (uint64_t*)aes->devKey; + + CVMX_MT_AES_IV(iv[0], 0); + CVMX_MT_AES_IV(iv[1], 1); + + CVMX_MT_AES_KEY(key[0], 0); + CVMX_MT_AES_KEY(key[1], 1); + CVMX_MT_AES_KEY(key[2], 2); + CVMX_MT_AES_KEY(key[3], 3); + CVMX_MT_AES_KEYLENGTH(aes->keylen/8 - 1); + + CVMX_PREFETCH0(inp64); + + i0 = inp64[0]; + i1 = inp64[1]; + + /* AES assembly can handle 32-byte chunks */ + if (inl >= 32) { + CVMX_MT_AES_DEC_CBC0(i0); + CVMX_MT_AES_DEC_CBC1(i1); + inp64 += 2; + outp64 += 2; + inl -= 16; + + if (inl >= 16) { + i0 = inp64[0]; + i1 = inp64[1]; + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + CVMX_MT_AES_DEC_CBC0(i0); + CVMX_MT_AES_DEC_CBC1(i1); + + for (;;) { + outp64[-2] = r0; + outp64[-1] = r1; + outp64 += 2; + inp64 += 2; + inl -= 16; + i0 = inp64[0]; + i1 = inp64[1]; + + if (inl < 16) + break; + + CVMX_PREFETCH(inp64, 64); + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + CVMX_MT_AES_DEC_CBC0(i0); + CVMX_MT_AES_DEC_CBC1(i1); + } + } + + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + outp64[-2] = r0; + outp64[-1] = r1; + } + /* remainder */ + if (inl > 0) { + uint64_t in64[2] = { 0, 0 }; + XMEMCPY(in64, inp64, inl); + CVMX_MT_AES_DEC_CBC0(in64[0]); + CVMX_MT_AES_DEC_CBC1(in64[1]); + CVMX_MF_AES_RESULT(r0, 0); + CVMX_MF_AES_RESULT(r1, 1); + outp64[0] = r0; + outp64[1] = r1; + } + + CVMX_MF_AES_IV(iv[0], 0); + CVMX_MF_AES_IV(iv[1], 1); + + return 0; +} +#endif /* HAVE_AES_CBC */ + + +#ifdef HAVE_AESGCM + +#define CVM_AES_RD_RESULT_WR_DATA(in1, in2, out1, out2) \ + asm volatile(\ + ".set noreorder \n" \ + "dmfc2 %[r1],0x0100\n" \ + "dmfc2 %[r2],0x0101\n" \ + "dmtc2 %[r3],0x010a\n" \ + "dmtc2 %[r4],0x310b\n" \ + ".set reorder \n" \ + : [r1] "=&d"(in1) , [r2] "=&d"(in2) \ + : [r3] "d"(out1), [r4] "d"(out2)) + +static inline void Octeon_GHASH_Restore(word16 poly, byte* h) +{ + word64* bigH = (word64*)h; + CVMX_MT_GFM_POLY((word64)poly); + CVMX_MT_GFM_MUL(bigH[0], 0); + CVMX_MT_GFM_MUL(bigH[1], 1); +} + + +static inline void Octeon_GHASH_Init(word16 poly, byte* h) +{ + Octeon_GHASH_Restore(poly, h); + CVMX_MT_GFM_RESINP(0, 0); + CVMX_MT_GFM_RESINP(0, 1); +} + + +static inline void Octeon_GHASH_Update(byte* in) +{ + word64* bigIn = (word64*)in; + CVMX_MT_GFM_XOR0(bigIn[0]); + CVMX_MT_GFM_XORMUL1(bigIn[1]); +} + + +static inline void Octeon_GHASH_Final(byte* out, word64 authInSz, word64 inSz) +{ + word64* bigOut = (word64*)out; + + CVMX_MT_GFM_XOR0(authInSz); + CVMX_MT_GFM_XORMUL1(inSz); + CVMX_MF_GFM_RESINP(bigOut[0], 0); + CVMX_MF_GFM_RESINP(bigOut[1], 1); +} + + +/* Sets the Octeon key with the key found in the Aes record. */ +static int Octeon_AesGcm_SetKey(Aes* aes) +{ + int ret = 0; + + if (aes == NULL) + ret = BAD_FUNC_ARG; + + if (ret != 0) { + word32* key = (word32*)aes->devKey; + + CVMX_MT_AES_KEY(key[0], 0); + CVMX_MT_AES_KEY(key[1], 1); + CVMX_MT_AES_KEY(key[2], 2); + CVMX_MT_AES_KEY(key[3], 3); + CVMX_MT_AES_KEYLENGTH((aes->keylen / 8) - 1); + } + + return ret; +} + + +static int Octeon_AesGcm_SetIV(Aes* aes, byte* iv, word32 ivSz) +{ + int ret = 0; + + if (aes == NULL || iv == NULL) + ret = BAD_FUNC_ARG; + + if (ret == 0) { + if (ivSz == GCM_NONCE_MID_SZ) { + XMEMSET((byte*)aes->reg, 0, sizeof(aes->reg)); + XMEMCPY((byte*)aes->reg, iv, ivSz); + aes->reg[3] = 1; + } + else { + int blocks, remainder, i; + byte aesBlock[AES_BLOCK_SIZE]; + + blocks = ivSz / AES_BLOCK_SIZE; + remainder = ivSz % AES_BLOCK_SIZE; + + for (i = 0; i < blocks; i++, iv += AES_BLOCK_SIZE) + Octeon_GHASH_Update(iv); + + XMEMSET(aesBlock, 0, sizeof(aesBlock)); + for (i = 0; i < remainder; i++) + aesBlock[i] = iv[i]; + Octeon_GHASH_Update(aesBlock); + + Octeon_GHASH_Final((byte*)aes->reg, 0, ivSz); + } + + aes->y0 = aes->reg[3]; + aes->reg[3]++; + + Octeon_GHASH_Init(0xe100, aes->H); + } + + return ret; +} + + +static int Octeon_AesGcm_SetAAD(Aes* aes, byte* aad, word32 aadSz) +{ + word64* p; + ALIGN16 byte aesBlock[AES_BLOCK_SIZE]; + int blocks, remainder, i; + + if (aes == NULL || (aadSz != 0 && aad == NULL)) + return BAD_FUNC_ARG; + + if (aadSz == 0) + return 0; + + blocks = aadSz / AES_BLOCK_SIZE; + remainder = aadSz % AES_BLOCK_SIZE; + + Octeon_GHASH_Restore(0xe100, aes->H); + + p = (word64*)aesBlock; + + for (i = 0; i < blocks; i++, aad += AES_BLOCK_SIZE) { + CVMX_LOADUNA_INT64(p[0], aad, 0); + CVMX_LOADUNA_INT64(p[1], aad, 8); + CVMX_MT_GFM_XOR0(p[0]); + CVMX_MT_GFM_XORMUL1(p[1]); + } + + XMEMSET(aesBlock, 0, sizeof(aesBlock)); + + for (i = 0; i < remainder; i++) + aesBlock[i] = aad[i]; + + CVMX_MT_GFM_XOR0(p[0]); + CVMX_MT_GFM_XORMUL1(p[1]); + + return 0; +} + + +static int Octeon_AesGcm_SetEncrypt(Aes* aes, byte* in, byte* out, word32 inSz, + int encrypt) +{ + word32 i, blocks, remainder; + ALIGN16 byte aesBlockIn[AES_BLOCK_SIZE]; + ALIGN16 byte aesBlockOut[AES_BLOCK_SIZE]; + ALIGN16 byte aesBlockMask[AES_BLOCK_SIZE]; + word64* pIn; + word64* pOut; + word64* pIv; + + if (aes == NULL || in == NULL || out == NULL) + return BAD_FUNC_ARG; + + pIn = (word64*)aesBlockIn; + pOut = (word64*)aesBlockOut; + pIv = (word64*)aes->reg; + + CVMX_PREFETCH0(in); + + CVMX_MT_AES_ENC0(&pIv[0]); + CVMX_MT_AES_ENC1(&pIv[1]); + + blocks = inSz / AES_BLOCK_SIZE; + remainder = inSz % AES_BLOCK_SIZE; + + for (i = 0; i < blocks; + i++, in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE) { + CVMX_PREFETCH128(in); + aes->reg[3]++; + + CVMX_LOADUNA_INT64(pIn[0], in, 0); + CVMX_LOADUNA_INT64(pIn[1], in, 8); + + CVM_AES_RD_RESULT_WR_DATA(pOut[0], pOut[1], pIv[0], pIv[1]); + + if (encrypt) { + pOut[0] ^= pIn[0]; + pOut[1] ^= pIn[1]; + CVMX_MT_GFM_XOR0(pOut[0]); + CVMX_MT_GFM_XORMUL1(pOut[1]); + } + else { + CVMX_MT_GFM_XOR0(pOut[0]); + CVMX_MT_GFM_XORMUL1(pOut[1]); + pOut[0] ^= pIn[0]; + pOut[1] ^= pIn[1]; + } + + CVMX_STOREUNA_INT64(pOut[0], out, 0); + CVMX_STOREUNA_INT64(pOut[1], out, 8); + } + + XMEMSET(aesBlockMask, 0, sizeof(aesBlockMask)); + for (i = 0; i < remainder; i++) { + aesBlockIn[i] = in[i]; + aesBlockMask[i] = 0xff; + } + + if (encrypt) { + CVMX_MF_AES_RESULT(pOut[0], 0); + CVMX_MF_AES_RESULT(pOut[1], 1); + + pOut[0] ^= pIn[0]; + pOut[1] ^= pIn[1]; + + pIv = (word64*)aesBlockMask; + pOut[0] &= pIv[0]; + pOut[1] &= pIv[1]; + + CVMX_MT_GFM_XOR0(pOut[0]); + CVMX_MT_GFM_XORMUL1(pOut[1]); + } + else { + CVMX_MT_GFM_XOR0(pIn[0]); + CVMX_MT_GFM_XORMUL1(pIn[1]); + + CVMX_MF_AES_RESULT(pOut[0], 0); + CVMX_MF_AES_RESULT(pOut[1], 1); + + pOut[0] ^= pIn[0]; + pOut[1] ^= pIn[1]; + + pIv = (word64*)aesBlockMask; + pOut[0] &= pIv[0]; + pOut[1] &= pIv[1]; + } + + for (i = 0; i < remainder; i++) + out[i] = aesBlockOut[i]; + + return 0; +} + + +static int Octeon_AesGcm_Finalize(Aes* aes, word32 inSz, word32 aadSz, + byte* tag) +{ + word64 bigSz; + word64* pIv; + word64* pIn; + word64* pOut; + uint32_t countSave; + ALIGN16 byte aesBlockIn[AES_BLOCK_SIZE]; + ALIGN16 byte aesBlockOut[AES_BLOCK_SIZE]; + + countSave = aes->reg[3]; + aes->reg[3] = aes->y0; + + pIv = (word64*)aes->reg; + CVMX_MT_AES_ENC0(pIv[0]); + CVMX_MT_AES_ENC1(pIv[1]); + + bigSz = (word64)aadSz * 8; + CVMX_MT_GFM_XOR0(bigSz); + bigSz = (word64)inSz * 8; + CVMX_MT_GFM_XORMUL1(bigSz); + + aes->reg[3] = countSave; + + pIn = (word64*)aesBlockIn; + CVMX_MF_AES_RESULT(pIn[0], 0); + CVMX_MF_AES_RESULT(pIn[1], 1); + + pOut = (word64*)aesBlockOut; + CVMX_MF_GFM_RESINP(pOut[0], 0); + CVMX_MF_GFM_RESINP(pOut[1], 1); + + pOut[0] ^= pIn[0]; + pOut[1] ^= pIn[1]; + + CVMX_STOREUNA_INT64(pOut[0], tag, 0); + CVMX_STOREUNA_INT64(pOut[1], tag, 8); + + return 0; +} + + +int Octeon_AesGcm_Encrypt(Aes* aes, byte* in, byte* out, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, byte* tag) +{ + int ret = 0; + + if (aes == NULL) + ret = BAD_FUNC_ARG; + + if (ret == 0) + ret = Octeon_AesGcm_SetKey(aes); + + if (ret == 0) + ret = Octeon_AesGcm_SetIV(aes, iv, ivSz); + + if (ret == 0) + ret = Octeon_AesGcm_SetAAD(aes, aad, aadSz); + + if (ret == 0) + ret = Octeon_AesGcm_SetEncrypt(aes, in, out, inSz, 1); + + if (ret == 0) + ret = Octeon_AesGcm_Finalize(aes, inSz, aadSz, tag); + + return ret; +} + + +int Octeon_AesGcm_Decrypt(Aes* aes, byte* in, byte* out, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, byte* tag) +{ + int ret = 0; + + if (aes == NULL) + ret = BAD_FUNC_ARG; + + if (ret == 0) + ret = Octeon_AesGcm_SetKey(aes); + + if (ret == 0) + ret = Octeon_AesGcm_SetIV(aes, iv, ivSz); + + if (ret == 0) + ret = Octeon_AesGcm_SetAAD(aes, aad, aadSz); + + if (ret == 0) + ret = Octeon_AesGcm_SetEncrypt(aes, in, out, inSz, 0); + + if (ret == 0) + ret = Octeon_AesGcm_Finalize(aes, inSz, aadSz, tag); + + return ret; +} + +#endif /* HAVE_AESGCM */ + +#endif /* !NO_AES */ + +#ifdef WOLF_CRYPTO_CB + +#include + + +static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + int ret = NOT_COMPILED_IN; /* return this to bypass HW and use SW */ + + if (info == NULL) + return BAD_FUNC_ARG; + +#ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: Algo Type %d\n", info->algo_type); +#endif + + if (info->algo_type == WC_ALGO_TYPE_CIPHER) { +#if !defined(NO_AES) || !defined(NO_DES3) + #ifdef HAVE_AESGCM + if (info->cipher.type == WC_CIPHER_AES_GCM) { + if (info->cipher.enc) { + ret = Octeon_AesGcm_Encrypt( + info->cipher.aesgcm_enc.aes, + (byte*)info->cipher.aesgcm_enc.in, + (byte*)info->cipher.aesgcm_enc.out, + info->cipher.aesgcm_enc.sz, + (byte*)info->cipher.aesgcm_enc.iv, + info->cipher.aesgcm_enc.ivSz, + (byte*)info->cipher.aesgcm_enc.authIn, + info->cipher.aesgcm_enc.authInSz, + (byte*)info->cipher.aesgcm_enc.authTag); + } + else { + ret = Octeon_AesGcm_Decrypt( + info->cipher.aesgcm_dec.aes, + (byte*)info->cipher.aesgcm_dec.in, + (byte*)info->cipher.aesgcm_dec.out, + info->cipher.aesgcm_dec.sz, + (byte*)info->cipher.aesgcm_dec.iv, + info->cipher.aesgcm_dec.ivSz, + (byte*)info->cipher.aesgcm_dec.authIn, + info->cipher.aesgcm_dec.authInSz, + (byte*)info->cipher.aesgcm_dec.authTag); + } + } + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AES_CBC + if (info->cipher.type == WC_CIPHER_AES_CBC) { + if (info->cipher.enc) { + ret = Octeon_AesCbc_Encrypt( + info->cipher.aescbc.aes, + (word64*)info->cipher.aescbc.in, + (word64*)info->cipher.aescbc.out, + info->cipher.aescbc.sz); + } + else { + ret = Octeon_AesCbc_Decrypt( + info->cipher.aescbc.aes, + (word64*)info->cipher.aescbc.in, + (word64*)info->cipher.aescbc.out, + info->cipher.aescbc.sz); + } + } + #endif /* HAVE_AES_CBC */ + #ifndef NO_DES3 + if (info->cipher.type == WC_CIPHER_DES3) { + if (info->cipher.enc) { + ret = Octeon_Des3_CbcEncrypt( + info->cipher.des3.des, + (word64*)info->cipher.des3.in, + (word64*)info->cipher.des3.out, + info->cipher.des3.sz); + } + else { + ret = Octeon_Des3_CbcDecrypt( + info->cipher.des3.des, + (word64*)info->cipher.des3.in, + (word64*)info->cipher.des3.out, + info->cipher.des3.sz); + } + } + #endif /* !NO_DES3 */ +#endif /* !NO_AES || !NO_DES3 */ + } + + (void)devIdArg; + (void)ctx; + + return ret; +} + +int wc_CryptoCb_InitOcteon(void) +{ + return wc_CryptoCb_RegisterDevice(devId, myCryptoDevCb, NULL); +} + +void wc_CryptoCb_CleanupOcteon(void) +{ + wc_CryptoCb_UnRegisterDevice(devId); +} + +int wc_CryptoCb_GetDevIdOcteon(void) +{ + return devId; +} + +#endif /* WOLF_CRYPTO_CB */ + + +#ifndef NO_MAIN_DRIVER + +#ifndef NO_DES3 +static int des3_test(void) +{ + const byte vector[] = { /* "Now is the time for all " w/o trailing 0 */ + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 + }; + + byte plain[24]; + byte cipher[24]; + + Des3 enc; + Des3 dec; + + const byte key3[] = + { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10, + 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 + }; + const byte iv3[] = + { + 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81 + + }; + + const byte verify3[] = + { + 0x43,0xa0,0x29,0x7e,0xd1,0x84,0xf8,0x0e, + 0x89,0x64,0x84,0x32,0x12,0xd5,0x08,0x98, + 0x18,0x94,0x15,0x74,0x87,0x12,0x7d,0xb0 + }; + + int ret; + + + if (wc_Des3Init(&enc, NULL, devId) != 0) + return -4700; + if (wc_Des3Init(&dec, NULL, devId) != 0) + return -4701; + + ret = wc_Des3_SetKey(&enc, key3, iv3, DES_ENCRYPTION); + if (ret != 0) + return -4702; + ret = wc_Des3_SetKey(&dec, key3, iv3, DES_DECRYPTION); + if (ret != 0) + return -4703; + ret = wc_Des3_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); + if (ret != 0) + return -4704; + ret = wc_Des3_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); + if (ret != 0) + return -4705; + + if (XMEMCMP(plain, vector, sizeof(plain))) + return -4706; + + if (XMEMCMP(cipher, verify3, sizeof(cipher))) + return -4707; + + + wc_Des3Free(&enc); + wc_Des3Free(&dec); + + return 0; +} +#endif /* NO_DES */ + +int main(void) +{ + int ret = 0; + + wolfCrypt_Init(); + + /* The following is called in wolfCrypt_Init(). + wc_CryptoCb_InitOcteon(); + */ + +#ifndef NO_DES3 + des3_test(); +#endif + + wolfCrypt_Cleanup(); + + return ret; +} +#endif /* !NO_MAIN_DRIVER */ + +#endif /* HAVE_CAVIUM_OCTEON_SYNC */ diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index b0b0faf83..f13a23740 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -76,6 +76,9 @@ #ifdef HAVE_INTEL_QA_SYNC #include + +#ifdef HAVE_CAVIUM_OCTEON_SYNC + #include #endif #ifdef _MSC_VER diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index cf25d6249..926a2f547 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -159,6 +159,9 @@ struct Aes { /* key-based fast multiplication table. */ ALIGN16 byte M0[256][AES_BLOCK_SIZE]; #endif /* GCM_TABLE */ +#ifdef HAVE_CAVIUM_OCTEON_SYNC + word32 y0; +#endif #endif /* HAVE_AESGCM */ #ifdef WOLFSSL_AESNI byte use_aesni; diff --git a/wolfssl/wolfcrypt/des3.h b/wolfssl/wolfcrypt/des3.h index 69cd6ed47..9c5e5d530 100644 --- a/wolfssl/wolfcrypt/des3.h +++ b/wolfssl/wolfcrypt/des3.h @@ -109,6 +109,7 @@ struct Des3 { #ifdef WOLF_CRYPTO_CB int devId; void* devCtx; + word32 devKey[DES3_KEY_SIZE/sizeof(word32)]; /* raw key */ #endif void* heap; }; diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 9b9d76588..56f5efe96 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -106,6 +106,10 @@ if BUILD_CAVIUM nobase_include_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h endif +if BUILD_OCTEON_SYNC +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h +endif + if BUILD_INTEL_QA nobase_include_HEADERS+= wolfssl/wolfcrypt/port/intel/quickassist.h nobase_include_HEADERS+= wolfssl/wolfcrypt/port/intel/quickassist_mem.h diff --git a/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h b/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h new file mode 100644 index 000000000..af0816898 --- /dev/null +++ b/wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h @@ -0,0 +1,79 @@ +/* cavium_octeon.h + * + * Copyright (C) 2006-2019 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 3 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_OCTEON_SYNC_H_ +#define _CAVIUM_OCTEON_SYNC_H_ + +#ifdef HAVE_CAVIUM_OCTEON_SYNC + +#ifndef NO_DES3 + #include +#endif +#ifndef NO_AES + #include +#endif + +#include +#include +#include + +#include "cvmx.h" +#include "cvmx-asm.h" +#include "cvmx-key.h" +#include "cvmx-swap.h" + + +#ifdef WOLF_CRYPTO_CB +int wc_CryptoCb_InitOcteon(void); +void wc_CryptoCb_CleanupOcteon(void); +int wc_CryptoCb_GetDevIdOcteon(void); +#endif /* WOLF_CRYPTO_CB */ + + +#ifndef NO_DES3 +int Octeon_Des3_CbcEncrypt(Des3 *key, uint64_t *inp64, uint64_t *outp64, size_t inl); +int Octeon_Des3_CbcDecrypt(Des3 *key, uint64_t *inp64, uint64_t *outp64, size_t inl); +#endif /* !NO_DES3 */ + + +#ifndef NO_AES + +#ifdef WOLFSSL_AES_DIRECT +int Octeon_AesEcb_Encrypt(Aes *aes, const unsigned char *in, unsigned char *out); +int Octeon_AesEcb_Decrypt(Aes *aes, const unsigned char *in, unsigned char *out); +#endif + +#ifdef HAVE_AES_CBC +int Octeon_AesCbc_Encrypt(Aes *aes, uint64_t *inp64, uint64_t *outp64, size_t inl); +int Octeon_AesCbc_Decrypt(Aes *aes, uint64_t *inp64, uint64_t *outp64, size_t inl); +#endif + +#ifdef HAVE_AESGCM +int Octeon_AesGcm_Encrypt(Aes* aes, byte* in, byte* out, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, byte* tag); +int Octeon_AesGcm_Decrypt(Aes* aes, byte* in, byte* out, word32 inSz, + byte* iv, word32 ivSz, byte* aad, word32 aadSz, byte* tag); +#endif /* HAVE_AESGCM */ + +#endif /* !NO_AES */ + +#endif /* HAVE_CAVIUM_OCTEON_SYNC */ +#endif /* _CAVIUM_OCTEON_SYNC_H_ */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 225876f22..3a1dd2b8b 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -731,6 +731,16 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #endif +#ifdef HAVE_NITROX_OCTEON + /* By default, the OCTEON's global variables are all thread local. This + * tag allows them to be shared between threads. */ + #include "cvmx-platform.h" + #define WOLFSSL_GLOBAL CVMX_SHARED +#else + #define WOLFSSL_GLOBAL +#endif + + #ifdef __cplusplus } /* extern "C" */ #endif