mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
Synchronous Cavium OCTEON Support for Sniffer
1. Add configure option for sync IntelQA that uses the crypto callback API. 2. Make a synchonous copy of the quickassist files. 3. Tie in the crypto device to the sniffer. 4. When making a sniffer build, define static DH enabled. 5. The readme files in the Cavium were being added to the distro optionally, changed to always add the readme files. 6. Added an include of the cavium_octeon header in the wc_ports.c. 7. Updated the Cavium OCTEON callback for AES-GCM. 8. Add the global tag to the list of crypto callback function pointers. 9. Add an accessor to the OCTEON crypto callback module to return the device ID of the OCTEON device. 10. Add a new version of ssl_SetWatchKeyCallback which takes an additional parameter of a device ID. This ID is used to set up the wolfSSL_CTXs in the sniffer session trackers. 11. Update the benchmark to use sync OCTEON and QAT.
This commit is contained in:
48
configure.ac
48
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 "---"
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -172,6 +172,13 @@
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
#include <wolfssl/wolfcrypt/cryptocb.h>
|
||||
#ifdef HAVE_CAVIUM_OCTEON_SYNC
|
||||
#include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
#include <wolfssl/wolfcrypt/async.h>
|
||||
#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);
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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
|
||||
|
150
wolfcrypt/src/port/cavium/README_Octeon.md
Normal file
150
wolfcrypt/src/port/cavium/README_Octeon.md
Normal file
@@ -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 <OCTEON_MODEL>
|
||||
|
||||
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
|
995
wolfcrypt/src/port/cavium/cavium_octeon_sync.c
Normal file
995
wolfcrypt/src/port/cavium/cavium_octeon_sync.c
Normal file
@@ -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 <config.h>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||
|
||||
#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 <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
|
||||
|
||||
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 <wolfssl/wolfcrypt/cryptocb.h>
|
||||
|
||||
|
||||
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 */
|
@@ -76,6 +76,9 @@
|
||||
|
||||
#ifdef HAVE_INTEL_QA_SYNC
|
||||
#include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>
|
||||
|
||||
#ifdef HAVE_CAVIUM_OCTEON_SYNC
|
||||
#include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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
|
||||
|
79
wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h
Normal file
79
wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h
Normal file
@@ -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 <wolfssl/wolfcrypt/des3.h>
|
||||
#endif
|
||||
#ifndef NO_AES
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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_ */
|
@@ -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
|
||||
|
Reference in New Issue
Block a user