From a361f5c4bfe66858d34cdaa96877e73393133a86 Mon Sep 17 00:00:00 2001 From: Todd Ouska Date: Tue, 29 Jan 2013 16:22:49 -0800 Subject: [PATCH] initial cavium, crypto only, no rsa --- configure.ac | 33 +++++++- ctaocrypt/benchmark/benchmark.c | 60 ++++++++++++++ ctaocrypt/src/aes.c | 127 ++++++++++++++++++++++++++++++ ctaocrypt/src/arc4.c | 95 ++++++++++++++++++++++- ctaocrypt/src/des3.c | 129 ++++++++++++++++++++++++++++++- ctaocrypt/src/hmac.c | 133 ++++++++++++++++++++++++++++++++ ctaocrypt/src/random.c | 58 +++++++++++++- ctaocrypt/test/test.c | 122 ++++++++++++++++++++++++++++- cyassl/ctaocrypt/aes.h | 17 ++++ cyassl/ctaocrypt/arc4.h | 11 +++ cyassl/ctaocrypt/des3.h | 13 ++++ cyassl/ctaocrypt/hmac.h | 21 +++++ cyassl/ctaocrypt/random.h | 11 +++ cyassl/ctaocrypt/types.h | 4 +- src/ssl.c | 10 +-- 15 files changed, 829 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index e17404d9e..c07f843f4 100644 --- a/configure.ac +++ b/configure.ac @@ -424,7 +424,7 @@ AC_ARG_ENABLE([sha512], if test "$ENABLED_SHA512" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DCYASSL_SHA512" + AM_CFLAGS="$AM_CFLAGS -DCYASSL_SHA512 -DCYASSL_SHA384" fi if test "$ENABLED_FORTRESS" = "yes" @@ -714,6 +714,7 @@ AS_IF([test "x$ENABLED_SINGLETHREADED" = "xyes"], [ENABLED_EXAMPLES="no"]) AS_IF([test "x$ENABLED_NOFILESYSTEM" = "xyes"], [ENABLED_EXAMPLES="no"]) AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$ENABLED_EXAMPLES" = "xyes"]) + # LIBZ trylibzdir="" AC_ARG_WITH([libz], @@ -751,6 +752,36 @@ AC_ARG_WITH([libz], ) +# cavium +trycaviumdir="" +AC_ARG_WITH([cavium], + [ --with-cavium=PATH PATH to cavium/software dir ], + [ + 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 + + 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 ]) + + 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 + ] +) + + # OPTIMIZE FLAGS if test "$GCC" = "yes" then diff --git a/ctaocrypt/benchmark/benchmark.c b/ctaocrypt/benchmark/benchmark.c index 306fe5336..241ca7329 100644 --- a/ctaocrypt/benchmark/benchmark.c +++ b/ctaocrypt/benchmark/benchmark.c @@ -44,6 +44,12 @@ #include #include +#ifdef HAVE_CAVIUM + #include "cavium_sysdep.h" + #include "cavium_common.h" + #include "cavium_ioctl.h" +#endif + #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ @@ -76,11 +82,42 @@ void bench_eccKeyAgree(void); double current_time(void); +#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 + + int main(int argc, char** argv) { (void)argc; (void)argv; +#ifdef HAVE_CAVIUM + int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); + if (ret != 0) { + printf("Cavium OpenNitroxDevice failed\n"); + exit(-1); + } +#endif /* HAVE_CAVIUM */ #ifndef NO_AES bench_aes(0); bench_aes(1); @@ -175,6 +212,11 @@ void bench_aes(int show) double start, total, persec; int i; +#ifdef HAVE_CAVIUM + if (AesInitCavium(&enc, CAVIUM_DEV_ID) != 0) + printf("aes init cavium failed\n"); +#endif + AesSetKey(&enc, key, 16, iv, AES_ENCRYPTION); start = current_time(); @@ -188,6 +230,9 @@ void bench_aes(int show) if (show) printf("AES %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, persec); +#ifdef HAVE_CAVIUM + AesFreeCavium(&enc); +#endif } #endif @@ -271,6 +316,10 @@ void bench_des(void) double start, total, persec; int i; +#ifdef HAVE_CAVIUM + if (Des3_InitCavium(&enc, CAVIUM_DEV_ID) != 0) + printf("des3 init cavium failed\n"); +#endif Des3_SetKey(&enc, key, iv, DES_ENCRYPTION); start = current_time(); @@ -283,6 +332,9 @@ void bench_des(void) printf("3DES %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, persec); +#ifdef HAVE_CAVIUM + Des3_FreeCavium(&enc); +#endif } #endif @@ -294,6 +346,11 @@ void bench_arc4(void) double start, total, persec; int i; +#ifdef HAVE_CAVIUM + if (Arc4InitCavium(&enc, CAVIUM_DEV_ID) != 0) + printf("arc4 init cavium failed\n"); +#endif + Arc4SetKey(&enc, key, 16); start = current_time(); @@ -305,6 +362,9 @@ void bench_arc4(void) printf("ARC4 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, persec); +#ifdef HAVE_CAVIUM + Arc4FreeCavium(&enc); +#endif } #endif diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index 448ed130c..05e7dcbe5 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -41,6 +41,15 @@ #endif +#ifdef HAVE_CAVIUM + static int AesCaviumSetKey(Aes* aes, const byte* key, word32 length, + const byte* iv); + static void AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in, + word32 length); + static void AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, + word32 length); +#endif + #ifdef STM32F2_CRYPTO /* * STM32F2 hardware AES support through the STM32F2 standard peripheral @@ -1349,6 +1358,11 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) return BAD_FUNC_ARG; +#ifdef HAVE_CAVIUM + if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) + return AesCaviumSetKey(aes, userKey, keylen, iv); +#endif + #ifdef CYASSL_AESNI if (checkAESNI == 0) { haveAESNI = Check_CPU_support_AES(); @@ -1661,6 +1675,11 @@ void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { word32 blocks = sz / AES_BLOCK_SIZE; +#ifdef HAVE_CAVIUM + if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) + return AesCaviumCbcEncrypt(aes, out, in, sz); +#endif + #ifdef CYASSL_AESNI if (haveAESNI) { #ifdef DEBUG_AESNI @@ -1695,6 +1714,11 @@ void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) { word32 blocks = sz / AES_BLOCK_SIZE; +#ifdef HAVE_CAVIUM + if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) + return AesCaviumCbcDecrypt(aes, out, in, sz); +#endif + #ifdef CYASSL_AESNI if (haveAESNI) { #ifdef DEBUG_AESNI @@ -2738,5 +2762,108 @@ int AesSetIV(Aes* aes, const byte* iv) } +#ifdef HAVE_CAVIUM + +#include +#include "cavium_common.h" + +/* Initiliaze Aes for use with Nitrox device */ +int AesInitCavium(Aes* aes, int devId) +{ + if (aes == NULL) + return -1; + + if (CspAllocContext(CONTEXT_SSL, &aes->contextHandle, devId) != 0) + return -1; + + aes->devId = devId; + aes->magic = CYASSL_AES_CAVIUM_MAGIC; + + return 0; +} + + +/* Free Aes from use with Nitrox device */ +void AesFreeCavium(Aes* aes) +{ + if (aes == NULL) + return; + + CspFreeContext(CONTEXT_SSL, aes->contextHandle, aes->devId); + aes->magic = 0; +} + + +static int 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 AesSetIV(aes, iv); +} + + +static void AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in, + word32 length) +{ + word offset = 0; + word32 requestId; + + while (length > CYASSL_MAX_16BIT) { + word16 slen = (word16)CYASSL_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) { + CYASSL_MSG("Bad Cavium Aes Encrypt"); + } + length -= CYASSL_MAX_16BIT; + } + 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) { + CYASSL_MSG("Bad Cavium Aes Encrypt"); + } + } +} + +static void AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, + word32 length) +{ + word32 requestId; + + while (length > CYASSL_MAX_16BIT) { + word16 slen = (word16)CYASSL_MAX_16BIT; + if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, + aes->type, slen, (byte*)in, out, (byte*)aes->reg, + (byte*)aes->key, &requestId, aes->devId) != 0) { + CYASSL_MSG("Bad Cavium Aes Decrypt"); + } + length -= CYASSL_MAX_16BIT; + } + if (length) { + word16 slen = (word16)length; + if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, + aes->type, slen, (byte*)in, out, (byte*)aes->reg, + (byte*)aes->key, &requestId, aes->devId) != 0) { + CYASSL_MSG("Bad Cavium Aes Decrypt"); + } + } +} + +#endif /* HAVE_CAVIUM */ + #endif /* NO_AES */ diff --git a/ctaocrypt/src/arc4.c b/ctaocrypt/src/arc4.c index cbb132da8..6e37defa8 100644 --- a/ctaocrypt/src/arc4.c +++ b/ctaocrypt/src/arc4.c @@ -26,11 +26,23 @@ #include +#ifdef HAVE_CAVIUM + static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length); + static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in, + word32 length); +#endif + + void Arc4SetKey(Arc4* arc4, const byte* key, word32 length) { word32 i; word32 keyIndex = 0, stateIndex = 0; +#ifdef HAVE_CAVIUM + if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC) + return Arc4CaviumSetKey(arc4, key, length); +#endif + arc4->x = 1; arc4->y = 0; @@ -66,8 +78,16 @@ static INLINE byte MakeByte(word32* x, word32* y, byte* s) void Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) { - word32 x = arc4->x; - word32 y = arc4->y; + word32 x; + word32 y; + +#ifdef HAVE_CAVIUM + if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC) + return Arc4CaviumProcess(arc4, out, in, length); +#endif + + x = arc4->x; + y = arc4->y; while(length--) *out++ = *in++ ^ MakeByte(&x, &y, arc4->state); @@ -76,3 +96,74 @@ void Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) arc4->y = (byte)y; } + +#ifdef HAVE_CAVIUM + +#include +#include "cavium_common.h" + +/* Initiliaze Arc4 for use with Nitrox device */ +int Arc4InitCavium(Arc4* arc4, int devId) +{ + if (arc4 == NULL) + return -1; + + if (CspAllocContext(CONTEXT_SSL, &arc4->contextHandle, devId) != 0) + return -1; + + arc4->devId = devId; + arc4->magic = CYASSL_ARC4_CAVIUM_MAGIC; + + return 0; +} + + +/* Free Arc4 from use with Nitrox device */ +void Arc4FreeCavium(Arc4* arc4) +{ + if (arc4 == NULL) + return; + + CspFreeContext(CONTEXT_SSL, arc4->contextHandle, arc4->devId); + arc4->magic = 0; +} + + +static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length) +{ + word32 requestId; + + if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->contextHandle, length, + (byte*)key, &requestId, arc4->devId) != 0) { + CYASSL_MSG("Bad Cavium Arc4 Init"); + } +} + + +static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in, + word32 length) +{ + word offset = 0; + word32 requestId; + + while (length > CYASSL_MAX_16BIT) { + word16 slen = (word16)CYASSL_MAX_16BIT; + if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_NO_UPDATE, + slen, (byte*)in + offset, out + offset, &requestId, + arc4->devId) != 0) { + CYASSL_MSG("Bad Cavium Arc4 Encrypt"); + } + length -= CYASSL_MAX_16BIT; + offset += CYASSL_MAX_16BIT; + } + if (length) { + word16 slen = (word16)length; + if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_NO_UPDATE, + slen, (byte*)in + offset, out + offset, &requestId, + arc4->devId) != 0) { + CYASSL_MSG("Bad Cavium Arc4 Encrypt"); + } + } +} + +#endif /* HAVE_CAVIUM */ diff --git a/ctaocrypt/src/des3.c b/ctaocrypt/src/des3.c index 25a5a690f..3cab82700 100644 --- a/ctaocrypt/src/des3.c +++ b/ctaocrypt/src/des3.c @@ -34,6 +34,14 @@ #endif +#ifdef HAVE_CAVIUM + static void Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv); + static void Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in, + word32 length); + static void Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in, + word32 length); +#endif + #ifdef STM32F2_CRYPTO /* * STM32F2 hardware DES/3DES support through the STM32F2 standard @@ -554,6 +562,11 @@ void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) { +#ifdef HAVE_CAVIUM + if (des->magic == CYASSL_3DES_CAVIUM_MAGIC) + return Des3_CaviumSetKey(des, key, iv); +#endif + DesSetKey(key + (dir == DES_ENCRYPTION ? 0 : 16), dir, des->key[0]); DesSetKey(key + 8, Reverse(dir), des->key[1]); DesSetKey(key + (dir == DES_DECRYPTION ? 0 : 16), dir, des->key[2]); @@ -682,8 +695,14 @@ void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; + word32 blocks; +#ifdef HAVE_CAVIUM + if (des->magic == CYASSL_3DES_CAVIUM_MAGIC) + return Des3_CaviumCbcEncrypt(des, out, in, sz); +#endif + + blocks = sz / DES_BLOCK_SIZE; while (blocks--) { xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE); Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg); @@ -697,8 +716,14 @@ void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; + word32 blocks; +#ifdef HAVE_CAVIUM + if (des->magic == CYASSL_3DES_CAVIUM_MAGIC) + return Des3_CaviumCbcDecrypt(des, out, in, sz); +#endif + + blocks = sz / DES_BLOCK_SIZE; while (blocks--) { XMEMCPY(des->tmp, in, DES_BLOCK_SIZE); Des3ProcessBlock(des, (byte*)des->tmp, out); @@ -743,4 +768,104 @@ void Des3_SetIV(Des3* des, const byte* iv) } +#ifdef HAVE_CAVIUM + +#include +#include "cavium_common.h" + +/* Initiliaze Des3 for use with Nitrox device */ +int Des3_InitCavium(Des3* des3, int devId) +{ + if (des3 == NULL) + return -1; + + if (CspAllocContext(CONTEXT_SSL, &des3->contextHandle, devId) != 0) + return -1; + + des3->devId = devId; + des3->magic = CYASSL_3DES_CAVIUM_MAGIC; + + return 0; +} + + +/* Free Des3 from use with Nitrox device */ +void Des3_FreeCavium(Des3* des3) +{ + if (des3 == NULL) + return; + + CspFreeContext(CONTEXT_SSL, des3->contextHandle, des3->devId); + des3->magic = 0; +} + + +static void Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv) +{ + if (des3 == NULL) + return; + + /* key[0] holds key, iv in reg */ + XMEMCPY(des3->key[0], key, DES_BLOCK_SIZE*3); + + Des3_SetIV(des3, iv); +} + + +static void Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in, + word32 length) +{ + word offset = 0; + word32 requestId; + + while (length > CYASSL_MAX_16BIT) { + word16 slen = (word16)CYASSL_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) { + CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt"); + } + length -= CYASSL_MAX_16BIT; + } + 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) { + CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt"); + } + } +} + +static void Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in, + word32 length) +{ + word32 requestId; + + while (length > CYASSL_MAX_16BIT) { + word16 slen = (word16)CYASSL_MAX_16BIT; + if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle, + CAVIUM_NO_UPDATE, slen, (byte*)in, out, + (byte*)des3->reg, (byte*)des3->key[0], &requestId, + des3->devId) != 0) { + CYASSL_MSG("Bad Cavium 3Des Decrypt"); + } + length -= CYASSL_MAX_16BIT; + } + if (length) { + word16 slen = (word16)length; + if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle, + CAVIUM_NO_UPDATE, slen, (byte*)in, out, + (byte*)des3->reg, (byte*)des3->key[0], &requestId, + des3->devId) != 0) { + CYASSL_MSG("Bad Cavium 3Des Decrypt"); + } + } +} + +#endif /* HAVE_CAVIUM */ + #endif /* NO_DES3 */ diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index af69368bf..db7019e33 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -29,6 +29,14 @@ #include +#ifdef HAVE_CAVIUM + static void HmacCaviumFinal(Hmac* hmac, byte* hash); + static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length); + static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, + word32 length); +#endif + + static int InitHmac(Hmac* hmac, int type) { hmac->innerHashKeyed = 0; @@ -74,6 +82,11 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) byte* op = (byte*) hmac->opad; word32 i, hmac_block_size = SHA_BLOCK_SIZE; +#ifdef HAVE_CAVIUM + if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) + return HmacCaviumSetKey(hmac, type, key, length); +#endif + InitHmac(hmac, type); switch (hmac->macType) { @@ -187,6 +200,11 @@ static void HmacKeyInnerHash(Hmac* hmac) void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) { +#ifdef HAVE_CAVIUM + if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) + return HmacCaviumUpdate(hmac, msg, length); +#endif + if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); @@ -222,6 +240,11 @@ void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) void HmacFinal(Hmac* hmac, byte* hash) { +#ifdef HAVE_CAVIUM + if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) + return HmacCaviumFinal(hmac, hash); +#endif + if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); @@ -290,5 +313,115 @@ void HmacFinal(Hmac* hmac, byte* hash) } +#ifdef HAVE_CAVIUM + +/* Initiliaze Hmac for use with Nitrox device */ +int HmacInitCavium(Hmac* hmac, int devId) +{ + if (hmac == NULL) + return -1; + + if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0) + return -1; + + hmac->keyLen = 0; + hmac->dataLen = 0; + hmac->type = 0; + hmac->devId = devId; + hmac->magic = CYASSL_HMAC_CAVIUM_MAGIC; + hmac->data = NULL; /* buffered input data */ + + hmac->innerHashKeyed = 0; + + return 0; +} + + +/* Free Hmac from use with Nitrox device */ +void HmacFreeCavium(Hmac* hmac) +{ + if (hmac == NULL) + return; + + CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId); + hmac->magic = 0; + XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); + hmac->data = NULL; +} + + +static void 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) { + CYASSL_MSG("Cavium Hmac failed"); + } + hmac->innerHashKeyed = 0; /* tell update to start over if used again */ +} + + +static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length) +{ + word16 add = (word16)length; + word32 total; + byte* tmp; + + if (length > CYASSL_MAX_16BIT) { + CYASSL_MSG("Too big msg for cavium hmac"); + return; + } + + if (hmac->innerHashKeyed == 0) { /* starting new */ + hmac->dataLen = 0; + hmac->innerHashKeyed = 1; + } + + total = add + hmac->dataLen; + if (total > CYASSL_MAX_16BIT) { + CYASSL_MSG("Too big msg for cavium hmac"); + return; + } + + tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP); + if (tmp == NULL) { + CYASSL_MSG("Out of memory for cavium update"); + return; + } + if (hmac->dataLen) + XMEMCPY(tmp, hmac->data, hmac->dataLen); + XMEMCPY(tmp + hmac->dataLen, msg, add); + + hmac->dataLen += add; + XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); + hmac->data = tmp; +} + + +static void 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 { + CYASSL_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); +} + +#endif /* HAVE_CAVIUM */ + #endif /* NO_HMAC */ diff --git a/ctaocrypt/src/random.c b/ctaocrypt/src/random.c index 3b0b90d14..e1247d16a 100644 --- a/ctaocrypt/src/random.c +++ b/ctaocrypt/src/random.c @@ -307,8 +307,13 @@ int InitRng(RNG* rng) { byte key[32]; byte junk[256]; + int ret; - int ret = GenerateSeed(&rng->seed, key, sizeof(key)); +#ifdef HAVE_CAVIUM + if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC) + return 0; +#endif + ret = GenerateSeed(&rng->seed, key, sizeof(key)); if (ret == 0) { Arc4SetKey(&rng->cipher, key, sizeof(key)); @@ -318,10 +323,17 @@ int InitRng(RNG* rng) return ret; } +#ifdef HAVE_CAVIUM + static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz); +#endif /* place a generated block in output */ void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) { +#ifdef HAVE_CAVIUM + if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC) + return CaviumRNG_GenerateBlock(rng, output, sz); +#endif XMEMSET(output, 0, sz); Arc4Process(&rng->cipher, output, output, sz); } @@ -335,6 +347,50 @@ byte RNG_GenerateByte(RNG* rng) return b; } + +#ifdef HAVE_CAVIUM + +#include +#include "cavium_common.h" + +/* Initiliaze RNG for use with Nitrox device */ +int InitRngCavium(RNG* rng, int devId) +{ + if (rng == NULL) + return -1; + + rng->devId = devId; + rng->magic = CYASSL_RNG_CAVIUM_MAGIC; + + return 0; +} + + +static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz) +{ + word offset = 0; + word32 requestId; + + while (sz > CYASSL_MAX_16BIT) { + word16 slen = (word16)CYASSL_MAX_16BIT; + if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, + rng->devId) != 0) { + CYASSL_MSG("Cavium RNG failed"); + } + sz -= CYASSL_MAX_16BIT; + offset += CYASSL_MAX_16BIT; + } + if (sz) { + word16 slen = (word16)sz; + if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, + rng->devId) != 0) { + CYASSL_MSG("Cavium RNG failed"); + } + } +} + +#endif /* HAVE_CAVIUM */ + #endif /* NO_RC4 */ diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index c96baee46..41fd47280 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -67,6 +67,11 @@ #ifdef HAVE_NTRU #include "crypto_ntru.h" #endif +#ifdef HAVE_CAVIUM + #include "cavium_sysdep.h" + #include "cavium_common.h" + #include "cavium_ioctl.h" +#endif #include #ifdef FREESCALE_MQX @@ -149,6 +154,30 @@ typedef struct func_args { } func_args; + +#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 + void ctaocrypt_test(void* args) { int ret = 0; @@ -165,6 +194,12 @@ void ctaocrypt_test(void* args) #endif /* USE_FAST_MATH */ #endif /* !CYASSL_LEANPSK */ +#ifdef HAVE_CAVIUM + ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); + if (ret != 0) + err_sys("Cavium OpenNitroxDevice failed", -1236); +#endif /* HAVE_CAVIUM */ + #ifndef NO_MD5 if ( (ret = md5_test()) ) err_sys("MD5 test failed!\n", ret); @@ -358,6 +393,10 @@ void ctaocrypt_test(void* args) printf( "ECC test passed!\n"); #endif +#ifdef HAVE_CAVIUM + CspShutdown(CAVIUM_DEV_ID); +#endif + ((func_args*)args)->return_code = ret; } @@ -885,6 +924,12 @@ int hmac_md5_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { +#ifdef HAVE_CAVIUM + if (i == 1) + continue; /* driver can't handle keys <= bytes */ + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20009; +#endif HmacSetKey(&hmac, MD5, (byte*)keys[i], (word32)strlen(keys[i])); HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); @@ -892,6 +937,9 @@ int hmac_md5_test(void) if (memcmp(hash, test_hmac[i].output, MD5_DIGEST_SIZE) != 0) return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif } return 0; @@ -944,6 +992,12 @@ int hmac_sha_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { +#ifdef HAVE_CAVIUM + if (i == 1) + continue; /* driver can't handle keys <= bytes */ + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20010; +#endif HmacSetKey(&hmac, SHA, (byte*)keys[i], (word32)strlen(keys[i])); HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); @@ -951,6 +1005,9 @@ int hmac_sha_test(void) if (memcmp(hash, test_hmac[i].output, SHA_DIGEST_SIZE) != 0) return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif } return 0; @@ -1007,6 +1064,12 @@ int hmac_sha256_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { +#ifdef HAVE_CAVIUM + if (i == 1) + continue; /* driver can't handle keys <= bytes */ + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20011; +#endif HmacSetKey(&hmac, SHA256, (byte*)keys[i], (word32)strlen(keys[i])); HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); @@ -1014,6 +1077,9 @@ int hmac_sha256_test(void) if (memcmp(hash, test_hmac[i].output, SHA256_DIGEST_SIZE) != 0) return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif } return 0; @@ -1073,6 +1139,12 @@ int hmac_sha384_test(void) test_hmac[2] = c; for (i = 0; i < times; ++i) { +#ifdef HAVE_CAVIUM + if (i == 1) + continue; /* driver can't handle keys <= bytes */ + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20012; +#endif HmacSetKey(&hmac, SHA384, (byte*)keys[i], (word32)strlen(keys[i])); HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); @@ -1080,6 +1152,9 @@ int hmac_sha384_test(void) if (memcmp(hash, test_hmac[i].output, SHA384_DIGEST_SIZE) != 0) return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif } return 0; @@ -1134,9 +1209,19 @@ int arc4_test(void) for (i = 0; i < times; ++i) { Arc4 enc; Arc4 dec; + int keylen = 8; /* strlen with key 0x00 not good */ + if (i == 3) + keylen = 4; - Arc4SetKey(&enc, (byte*)keys[i], (word32)strlen(keys[i])); - Arc4SetKey(&dec, (byte*)keys[i], (word32)strlen(keys[i])); +#ifdef HAVE_CAVIUM + if (Arc4InitCavium(&enc, CAVIUM_DEV_ID) != 0) + return -20001; + if (Arc4InitCavium(&dec, CAVIUM_DEV_ID) != 0) + return -20002; +#endif + + Arc4SetKey(&enc, (byte*)keys[i], keylen); + Arc4SetKey(&dec, (byte*)keys[i], keylen); Arc4Process(&enc, cipher, (byte*)test_arc4[i].input, (word32)test_arc4[i].outLen); @@ -1147,6 +1232,11 @@ int arc4_test(void) if (memcmp(cipher, test_arc4[i].output, test_arc4[i].outLen)) return -20 - 5 - i; + +#ifdef HAVE_CAVIUM + Arc4FreeCavium(&enc); + Arc4FreeCavium(&dec); +#endif } return 0; @@ -1397,6 +1487,12 @@ int des3_test(void) }; +#ifdef HAVE_CAVIUM + if (Des3_InitCavium(&enc, CAVIUM_DEV_ID) != 0) + return -20005; + if (Des3_InitCavium(&dec, CAVIUM_DEV_ID) != 0) + return -20006; +#endif Des3_SetKey(&enc, key3, iv3, DES_ENCRYPTION); Des3_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); Des3_SetKey(&dec, key3, iv3, DES_DECRYPTION); @@ -1408,6 +1504,10 @@ int des3_test(void) if (memcmp(cipher, verify3, sizeof(cipher))) return -34; +#ifdef HAVE_CAVIUM + Des3_FreeCavium(&enc); + Des3_FreeCavium(&dec); +#endif return 0; } #endif /* NO_DES */ @@ -1437,6 +1537,12 @@ int aes_test(void) byte cipher[AES_BLOCK_SIZE * 4]; byte plain [AES_BLOCK_SIZE * 4]; +#ifdef HAVE_CAVIUM + if (AesInitCavium(&enc, CAVIUM_DEV_ID) != 0) + return -20003; + if (AesInitCavium(&dec, CAVIUM_DEV_ID) != 0) + return -20004; +#endif AesSetKey(&enc, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); AesSetKey(&dec, key, AES_BLOCK_SIZE, iv, AES_DECRYPTION); @@ -1449,6 +1555,10 @@ int aes_test(void) if (memcmp(cipher, verify, AES_BLOCK_SIZE)) return -61; +#ifdef HAVE_CAVIUM + AesFreeCavium(&enc); + AesFreeCavium(&dec); +#endif #ifdef CYASSL_AES_COUNTER { const byte ctrKey[] = @@ -1895,7 +2005,13 @@ int random_test(void) { RNG rng; byte block[32]; - int ret = InitRng(&rng); + int ret; + +#ifdef HAVE_CAVIUM + ret = InitRngCavium(&rng, CAVIUM_DEV_ID); + if (ret != 0) return -2007; +#endif + ret = InitRng(&rng); if (ret != 0) return -39; RNG_GenerateBlock(&rng, block, sizeof(block)); diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index 4272973da..53e37c5dc 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -28,6 +28,11 @@ #include +#ifdef HAVE_CAVIUM + #include + #include "cavium_common.h" +#endif + #ifdef CYASSL_AESNI #include @@ -53,6 +58,8 @@ #endif +#define CYASSL_AES_CAVIUM_MAGIC 0xBEEF0002 + enum { AES_ENC_TYPE = 1, /* cipher unique type */ AES_ENCRYPTION = 0, @@ -79,6 +86,12 @@ typedef struct Aes { #ifdef CYASSL_AESNI byte use_aesni; #endif /* CYASSL_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 } Aes; @@ -115,6 +128,10 @@ CYASSL_API int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, const byte* authIn, word32 authInSz); #endif /* HAVE_AESCCM */ +#ifdef HAVE_CAVIUM + CYASSL_API int AesInitCavium(Aes*, int); + CYASSL_API void AesFreeCavium(Aes*); +#endif #ifdef __cplusplus } /* extern "C" */ diff --git a/cyassl/ctaocrypt/arc4.h b/cyassl/ctaocrypt/arc4.h index b49146675..a74f14e37 100644 --- a/cyassl/ctaocrypt/arc4.h +++ b/cyassl/ctaocrypt/arc4.h @@ -32,6 +32,8 @@ #endif +#define CYASSL_ARC4_CAVIUM_MAGIC 0xBEEF0001 + enum { ARC4_ENC_TYPE = 4, /* cipher unique type */ ARC4_STATE_SIZE = 256 @@ -42,11 +44,20 @@ 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 */ +#endif } Arc4; CYASSL_API void Arc4Process(Arc4*, byte*, const byte*, word32); CYASSL_API void Arc4SetKey(Arc4*, const byte*, word32); +#ifdef HAVE_CAVIUM + CYASSL_API int Arc4InitCavium(Arc4*, int); + CYASSL_API void Arc4FreeCavium(Arc4*); +#endif #ifdef __cplusplus } /* extern "C" */ diff --git a/cyassl/ctaocrypt/des3.h b/cyassl/ctaocrypt/des3.h index 8fbe195d8..1f8a47e9f 100644 --- a/cyassl/ctaocrypt/des3.h +++ b/cyassl/ctaocrypt/des3.h @@ -33,6 +33,8 @@ extern "C" { #endif +#define CYASSL_3DES_CAVIUM_MAGIC 0xBEEF0003 + enum { DES_ENC_TYPE = 2, /* cipher unique type */ DES3_ENC_TYPE = 3, /* cipher unique type */ @@ -64,6 +66,11 @@ 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 */ +#endif } Des3; @@ -79,6 +86,12 @@ CYASSL_API void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in,word32 sz); CYASSL_API void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in,word32 sz); +#ifdef HAVE_CAVIUM + CYASSL_API int Des3_InitCavium(Des3*, int); + CYASSL_API void Des3_FreeCavium(Des3*); +#endif + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index 0be5b9ccf..ea2697f61 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -39,11 +39,18 @@ #include #endif +#ifdef HAVE_CAVIUM + #include + #include "cavium_common.h" +#endif + #ifdef __cplusplus extern "C" { #endif +#define CYASSL_HMAC_CAVIUM_MAGIC 0xBEEF0005 + enum { IPAD = 0x36, OPAD = 0x5C, @@ -88,6 +95,15 @@ typedef struct Hmac { word32 innerHash[INNER_HASH_SIZE / sizeof(word32)]; /* max size */ byte macType; /* md5 sha or sha256 */ byte innerHashKeyed; /* keyed flag */ +#ifdef HAVE_CAVIUM + word16 keyLen; /* hmac key length */ + word16 dataLen; + HashType type; /* hmac key type */ + int devId; /* nitrox device id */ + word32 magic; /* using cavium magic */ + word64 contextHandle; /* nitrox context memory handle */ + byte* data; /* buffered input data for one call */ +#endif } Hmac; @@ -96,6 +112,11 @@ CYASSL_API void HmacSetKey(Hmac*, int type, const byte* key, word32 keySz); CYASSL_API void HmacUpdate(Hmac*, const byte*, word32); CYASSL_API void HmacFinal(Hmac*, byte*); +#ifdef HAVE_CAVIUM + CYASSL_API int HmacInitCavium(Hmac*, int); + CYASSL_API void HmacFreeCavium(Hmac*); +#endif + #ifdef __cplusplus } /* extern "C" */ diff --git a/cyassl/ctaocrypt/random.h b/cyassl/ctaocrypt/random.h index 2bc790dc5..a4452582b 100644 --- a/cyassl/ctaocrypt/random.h +++ b/cyassl/ctaocrypt/random.h @@ -61,12 +61,23 @@ int GenerateSeed(OS_Seed* os, byte* seed, word32 sz); #ifndef NO_RC4 +#define CYASSL_RNG_CAVIUM_MAGIC 0xBEEF0004 + /* secure Random Nnumber Generator */ typedef struct RNG { OS_Seed seed; Arc4 cipher; +#ifdef HAVE_CAVIUM + int devId; /* nitrox device id */ + word32 magic; /* using cavium magic */ +#endif } RNG; + +#ifdef HAVE_CAVIUM + CYASSL_API int InitRngCavium(RNG*, int); +#endif + #else /* NO_RC4 */ #define DBRG_SEED_LEN (440/8) diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h index 82bbaec5b..b33c37e9a 100644 --- a/cyassl/ctaocrypt/types.h +++ b/cyassl/ctaocrypt/types.h @@ -98,6 +98,7 @@ enum { WORD_BITS = WORD_SIZE * BIT_SIZE }; +#define CYASSL_MAX_16BIT 0xffffU /* use inlining if compiler allows */ #ifndef INLINE @@ -228,7 +229,8 @@ enum { DYNAMIC_TYPE_SOCKADDR = 35, DYNAMIC_TYPE_LIBZ = 36, DYNAMIC_TYPE_ECC = 37, - DYNAMIC_TYPE_TMP_BUFFER = 38 + DYNAMIC_TYPE_TMP_BUFFER = 38, + DYNAMIC_TYPE_CAVIUM_TMP = 40 }; /* stack protection */ diff --git a/src/ssl.c b/src/ssl.c index 97ef9682f..75aba4e8a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3269,7 +3269,7 @@ int CyaSSL_set_compression(CYASSL* ssl) { byte tmp[FILE_BUFFER_SIZE]; byte* myBuffer = tmp; - int send = 0; + int sending = 0; int newBuffer = 0; int idx = 0; int i; @@ -3278,10 +3278,10 @@ int CyaSSL_set_compression(CYASSL* ssl) CYASSL_ENTER("CyaSSL_writev"); for (i = 0; i < iovcnt; i++) - send += (int)iov[i].iov_len; + sending += (int)iov[i].iov_len; - if (send > (int)sizeof(tmp)) { - byte* tmp2 = (byte*) XMALLOC(send, ssl->heap, + if (sending > (int)sizeof(tmp)) { + byte* tmp2 = (byte*) XMALLOC(sending, ssl->heap, DYNAMIC_TYPE_WRITEV); if (!tmp2) return MEMORY_ERROR; @@ -3294,7 +3294,7 @@ int CyaSSL_set_compression(CYASSL* ssl) idx += (int)iov[i].iov_len; } - ret = CyaSSL_write(ssl, myBuffer, send); + ret = CyaSSL_write(ssl, myBuffer, sending); if (newBuffer) XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);