diff --git a/wolfcrypt/src/async.c b/wolfcrypt/src/async.c index 00bfd8d..5e020d0 100644 --- a/wolfcrypt/src/async.c +++ b/wolfcrypt/src/async.c @@ -26,6 +26,7 @@ #include #ifdef WOLFSSL_ASYNC_CRYPT + #include #include #include @@ -304,7 +305,7 @@ int wolfAsync_DevOpenThread(int *pDevId, void* threadId) int devId = INVALID_DEVID; #ifdef HAVE_CAVIUM - ret = NitroxOpenDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); + ret = NitroxOpenDeviceDefault(); if (ret >= 0) devId = ret; else @@ -468,6 +469,40 @@ int wolfAsync_EventQueuePush(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event) return wolfEventQueue_Push(queue, event); } +#ifdef HAVE_CAVIUM +static int wolfAsync_NitroxCheckReq(WC_ASYNC_DEV* asyncDev, WOLF_EVENT* event) +{ + int ret; + + /* populate event requestId */ + event->reqId = asyncDev->nitrox.reqId; + if (event->reqId == 0) + return WC_INIT_E; + + /* poll specific request */ + ret = NitroxCheckRequest(asyncDev, event); + +#ifdef WOLFSSL_NITROX_DEBUG + if (event->ret == WC_PENDING_E) + event->pendCount++; + else + printf("NitroxCheckRequest: ret %x, req %lx, count %d\n", + ret, + event->reqId, + event->pendCount); +#else + (void)ret; +#endif + + /* if not pending then clear requestId */ + if (event->ret != WC_PENDING_E) { + event->reqId = 0; + } + + return 0; +} +#endif /* HAVE_CAVIUM */ + int wolfAsync_EventPoll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags) { int ret = 0; @@ -479,14 +514,15 @@ int wolfAsync_EventPoll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags) return BAD_FUNC_ARG; } asyncDev = event->dev.async; - - /* Note: event queue mutex is locked here, so make sure - hardware doesn't try and lock event_queue */ + if (asyncDev == NULL) { + return WC_INIT_E; + } if (flags & WOLF_POLL_FLAG_CHECK_HW) { #if defined(HAVE_CAVIUM) - event->ret = NitroxCheckRequest(asyncDev, event); + ret = wolfAsync_NitroxCheckReq(asyncDev, event); #elif defined(HAVE_INTEL_QA) + /* poll QAT hardware, callback returns data, IntelQaPoll sets event */ ret = IntelQaPoll(asyncDev); #elif defined(WOLFSSL_ASYNC_CRYPT_TEST) event->ret = wolfAsync_crypt_test(asyncDev); @@ -503,9 +539,9 @@ int wolfAsync_EventPoll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags) #ifdef HAVE_CAVIUM -static int wolfAsync_CheckMultiReqBuf(WC_ASYNC_DEV* asyncDev, +static int wolfAsync_NitroxCheckMultiReqBuf(WC_ASYNC_DEV* asyncDev, WOLF_EVENT_QUEUE* queue, void* context_filter, - struct CspMultiRequestStatusBuffer* multi_req) + CspMultiRequestStatusBuffer* multi_req, int req_count) { WOLF_EVENT* event; int ret = 0, i; @@ -520,7 +556,7 @@ static int wolfAsync_CheckMultiReqBuf(WC_ASYNC_DEV* asyncDev, return ret; } - /* Itterate event queue */ + /* Iterate event queue */ for (event = queue->head; event != NULL; event = event->next) { if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST && event->type <= WOLF_EVENT_TYPE_ASYNC_LAST) @@ -528,9 +564,21 @@ static int wolfAsync_CheckMultiReqBuf(WC_ASYNC_DEV* asyncDev, /* optional filter based on context */ if (context_filter == NULL || event->context == context_filter) { /* find request */ - for (i = 0; i < multi_req->count; i++) { - if (event->reqId > 0 && event->reqId == multi_req->req[i].request_id) { - event->ret = NitroxTranslateResponseCode(multi_req->req[i].status); + for (i = 0; i < req_count; i++) { + if (event->reqId == multi_req->req[i].request_id) { + + event->ret = NitroxTranslateResponseCode( + multi_req->req[i].status); + + #ifdef WOLFSSL_NITROX_DEBUG + if (event->ret == WC_PENDING_E) + event->pendCount++; + else + printf("NitroxCheckRequests: ret %x, req %lx, count %d\n", + multi_req->req[i].status, + multi_req->req[i].request_id, + event->pendCount); + #endif /* If not pending then mark as done */ if (event->ret != WC_PENDING_E) { @@ -545,11 +593,12 @@ static int wolfAsync_CheckMultiReqBuf(WC_ASYNC_DEV* asyncDev, } /* reset multi request buffer */ - XMEMSET(multi_req, 0, sizeof(struct CspMultiRequestStatusBuffer)); + XMEMSET(multi_req, 0, sizeof(CspMultiRequestStatusBuffer)); + multi_req->count = CAVIUM_MAX_POLL; return ret; } -#endif +#endif /* HAVE_CAVIUM */ int wolfAsync_EventQueuePoll(WOLF_EVENT_QUEUE* queue, void* context_filter, WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount) @@ -557,9 +606,13 @@ int wolfAsync_EventQueuePoll(WOLF_EVENT_QUEUE* queue, void* context_filter, WOLF_EVENT* event; int ret = 0, count = 0; WC_ASYNC_DEV* asyncDev = NULL; -#ifdef HAVE_CAVIUM - struct CspMultiRequestStatusBuffer multi_req; - XMEMSET(&multi_req, 0, sizeof(multi_req)); +#if defined(HAVE_CAVIUM) + CspMultiRequestStatusBuffer multi_req; + int req_count = 0; + + /* reset multi request buffer */ + XMEMSET(&multi_req, 0, sizeof(CspMultiRequestStatusBuffer)); + multi_req.count = CAVIUM_MAX_POLL; #endif /* possible un-used variable */ @@ -579,7 +632,6 @@ int wolfAsync_EventQueuePoll(WOLF_EVENT_QUEUE* queue, void* context_filter, /* if check hardware flag is set */ if (flags & WOLF_POLL_FLAG_CHECK_HW) { /* check event queue */ - count = 0; for (event = queue->head; event != NULL; event = event->next) { if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST && event->type <= WOLF_EVENT_TYPE_ASYNC_LAST) @@ -596,22 +648,24 @@ int wolfAsync_EventQueuePoll(WOLF_EVENT_QUEUE* queue, void* context_filter, count++; #if defined(HAVE_CAVIUM) - /* Add entry to multi-request buffer */ + /* populate event requestId */ + event->reqId = asyncDev->nitrox.reqId; + + /* add entry to multi-request buffer for polling */ if (event->reqId > 0) { - multi_req.req[multi_req.count].request_id = event->reqId; - multi_req.count++; + multi_req.req[req_count++].request_id = event->reqId; } - /* Submit filled multi-request query */ - if (multi_req.count >= CAVIUM_MAX_POLL) { - ret = wolfAsync_CheckMultiReqBuf(asyncDev, - queue, context_filter, &multi_req); + /* submit filled multi-request query */ + if (req_count == CAVIUM_MAX_POLL) { + ret = wolfAsync_NitroxCheckMultiReqBuf(asyncDev, + queue, context_filter, &multi_req, req_count); if (ret != 0) { break; } } #else #if defined(HAVE_INTEL_QA) - /* poll QAT hardware, callback returns data, this thread poll sets event */ + /* poll QAT hardware, callback returns data, IntelQaPoll sets event */ ret = IntelQaPoll(asyncDev); if (ret != 0) { break; @@ -642,10 +696,10 @@ int wolfAsync_EventQueuePoll(WOLF_EVENT_QUEUE* queue, void* context_filter, } /* for */ #if defined(HAVE_CAVIUM) - /* Submit partial multi-request query (if no prev errors) */ - if (ret == 0 && multi_req.count > 0) { - ret = wolfAsync_CheckMultiReqBuf(asyncDev, - queue, context_filter, &multi_req); + /* submit partial multi-request query (if no prev errors) */ + if (ret == 0 && req_count > 0) { + ret = wolfAsync_NitroxCheckMultiReqBuf(asyncDev, + queue, context_filter, &multi_req, req_count); } #endif } /* flag WOLF_POLL_FLAG_CHECK_HW */ @@ -713,7 +767,7 @@ int wolfAsync_EventInit(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context, event->dev.async = asyncDev; event->flags = flags; #ifdef HAVE_CAVIUM - event->reqId = asyncDev->nitrox.reqId; + event->reqId = 0; #endif return ret; diff --git a/wolfcrypt/src/port/cavium/README.md b/wolfcrypt/src/port/cavium/README.md index 57bdbe1..23b3abd 100644 --- a/wolfcrypt/src/port/cavium/README.md +++ b/wolfcrypt/src/port/cavium/README.md @@ -5,9 +5,9 @@ `/CNN55XX-SDK` `/wolfssl` -## Cavium Driver +## Building Cavium Driver -Tested against `CNN55XX-Driver-Linux-KVM-XEN-PF-SDK-1.4.14.tar` +Tested using `CNN55XX-Driver-Linux-KVM-XEN-PF-SDK-1.4.14.tar` ### Installation @@ -19,17 +19,11 @@ cd bin sudo perl ./init_nitrox.pl ``` +#### Issues -## Building wolfSSL - -``` -./configure --with-cavium-v=../CNN55XX-SDK --enable-asynccrypt --enable-aesni --enable-intelasm -make -``` - -### Fixes to Nitrox Driver for includes into wolfSSL +1. Fixes to Nitrox Driver for includes into wolfSSL -1. Modify `include/vf_defs.h:120` -> `vf_config_mode_str()` function to: +a. Modify `include/vf_defs.h:120` -> `vf_config_mode_str()` function to: ``` static inline const char *vf_config_mode_str(vf_config_type_t vf_mode) @@ -37,23 +31,12 @@ static inline const char *vf_config_mode_str(vf_config_type_t vf_mode) const char *vf_mode_str; ``` -2. Add `case PF:` to `include/vf_defs.h:82` above `default:` in `vf_config_mode_to_num_vfs()`. +b. Add `case PF:` to `include/vf_defs.h:82` above `default:` in `vf_config_mode_to_num_vfs()`. -3. In `/include/linux/sysdep.h:46` rename `__BYTED_ORDER` to `__BYTE_ORDER`. +c. In `/include/linux/sysdep.h:46` rename `__BYTED_ORDER` to `__BYTE_ORDER`. -## Usage - -Note: Must run applications with sudo to access device. - -``` -sudo ./wolfcrypt/benchmark/benchmark -sudo ./wolfcrypt/test/testwolfcrypt -``` - -## Issues - -If the CNN55XX driver is not extracted on the Linux box it can cause issues with the symbolic links in the microcode folder. Fix was to resolve the symbolic links in `./microcode`. +2. If the CNN55XX driver is not extracted on the Linux box it can cause issues with the symbolic links in the microcode folder. Fix was to resolve the symbolic links in `./microcode`. ``` NITROX Model: 0x1200 [ CNN55XX PASS 1.0 ] @@ -72,3 +55,168 @@ rm main_ssl.out ls -s ./build/main_ssl.out ./main_ssl.out ``` + +## Building wolfSSL + +``` +./configure --with-cavium-v=../CNN55XX-SDK --enable-asynccrypt --enable-aesni --enable-intelasm +make +sudo make install +``` + +### CFLAGS + +`CFLAGS+= -DHAVE_CAVIUM -DHAVE_CAVIUM_V -DWOLFSSL_ASYNC_CRYPT -DHAVE_WOLF_EVENT -DHAVE_WOLF_BIGINT` +`CFLAGS+= -I../CNN55XX-SDK/include -lrt -lcrypto` + +* `HAVE_CAVIUM`: The Cavium define +* `HAVE_CAVIUM_V`: Nitrox V +* `WOLFSSL_ASYNC_CRYPT`: Enable asynchronous wolfCrypt. +* `HAVE_WOLF_EVENT`: Enable wolf event support (required for async) +* `HAVE_WOLF_BIGINT`: Enable wolf big integer support (required for async) + + +### LDFLAGS + +Include the libnitrox static library: +`LDFLAGS+= ../CNN55XX-SDK/lib/libnitrox.a` + + +### Issues + +a. If building with debug `-g` and using an older binutils LD version 2.23 or less you may see a linker crash. Example of error: `BFD (GNU Binutils) 2.23.2 internal error, aborting at merge.c line 873 in _bfd_merged_section_offset`. Resolution is to use this in the CFLAGS `-g -fno-merge-debug-strings -fdebug-types-section`. + + +## Usage + +Note: Must run applications with `sudo` to access device. + +``` +sudo ./wolfcrypt/benchmark/benchmark +sudo ./wolfcrypt/test/testwolfcrypt +``` + + +## TLS Code Tempalte + +``` +/* GLOBAL DEVICE IDENTIFIER */ +#ifdef WOLFSSL_ASYNC_CRYPT + static int devId = INVALID_DEVID; +#endif + + +/* DONE AT INIT */ +#ifdef WOLFSSL_ASYNC_CRYPT + if (wolfAsync_DevOpen(&devId) != 0) { + fprintf(stderr, "Async device open failed\nRunning without async\n"); + } + + wolfSSL_CTX_UseAsync(ctx, devId); +#endif + + +/* DONE IN YOUR WORKER LOOP IN WC_PENDING_E CASES AGAINST YOUR WOLFSSL_CTX */ +#ifdef WOLFSSL_ASYNC_CRYPT + int ret; + WOLF_EVENT* wolfEvents[MAX_WOLF_EVENTS]; + int eventCount, i; + + /* get list of events that are done (not pending) */ + ret = wolfSSL_CTX_AsyncPoll(ctx, wolfEvents, MAX_WOLF_EVENTS, WOLF_POLL_FLAG_CHECK_HW, &eventCount); + if (ret != 0) + goto error; + + for (i = 0; i < eventCount; i++) { + WOLFSSL* ssl = (WOLFSSL*)wolfEvents[i]->context; + if (ssl) { + /* your SSL object is ready to be called again */ + } + } +#endif + + +/* DONE AT CLEANUP */ +#ifdef WOLFSSL_ASYNC_CRYPT + wolfAsync_DevClose(&devId); +#endif +``` + +## Benchmarks + +Nitrox V: CNN5560-900-C45 +Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz +CentOS: Kernel 3.10.0-514.16.1.el7.x86_64 +Single Thread + +``` +./configure --with-cavium-v=../CNN55XX-SDK --enable-asynccrypt --enable-aesni --enable-intelasm CFLAGS="-DWC_NO_ASYNC_THREADING" && make + +sudo ./wolfcrypt/benchmark/benchmark + +wolfCrypt Benchmark (block bytes 1048576, min 1.0 sec each) +RNG SW 135 MB took 1.012 seconds, 133.356 MB/s Cycles per byte = 25.69 +RNG HW 85 MB took 1.049 seconds, 81.039 MB/s Cycles per byte = 42.27 +AES-128-CBC-enc SW 845 MB took 1.001 seconds, 844.293 MB/s Cycles per byte = 4.06 +AES-128-CBC-dec SW 6060 MB took 1.001 seconds, 6055.102 MB/s Cycles per byte = 0.57 +AES-192-CBC-enc SW 710 MB took 1.004 seconds, 707.248 MB/s Cycles per byte = 4.84 +AES-192-CBC-dec SW 5055 MB took 1.001 seconds, 5050.086 MB/s Cycles per byte = 0.68 +AES-256-CBC-enc SW 610 MB took 1.003 seconds, 608.296 MB/s Cycles per byte = 5.63 +AES-256-CBC-dec SW 4330 MB took 1.001 seconds, 4326.604 MB/s Cycles per byte = 0.79 +AES-128-CBC-enc HW 240 MB took 1.018 seconds, 235.801 MB/s Cycles per byte = 14.53 +AES-128-CBC-dec HW 240 MB took 1.011 seconds, 237.312 MB/s Cycles per byte = 14.43 +AES-192-CBC-enc HW 220 MB took 1.021 seconds, 215.411 MB/s Cycles per byte = 15.90 +AES-192-CBC-dec HW 215 MB took 1.002 seconds, 214.516 MB/s Cycles per byte = 15.97 +AES-256-CBC-enc HW 200 MB took 1.016 seconds, 196.910 MB/s Cycles per byte = 17.40 +AES-256-CBC-dec HW 200 MB took 1.016 seconds, 196.758 MB/s Cycles per byte = 17.41 +AES-128-GCM-enc SW 3095 MB took 1.000 seconds, 3093.571 MB/s Cycles per byte = 1.11 +AES-128-GCM-dec SW 3090 MB took 1.001 seconds, 3087.702 MB/s Cycles per byte = 1.11 +AES-192-GCM-enc SW 2825 MB took 1.002 seconds, 2820.654 MB/s Cycles per byte = 1.21 +AES-192-GCM-dec SW 2815 MB took 1.000 seconds, 2814.153 MB/s Cycles per byte = 1.22 +AES-256-GCM-enc SW 2550 MB took 1.001 seconds, 2548.379 MB/s Cycles per byte = 1.34 +AES-256-GCM-dec SW 2555 MB took 1.002 seconds, 2550.183 MB/s Cycles per byte = 1.34 +AES-128-GCM-enc HW 135 MB took 1.018 seconds, 132.618 MB/s Cycles per byte = 25.83 +AES-128-GCM-dec HW 130 MB took 1.022 seconds, 127.202 MB/s Cycles per byte = 26.93 +AES-192-GCM-enc HW 135 MB took 1.019 seconds, 132.435 MB/s Cycles per byte = 25.86 +AES-192-GCM-dec HW 130 MB took 1.025 seconds, 126.789 MB/s Cycles per byte = 27.02 +AES-256-GCM-enc HW 135 MB took 1.019 seconds, 132.418 MB/s Cycles per byte = 25.87 +AES-256-GCM-dec HW 130 MB took 1.023 seconds, 127.071 MB/s Cycles per byte = 26.96 +CHACHA SW 3245 MB took 1.001 seconds, 3241.680 MB/s Cycles per byte = 1.06 +CHA-POLY SW 1930 MB took 1.000 seconds, 1929.817 MB/s Cycles per byte = 1.77 +MD5 SW 710 MB took 1.005 seconds, 706.678 MB/s Cycles per byte = 4.85 +POLY1305 SW 4850 MB took 1.000 seconds, 4849.127 MB/s Cycles per byte = 0.71 +SHA SW 560 MB took 1.008 seconds, 555.558 MB/s Cycles per byte = 6.17 +SHA-224 SW 460 MB took 1.002 seconds, 459.021 MB/s Cycles per byte = 7.46 +SHA-256 SW 460 MB took 1.002 seconds, 459.013 MB/s Cycles per byte = 7.46 +SHA-384 SW 690 MB took 1.002 seconds, 688.368 MB/s Cycles per byte = 4.98 +SHA-512 SW 690 MB took 1.002 seconds, 688.414 MB/s Cycles per byte = 4.98 +SHA3-224 SW 330 MB took 1.007 seconds, 327.713 MB/s Cycles per byte = 10.45 +SHA3-256 SW 310 MB took 1.000 seconds, 309.909 MB/s Cycles per byte = 11.05 +SHA3-384 SW 235 MB took 1.007 seconds, 233.355 MB/s Cycles per byte = 14.68 +SHA3-512 SW 170 MB took 1.027 seconds, 165.547 MB/s Cycles per byte = 20.69 +HMAC-MD5 SW 705 MB took 1.002 seconds, 703.344 MB/s Cycles per byte = 4.87 +HMAC-MD5 HW 62670 MB took 1.000 seconds,62666.115 MB/s Cycles per byte = 0.05 +HMAC-SHA SW 555 MB took 1.000 seconds, 554.964 MB/s Cycles per byte = 6.17 +HMAC-SHA HW 62745 MB took 1.000 seconds,62744.312 MB/s Cycles per byte = 0.05 +HMAC-SHA224 SW 475 MB took 1.005 seconds, 472.870 MB/s Cycles per byte = 7.24 +HMAC-SHA224 HW 62415 MB took 1.000 seconds,62412.262 MB/s Cycles per byte = 0.05 +HMAC-SHA256 SW 475 MB took 1.005 seconds, 472.710 MB/s Cycles per byte = 7.25 +HMAC-SHA256 HW 63185 MB took 1.000 seconds,63180.255 MB/s Cycles per byte = 0.05 +HMAC-SHA384 SW 690 MB took 1.005 seconds, 686.794 MB/s Cycles per byte = 4.99 +HMAC-SHA384 HW 62575 MB took 1.000 seconds,62573.195 MB/s Cycles per byte = 0.05 +HMAC-SHA512 SW 690 MB took 1.004 seconds, 687.563 MB/s Cycles per byte = 4.98 +HMAC-SHA512 HW 62430 MB took 1.000 seconds,62428.497 MB/s Cycles per byte = 0.05 +RSA 2048 public SW 3900 ops took 1.026 sec, avg 0.263 ms, 3801.211 ops/sec +RSA 2048 private SW 300 ops took 1.035 sec, avg 3.452 ms, 289.722 ops/sec +RSA 2048 public HW 140900 ops took 1.001 sec, avg 0.007 ms, 140825.228 ops/sec +RSA 2048 private HW 8300 ops took 1.004 sec, avg 0.121 ms, 8267.789 ops/sec +DH 2048 key gen SW 1010 ops took 1.004 sec, avg 0.994 ms, 1005.939 ops/sec +DH 2048 agree SW 1000 ops took 1.005 sec, avg 1.005 ms, 995.404 ops/sec +ECC 256 key gen SW 1090 ops took 1.001 sec, avg 0.918 ms, 1089.153 ops/sec +ECDHE 256 agree SW 1400 ops took 1.038 sec, avg 0.742 ms, 1348.211 ops/sec +ECDSA 256 sign SW 1400 ops took 1.076 sec, avg 0.769 ms, 1300.595 ops/sec +ECDSA 256 verify SW 1900 ops took 1.016 sec, avg 0.535 ms, 1870.353 ops/sec +ECDHE 256 agree HW 10500 ops took 1.001 sec, avg 0.095 ms, 10485.383 ops/sec +ECDSA 256 sign HW 22200 ops took 1.001 sec, avg 0.045 ms, 22169.233 ops/sec +ECDSA 256 verify HW 7500 ops took 1.012 sec, avg 0.135 ms, 7408.213 ops/sec +``` diff --git a/wolfcrypt/src/port/cavium/cavium_nitrox.c b/wolfcrypt/src/port/cavium/cavium_nitrox.c index 5e373d9..d6c403d 100644 --- a/wolfcrypt/src/port/cavium/cavium_nitrox.c +++ b/wolfcrypt/src/port/cavium/cavium_nitrox.c @@ -37,8 +37,19 @@ #ifndef NO_AES #include #endif +#ifdef HAVE_ECC + #include +#endif +#include #include +#ifndef HAVE_CAVIUM_V + #include "cavium_ioctl.h" +#else + #include "cavium_sym_crypto.h" + #include "cavium_asym_crypto.h" +#endif +#include #include /* For ntohs */ static CspHandle mLastDevHandle = INVALID_DEVID; @@ -62,6 +73,15 @@ int NitroxTranslateResponseCode(int ret) case ERR_DATA_LEN_INVALID: ret = BAD_FUNC_ARG; break; + case ERR_ECC_SIGNATURE_MISMATCH: + ret = SIG_VERIFY_E; + break; + case ERR_PKCS_DECRYPT_INCORRECT: + ret = ASN_SIG_CONFIRM_E; /* RSA_PAD_E */ + break; + case ERR_GC_ICV_MISCOMPARE: + ret = AES_GCM_AUTH_E; + break; case 0: case 1: ret = 0; /* treat as success */ @@ -79,6 +99,7 @@ static INLINE void NitroxDevClear(WC_ASYNC_DEV* dev) /* this is because operation may complete before added to event list */ dev->event.ret = WC_PENDING_E; dev->event.state = WOLF_EVENT_STATE_PENDING; + dev->event.reqId = 0; } CspHandle NitroxGetDeviceHandle(void) @@ -125,6 +146,11 @@ CspHandle NitroxOpenDevice(int dma_mode, int dev_id) return mLastDevHandle; } +CspHandle NitroxOpenDeviceDefault(void) +{ + return NitroxOpenDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID); +} + int NitroxAllocContext(WC_ASYNC_DEV* dev, CspHandle devId, context_type_t type) @@ -181,14 +207,32 @@ void NitroxCloseDevice(CspHandle devId) int NitroxCheckRequest(WC_ASYNC_DEV* dev, WOLF_EVENT* event) { - int ret = CspCheckForCompletion(dev->nitrox.devId, event->reqId); - return NitroxTranslateResponseCode(ret); + int ret = BAD_FUNC_ARG; + if (dev && event) { + ret = CspCheckForCompletion(dev->nitrox.devId, event->reqId); + event->ret = NitroxTranslateResponseCode(ret); + } + return ret; } int NitroxCheckRequests(WC_ASYNC_DEV* dev, - struct CspMultiRequestStatusBuffer* req_stat_buf) + CspMultiRequestStatusBuffer* req_stat_buf) { - int ret = CspGetAllResults(req_stat_buf, dev->nitrox.devId); + int ret; + + if (dev == NULL || req_stat_buf == NULL) + return BAD_FUNC_ARG; + +#ifdef HAVE_CAVIUM_V + ret = CspGetAllResults(req_stat_buf, dev->nitrox.devId); +#else + word32 res_count = 0; + word32 buf_size = sizeof(req_stat_buf->req); + ret = CspGetAllResults(req_stat_buf->req, buf_size, &res_count, + dev->nitrox.devId); + multi_req->count = res_count; +#endif + return NitroxTranslateResponseCode(ret); } @@ -224,6 +268,12 @@ int NitroxRsaExptMod(const byte* in, word32 inLen, /* Not implemented/supported */ ret = NOT_COMPILED_IN; #endif + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxRsaExptMod: ret %x, req %lx in %p (%d), out %p (%d)\n", + ret, key->asyncDev.nitrox.reqId, in, inLen, out, *outLen); +#endif + ret = NitroxTranslateResponseCode(ret); if (ret != 0) { return ret; @@ -255,6 +305,12 @@ int NitroxRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, (word16)inLen, key->n.raw.buf, key->e.raw.buf, (byte*)in, out, &key->asyncDev.nitrox.reqId, key->asyncDev.nitrox.devId); #endif + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxRsaPublicEncrypt: ret %x, req %lx in %p (%d), out %p (%d)\n", + ret, key->asyncDev.nitrox.reqId, in, inLen, out, outLen); +#endif + ret = NitroxTranslateResponseCode(ret); if (ret != 0) { return ret; @@ -264,11 +320,6 @@ int NitroxRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, } -static INLINE void ato16(const byte* c, word16* u16) -{ - *u16 = (c[0] << 8) | (c[1]); -} - int NitroxRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32* outLen, RsaKey* key) { @@ -293,12 +344,18 @@ int NitroxRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, key->u.raw.buf, (byte*)in, &outLen, out, &key->asyncDev.nitrox.reqId, key->asyncDev.nitrox.devId); #endif + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxRsaPrivateDecrypt: ret %x, req %lx in %p (%d), out %p (%d)\n", + ret, key->asyncDev.nitrox.reqId, in, inLen, out, *outLen); +#endif + ret = NitroxTranslateResponseCode(ret); if (ret != 0) { return ret; } - ato16((const byte*)outLen, (word16*)outLen); + *outLen = ntohs(*outLen); return *outLen; } @@ -323,11 +380,17 @@ int NitroxRsaSSL_Sign(const byte* in, word32 inLen, byte* out, key->q.raw.buf, key->dQ.raw.buf, key->p.raw.buf, key->dP.raw.buf, key->u.raw.buf, (byte*)in, out, &key->asyncDev.nitrox.reqId); #else - ret = CspPkcs1v15CrtEnc(CAVIUM_REQ_MODE, BT1, key->n.raw.len,(word16)inLen, + ret = CspPkcs1v15CrtEnc(CAVIUM_REQ_MODE, BT1, key->n.raw.len, (word16)inLen, key->q.raw.buf, key->dQ.raw.buf, key->p.raw.buf, key->dP.raw.buf, key->u.raw.buf, (byte*)in, out, &key->asyncDev.nitrox.reqId, key->asyncDev.nitrox.devId); #endif + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxRsaSSL_Sign: ret %x, req %lx in %p (%d), out %p (%d)\n", + ret, key->asyncDev.nitrox.reqId, in, inLen, out, outLen); +#endif + ret = NitroxTranslateResponseCode(ret); if (ret != 0) { return ret; @@ -342,7 +405,8 @@ int NitroxRsaSSL_Verify(const byte* in, word32 inLen, byte* out, { int ret; - if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->n.raw.len) { + if (key == NULL || in == NULL || out == NULL || + inLen != (word32)key->n.raw.len) { return BAD_FUNC_ARG; } @@ -359,6 +423,12 @@ int NitroxRsaSSL_Verify(const byte* in, word32 inLen, byte* out, key->n.raw.buf, key->e.raw.buf, (byte*)in, &outLen, out, &key->asyncDev.nitrox.reqId, key->asyncDev.nitrox.devId); #endif + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxRsaSSL_Verify: ret %x, req %lx in %p (%d), out %p (%d)\n", + ret, key->asyncDev.nitrox.reqId, in, inLen, out, *outLen); +#endif + ret = NitroxTranslateResponseCode(ret); if (ret != 0) { return ret; @@ -371,193 +441,452 @@ int NitroxRsaSSL_Verify(const byte* in, word32 inLen, byte* out, #endif /* !NO_RSA */ + +#if defined(HAVE_ECC) && defined(HAVE_CAVIUM_V) + + +static int NitroxEccGetCid(ecc_key* key, CurveId* cid) +{ + int ret = 0; + + if (key == NULL || key->dp == NULL) + return BAD_FUNC_ARG; + + switch (key->dp->id) { + #if 0 /* ECDH P521 appears to be broken on Nitrox V v1.4 SDK */ + case ECC_SECP521R1: + *cid = P521; + break; + #endif + case ECC_SECP384R1: + *cid = P384; + break; + case ECC_SECP256R1: + *cid = P256; + break; + case ECC_SECP224R1: + *cid = P224; + break; + case ECC_SECP192R1: + *cid = P192; + break; + default: + ret = BAD_FUNC_ARG; + break; + } + + return ret; +} +int NitroxEccIsCurveSupported(ecc_key* key) +{ + CurveId cid; + return NitroxEccGetCid(key, &cid) == 0 ? 1 : 0; +} + +int NitroxEccGetSize(ecc_key* key) +{ + return ROUNDUP8(key->dp->size); +} + +int NitroxEccPad(WC_BIGINT* bi, word32 padTo) +{ + if (bi->len < padTo) { + int x = padTo - bi->len; + XMEMCPY(bi->buf + x, bi->buf, bi->len); + XMEMSET(bi->buf, 0, x); + bi->len = padTo; + } + return 0; +} + +int NitroxEccRsSplit(ecc_key* key, WC_BIGINT* r, WC_BIGINT* s) +{ + if (NitroxEccIsCurveSupported(key)) { + int rSz = NitroxEccGetSize(key); + + /* split r and s */ + XMEMCPY(s->buf, r->buf + rSz, key->dp->size); + XMEMSET(r->buf + key->dp->size, 0, key->dp->size); + r->len = key->dp->size; + s->len = key->dp->size; + } + return 0; +} + +#ifdef HAVE_ECC_DHE +int NitroxEcdh(ecc_key* key, + WC_BIGINT* k, WC_BIGINT* xG, WC_BIGINT* yG, + byte* out, word32* outlen, WC_BIGINT* q) +{ + int ret; + CurveId cid; + word32 curveSz; + + ret = NitroxEccGetCid(key, &cid); + if (ret < 0) + return ret; + + /* out buffer requires spaces for X and Y even though only X is used */ + curveSz = NitroxEccGetSize(key); + if (*outlen < curveSz * 2) + return BUFFER_E; + + /* init return codes */ + NitroxDevClear(&key->asyncDev); + + ret = CspECPointMul(key->asyncDev.nitrox.devId, CAVIUM_REQ_MODE, + CAVIUM_SSL_GRP, CAVIUM_DPORT, cid, + xG->buf, yG->buf, q->buf, k->len, k->buf, out, out + curveSz, + &key->asyncDev.nitrox.reqId); + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxEcdh: ret %x, req %lx out %p (%d)\n", + ret, key->asyncDev.nitrox.reqId, out, *outlen); +#endif + + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + return ret; +} +#endif /* HAVE_ECC_DHE */ + +#ifdef HAVE_ECC_SIGN +int NitroxEcdsaSign(ecc_key* key, + WC_BIGINT* m, WC_BIGINT* d, WC_BIGINT* k, + WC_BIGINT* r, WC_BIGINT* s, WC_BIGINT* q, WC_BIGINT* n) +{ + int ret; + CurveId cid; + + ret = NitroxEccGetCid(key, &cid); + if (ret < 0) + return ret; + + /* init return codes */ + NitroxDevClear(&key->asyncDev); + + (void)s; /* placed at end of R */ + + ret = CspECDSASign(key->asyncDev.nitrox.devId, CAVIUM_REQ_MODE, + CAVIUM_SSL_GRP, CAVIUM_DPORT, cid, q->buf, n->buf, k->len, k->buf, + m->len, m->buf, d->buf, r->buf, &key->asyncDev.nitrox.reqId); + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxEcdsaSign: ret %x, req %lx msg %p (%d), r %p\n", + ret, key->asyncDev.nitrox.reqId, m->buf, m->len, r->buf); +#endif + + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + return ret; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +int NitroxEcdsaVerify(ecc_key* key, + WC_BIGINT* m, WC_BIGINT* xp, WC_BIGINT* yp, + WC_BIGINT* r, WC_BIGINT* s, + WC_BIGINT* q, WC_BIGINT* n, int* stat) +{ + int ret; + CurveId cid; + int curveSz = key->dp->size; + + ret = NitroxEccGetCid(key, &cid); + if (ret < 0) + return ret; + + /* init return codes */ + NitroxDevClear(&key->asyncDev); + + /* adjust r and s for leading zero pad */ + NitroxEccPad(r, curveSz); + NitroxEccPad(s, curveSz); + + ret = CspECDSAVerify(key->asyncDev.nitrox.devId, CAVIUM_REQ_MODE, + CAVIUM_SSL_GRP, CAVIUM_DPORT, cid, r->buf, s->buf, m->len, m->buf, + n->buf, q->buf, xp->buf, yp->buf, &key->asyncDev.nitrox.reqId); + + /* hardware will ret failure if verify fails */ + *stat = 1; + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxEcdsaVerify: ret %x, req %lx msg %p (%d), r %p, s%p\n", + ret, key->asyncDev.nitrox.reqId, m->buf, m->len, r->buf, s->buf); +#endif + + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } + + return ret; +} +#endif /* HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC */ + + #ifndef NO_AES -#ifdef HAVE_AES_CBC +#if defined(HAVE_AES_CBC) || defined(HAVE_AESGCM) + static int NitroxAesGetType(Aes* aes, AesType* type) { int ret = 0; - if (aes->keylen == 16) - *type = AES_128_BIT; - else if (aes->keylen == 24) - *type = AES_192_BIT; - else if (aes->keylen == 32) - *type = AES_256_BIT; - else - ret = BAD_FUNC_ARG; + switch (aes->keylen) { + case 16: + *type = AES_128_BIT; + break; + case 24: + *type = AES_192_BIT; + break; + case 32: + *type = AES_256_BIT; + break; + default: + ret = BAD_FUNC_ARG; + break; + } return ret; } -int NitroxAesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 length) +static int NitroxAesEncrypt(Aes* aes, int aes_algo, + const byte* key, const byte* iv, + byte* out, const byte* in, word32 length, + word32 aad_len, const byte* aad, byte* tag) { - int ret; - wolfssl_word offset = 0; - AesType type; + int ret = 0, cav_ret = 0; + int offset = 0; + AesType aes_type; + const int blockMode = CAVIUM_BLOCKING; - ret = NitroxAesGetType(aes, &type); + ret = NitroxAesGetType(aes, &aes_type); if (ret != 0) { return ret; } /* init return codes */ - NitroxDevClear(&aes->asyncDev); + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&aes->asyncDev); + + while (length > 0) { + word32 slen = length; + if (slen > NITROX_MAX_BUF_LEN) + slen = NITROX_MAX_BUF_LEN; - while (length > NITROX_MAX_BUF_LEN) { - word16 slen = (word16)NITROX_MAX_BUF_LEN; #ifdef HAVE_CAVIUM_V - ret = CspEncryptAes(aes->asyncDev.nitrox.devId, CAVIUM_BLOCKING, + cav_ret = CspEncryptAes(aes->asyncDev.nitrox.devId, blockMode, DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, - aes->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, AES_CBC, - type, (byte*)aes->asyncKey, (byte*)aes->asyncIv, 0, NULL, NULL, - slen, (byte*)in + offset, out + offset, + aes->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, aes_algo, + aes_type, (byte*)key, (byte*)iv, aad_len, (byte*)aad, (byte*)tag, + (word16)slen, (byte*)in + offset, out + offset, &aes->asyncDev.nitrox.reqId); #else - ret = CspEncryptAes(CAVIUM_BLOCKING, aes->asyncDev.nitrox.contextHandle, - CAVIUM_NO_UPDATE, type, slen, (byte*)in + offset, out + offset, - (byte*)aes->asyncIv, (byte*)aes->asyncKey, - &aes->asyncDev.nitrox.reqId, aes->asyncDev.nitrox.devId); - #endif - ret = NitroxTranslateResponseCode(ret); - if (ret != 0) { - return ret; + if (aes_type != AES_CBC) { + ret = NOT_COMPILED_IN; + break; } - length -= NITROX_MAX_BUF_LEN; - offset += NITROX_MAX_BUF_LEN; - XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - } - if (length) { - word16 slen = (word16)length; - #ifdef HAVE_CAVIUM_V - ret = CspEncryptAes(aes->asyncDev.nitrox.devId, CAVIUM_BLOCKING, - DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, - aes->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, AES_CBC, - type, (byte*)aes->asyncKey, (byte*)aes->asyncIv, 0, NULL, NULL, - slen, (byte*)in + offset, out + offset, - &aes->asyncDev.nitrox.reqId); - #else - ret = CspEncryptAes(CAVIUM_BLOCKING, aes->asyncDev.nitrox.contextHandle, - CAVIUM_NO_UPDATE, type, slen, (byte*)in + offset, out + offset, - (byte*)aes->asyncIv, (byte*)aes->asyncKey, + + (void)aad_len; + (void)aad; + (void)tag; + + cav_ret = CspEncryptAes(blockMode, aes->asyncDev.nitrox.contextHandle, + CAVIUM_NO_UPDATE, aes_type, + (word16)slen, (byte*)in + offset, out + offset, (byte*)iv, (byte*)key, &aes->asyncDev.nitrox.reqId, aes->asyncDev.nitrox.devId); #endif - ret = NitroxTranslateResponseCode(ret); + ret = NitroxTranslateResponseCode(cav_ret); if (ret != 0) { - return ret; + break; } - XMEMCPY(aes->reg, out + offset+length - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + length -= slen; + offset += slen; + + XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); } - return 0; + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxAesEncrypt: ret %x (%d), algo %d, in %p, out %p, sz %d, iv %p, aad %p (%d), tag %p\n", + cav_ret, ret, aes_algo, in, out, offset, iv, aad, aad_len, tag); +#endif + + return ret; } #ifdef HAVE_AES_DECRYPT -int NitroxAesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 length) +static int NitroxAesDecrypt(Aes* aes, int aes_algo, + const byte* key, const byte* iv, + byte* out, const byte* in, word32 length, + word32 aad_len, const byte* aad, const byte* tag) { - int ret; - wolfssl_word offset = 0; - AesType type; + int ret = 0, cav_ret = 0; + int offset = 0; + AesType aes_type; + const int blockMode = CAVIUM_BLOCKING; - ret = NitroxAesGetType(aes, &type); + ret = NitroxAesGetType(aes, &aes_type); if (ret != 0) { return ret; } /* init return codes */ - NitroxDevClear(&aes->asyncDev); + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&aes->asyncDev); + + while (length > 0) { + word32 slen = length; + if (slen > NITROX_MAX_BUF_LEN) + slen = NITROX_MAX_BUF_LEN; - while (length > NITROX_MAX_BUF_LEN) { - word16 slen = (word16)NITROX_MAX_BUF_LEN; XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + #ifdef HAVE_CAVIUM_V - ret = CspDecryptAes(aes->asyncDev.nitrox.devId, CAVIUM_BLOCKING, + cav_ret = CspDecryptAes(aes->asyncDev.nitrox.devId, blockMode, DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, - aes->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, AES_CBC, - type, (byte*)aes->asyncKey, (byte*)aes->asyncIv, 0, NULL, NULL, - slen, (byte*)in + offset, out + offset, + aes->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, aes_algo, + aes_type, (byte*)key, (byte*)iv, aad_len, (byte*)aad, (byte*)tag, + (word16)slen, (byte*)in + offset, out + offset, &aes->asyncDev.nitrox.reqId); #else - ret = CspDecryptAes(CAVIUM_BLOCKING, aes->asyncDev.nitrox.contextHandle, - CAVIUM_NO_UPDATE, type, slen, (byte*)in + offset, out + offset, - (byte*)aes->asyncIv, (byte*)aes->asyncKey, - &aes->asyncDev.nitrox.reqId, aes->asyncDev.nitrox.devId); - #endif - ret = NitroxTranslateResponseCode(ret); - if (ret != 0) { - return ret; + if (aes_type != AES_CBC) { + ret = NOT_COMPILED_IN; + break; } - length -= NITROX_MAX_BUF_LEN; - offset += NITROX_MAX_BUF_LEN; - XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); - } - if (length) { - word16 slen = (word16)length; - XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - #ifdef HAVE_CAVIUM_V - ret = CspDecryptAes(aes->asyncDev.nitrox.devId, CAVIUM_BLOCKING, - DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, - aes->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, AES_CBC, - type, (byte*)aes->asyncKey, (byte*)aes->asyncIv, 0, NULL, NULL, - slen, (byte*)in + offset, out + offset, - &aes->asyncDev.nitrox.reqId); - #else - ret = CspDecryptAes(CAVIUM_BLOCKING, aes->asyncDev.nitrox.contextHandle, - CAVIUM_NO_UPDATE, type, slen, (byte*)in + offset, out + offset, - (byte*)aes->asyncIv, (byte*)aes->asyncKey, + + (void)aad_len; + (void)aad; + (void)tag; + + cav_ret = CspDecryptAes(blockMode, aes->asyncDev.nitrox.contextHandle, + CAVIUM_NO_UPDATE, aes_sz_type, + (word16)slen, (byte*)in + offset, out + offset, (byte*)iv, (byte*)key, &aes->asyncDev.nitrox.reqId, aes->asyncDev.nitrox.devId); #endif - ret = NitroxTranslateResponseCode(ret); + ret = NitroxTranslateResponseCode(cav_ret); if (ret != 0) { - return ret; + break; } + length -= slen; + offset += slen; + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); } - return 0; + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxAesDecrypt: ret %x (%d), algo %d, in %p, out %p, sz %d, iv %p, aad %p (%d), tag %p\n", + cav_ret, ret, aes_algo, in, out, offset, iv, aad, aad_len, tag); +#endif + + return ret; +} +#endif /* HAVE_AES_DECRYPT */ + +#ifdef HAVE_AES_CBC +int NitroxAesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 length) +{ + return NitroxAesEncrypt(aes, AES_CBC, + (byte*)aes->asyncKey, (byte*)aes->asyncIv, + out, in, length, 0, NULL, NULL); +} + +#ifdef HAVE_AES_DECRYPT +int NitroxAesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 length) +{ + return NitroxAesDecrypt(aes, AES_CBC, + (byte*)aes->asyncKey, (byte*)aes->asyncIv, + out, in, length, 0, NULL, NULL); } #endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AES_CBC */ + +#ifdef HAVE_AESGCM +int NitroxAesGcmEncrypt(Aes* aes, + byte* out, const byte* in, word32 sz, + const byte* key, word32 keySz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + (void)keySz; + (void)ivSz; + (void)authTagSz; + return NitroxAesEncrypt(aes, AES_GCM, key, iv, out, in, sz, + authInSz, authIn, authTag); +} +#ifdef HAVE_AES_DECRYPT +int NitroxAesGcmDecrypt(Aes* aes, + byte* out, const byte* in, word32 sz, + const byte* key, word32 keySz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + (void)keySz; + (void)ivSz; + (void)authTagSz; + return NitroxAesDecrypt(aes, AES_GCM, key, iv, out, in, sz, + authInSz, authIn, authTag); +} +#endif /* HAVE_AES_DECRYPT */ +#endif /* HAVE_AESGCM */ + +#endif /* HAVE_AES_CBC || HAVE_AESGCM */ #endif /* !NO_AES */ #if !defined(NO_ARC4) && !defined(HAVE_CAVIUM_V) -void NitroxArc4SetKey(Arc4* arc4, const byte* key, word32 length) +int NitroxArc4SetKey(Arc4* arc4, const byte* key, word32 length) { if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->asyncDev.nitrox.contextHandle, length, (byte*)key, &arc4->asyncDev.nitrox.reqId, arc4->devId) != 0) { WOLFSSL_MSG("Bad Cavium Arc4 Init"); + return ASYNC_INIT_E; } + return 0; } -void NitroxArc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) +int NitroxArc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) { - int ret; - wolfssl_word offset = 0; + int ret = 0, cav_ret = 0; + int offset = 0; + const int blockMode = CAVIUM_BLOCKING; /* init return codes */ - NitroxDevClear(&arc4->asyncDev); + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&arc4->asyncDev); - while (length > NITROX_MAX_BUF_LEN) { - word16 slen = (word16)NITROX_MAX_BUF_LEN; - ret = CspEncryptRc4(CAVIUM_BLOCKING, - arc4->asyncDev.nitrox.contextHandle, CAVIUM_UPDATE, slen, - (byte*)in + offset, out + offset, - &arc4->asyncDev.nitrox.reqId, arc4->devId); - ret = NitroxTranslateResponseCode(ret); - if (ret != 0) { - return ret; - } - length -= NITROX_MAX_BUF_LEN; - offset += NITROX_MAX_BUF_LEN; - } - if (length) { - word16 slen = (word16)length; - ret = CspEncryptRc4(CAVIUM_BLOCKING, - arc4->asyncDev.nitrox.contextHandle, CAVIUM_UPDATE, slen, + while (length > 0) { + word32 slen = length; + if (slen > NITROX_MAX_BUF_LEN) + slen = NITROX_MAX_BUF_LEN; + + cav_ret = CspEncryptRc4(blockMode, + arc4->asyncDev.nitrox.contextHandle, CAVIUM_UPDATE, (word16)slen, (byte*)in + offset, out + offset, &arc4->asyncDev.nitrox.reqId, arc4->devId); - ret = NitroxTranslateResponseCode(ret); + ret = NitroxTranslateResponseCode(cav_ret); if (ret != 0) { - return ret; + break; } + + length -= slen; + offset += slen; } + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxArc4Process: ret %x (%d), in %p, output %p, sz %d\n", + cav_ret, ret, in, output, offset); +#endif + + return ret; } #endif /* !NO_ARC4 && !HAVE_CAVIUM_V */ @@ -565,114 +894,96 @@ void NitroxArc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) #ifndef NO_DES3 int NitroxDes3CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 length) { - wolfssl_word offset = 0; - int ret; + int ret = 0, cav_ret = 0; + int offset = 0; + const int blockMode = CAVIUM_BLOCKING; /* init return codes */ - NitroxDevClear(&des3->asyncDev); + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&des3->asyncDev); + + while (length > 0) { + word32 slen = length; + if (slen > NITROX_MAX_BUF_LEN) + slen = NITROX_MAX_BUF_LEN; - while (length > NITROX_MAX_BUF_LEN) { - word16 slen = (word16)NITROX_MAX_BUF_LEN; #ifdef HAVE_CAVIUM_V - ret = CspEncrypt3Des(des3->asyncDev.nitrox.devId, CAVIUM_BLOCKING, + cav_ret = CspEncrypt3Des(des3->asyncDev.nitrox.devId, blockMode, DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, des3->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, DES3_CBC, - (byte*)des3->key_raw, (byte*)des3->iv_raw, slen, (byte*)in + offset, + (byte*)des3->key_raw, (byte*)des3->iv_raw, (word16)slen, (byte*)in + offset, out + offset, &des3->asyncDev.nitrox.reqId); #else - ret = CspEncrypt3Des(CAVIUM_BLOCKING, - des3->asyncDev.nitrox.contextHandle, CAVIUM_NO_UPDATE, slen, + cav_ret = CspEncrypt3Des(blockMode, + des3->asyncDev.nitrox.contextHandle, CAVIUM_NO_UPDATE, (word16)slen, (byte*)in + offset, out + offset, (byte*)des3->iv_raw, (byte*)des3->key_raw, &des3->asyncDev.nitrox.reqId, des3->asyncDev.nitrox.devId); #endif - ret = NitroxTranslateResponseCode(ret); + ret = NitroxTranslateResponseCode(cav_ret); if (ret != 0) { - return ret; + break; } - length -= NITROX_MAX_BUF_LEN; - offset += NITROX_MAX_BUF_LEN; + length -= slen; + offset += slen; + XMEMCPY(des3->reg, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE); } - if (length) { - word16 slen = (word16)length; - #ifdef HAVE_CAVIUM_V - ret = CspEncrypt3Des(des3->asyncDev.nitrox.devId, CAVIUM_BLOCKING, - DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, - des3->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, DES3_CBC, - (byte*)des3->key_raw, (byte*)des3->iv_raw, slen, (byte*)in + offset, - out + offset, &des3->asyncDev.nitrox.reqId); - #else - ret = CspEncrypt3Des(CAVIUM_BLOCKING, - des3->asyncDev.nitrox.contextHandle, CAVIUM_NO_UPDATE, slen, - (byte*)in + offset, out + offset, (byte*)des3->iv_raw, - (byte*)des3->key_raw, &des3->asyncDev.nitrox.reqId, - des3->asyncDev.nitrox.devId); - #endif - ret = NitroxTranslateResponseCode(ret); - if (ret != 0) { - return ret; - } - XMEMCPY(des3->reg, out+offset+length - DES_BLOCK_SIZE, DES_BLOCK_SIZE); - } - return 0; + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxDes3CbcEncrypt: ret %x (%d), in %p, out %p, sz %d\n", + cav_ret, ret, in, out, offset); +#endif + + return ret; } int NitroxDes3CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 length) { - wolfssl_word offset = 0; - int ret; + int ret = 0, cav_ret = 0; + int offset = 0; + const int blockMode = CAVIUM_BLOCKING; /* init return codes */ - NitroxDevClear(&des3->asyncDev); + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&des3->asyncDev); + + while (length > 0) { + word32 slen = length; + if (slen > NITROX_MAX_BUF_LEN) + slen = NITROX_MAX_BUF_LEN; - while (length > NITROX_MAX_BUF_LEN) { - word16 slen = (word16)NITROX_MAX_BUF_LEN; XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + #ifdef HAVE_CAVIUM_V - ret = CspDecrypt3Des(des3->asyncDev.nitrox.devId, CAVIUM_BLOCKING, - DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, - des3->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, DES3_CBC, - (byte*)des3->key_raw, (byte*)des3->iv_raw, slen, (byte*)in + offset, - out + offset, &des3->asyncDev.nitrox.reqId); - #else - ret = CspDecrypt3Des(CAVIUM_BLOCKING, - des3->asyncDev.nitrox.contextHandle, CAVIUM_NO_UPDATE, slen, - (byte*)in + offset, out + offset, (byte*)des3->iv_raw, - (byte*)des3->key_raw, &des3->asyncDev.nitrox.reqId, - des3->asyncDev.nitrox.devId); - #endif - ret = NitroxTranslateResponseCode(ret); - if (ret != 0) { - return ret; - } - length -= NITROX_MAX_BUF_LEN; - offset += NITROX_MAX_BUF_LEN; - XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE); - } - if (length) { - word16 slen = (word16)length; - XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE,DES_BLOCK_SIZE); - #ifdef HAVE_CAVIUM_V - ret = CspDecrypt3Des(des3->asyncDev.nitrox.devId, CAVIUM_BLOCKING, + cav_ret = CspDecrypt3Des(des3->asyncDev.nitrox.devId, blockMode, DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, des3->asyncDev.nitrox.contextHandle, FROM_DPTR, FROM_CTX, DES3_CBC, - (byte*)des3->key_raw, (byte*)des3->iv_raw, slen, (byte*)in + offset, + (byte*)des3->key_raw, (byte*)des3->iv_raw, (word16)slen, (byte*)in + offset, out + offset, &des3->asyncDev.nitrox.reqId); #else - ret = CspDecrypt3Des(CAVIUM_BLOCKING, - des3->asyncDev.nitrox.contextHandle, CAVIUM_NO_UPDATE, slen, + cav_ret = CspDecrypt3Des(blockMode, + des3->asyncDev.nitrox.contextHandle, CAVIUM_NO_UPDATE, (word16)slen, (byte*)in + offset, out + offset, (byte*)des3->iv_raw, (byte*)des3->key_raw, &des3->asyncDev.nitrox.reqId, des3->asyncDev.nitrox.devId); #endif - ret = NitroxTranslateResponseCode(ret); + ret = NitroxTranslateResponseCode(cav_ret); if (ret != 0) { - return ret; + break; } + length -= slen; + offset += slen; + XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE); } - return 0; + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxDes3CbcDecrypt: ret %x (%d), in %p, out %p, sz %d\n", + cav_ret, ret, in, out, offset); +#endif + + return ret; } #endif /* !NO_DES3 */ @@ -712,18 +1023,40 @@ static int NitroxHmacGetType(int type) #endif break; #endif - #ifdef HAVE_CAVIUM_V - #ifdef WOLFSSL_SHA512 - case WC_SHA512: - cav_type = SHA2_SHA512; - break; +#ifdef HAVE_CAVIUM_V + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + #ifdef HAVE_CAVIUM_V + cav_type = SHA2_SHA512; + #else + cav_type = SHA512_TYPE; #endif - #ifdef WOLFSSL_SHA384 - case WC_SHA384: - cav_type = SHA2_SHA384; - break; + break; + #endif + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + #ifdef HAVE_CAVIUM_V + cav_type = SHA2_SHA384; + #else + cav_type = SHA384_TYPE; #endif - #endif /* HAVE_CAVIUM_V */ + break; + #endif + #ifdef WOLFSSL_SHA3 + case WC_SHA3_224: + cav_type = SHA3_SHA224; + break; + case WC_SHA3_256: + cav_type = SHA3_SHA256; + break; + case WC_SHA3_384: + cav_type = SHA3_SHA384; + break; + case WC_SHA3_512: + cav_type = SHA3_SHA512; + break; + #endif /* WOLFSSL_SHA3 */ +#endif /* HAVE_CAVIUM_V */ default: WOLFSSL_MSG("unsupported cavium hmac type"); cav_type = -1; @@ -735,65 +1068,92 @@ static int NitroxHmacGetType(int type) int NitroxHmacUpdate(Hmac* hmac, const byte* msg, word32 length) { - word16 add = (word16)length; - word32 total; - byte* tmp; + int ret; + int cav_type = NitroxHmacGetType(hmac->macType); + const int blockMode = CAVIUM_BLOCKING; - if (length > NITROX_MAX_BUF_LEN) { - WOLFSSL_MSG("Too big msg for cavium hmac"); - return BUFFER_E; + if (cav_type == -1) { + return NOT_COMPILED_IN; } + /* init return codes */ + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&hmac->asyncDev); + if (hmac->innerHashKeyed == 0) { /* starting new */ - hmac->dataLen = 0; + #ifdef HAVE_CAVIUM_V + int digest_sz = wc_HmacSizeByType(hmac->macType); + ret = CspHmacStart(hmac->asyncDev.nitrox.devId, blockMode, + DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, + hmac->asyncDev.nitrox.contextHandle, cav_type, + hmac->keyLen, (byte*)hmac->ipad, length, (Uint8*)msg, + digest_sz, &hmac->asyncDev.nitrox.reqId); + #else + ret = CspHmacStart(blockMode, hmac->asyncDev.nitrox.contextHandle, + cav_type, hmac->keyLen, (byte*)hmac->ipad, length, msg, + &hmac->asyncDev.nitrox.reqId, hmac->asyncDev.nitrox.devId); + #endif + hmac->innerHashKeyed = 1; } + else { + /* do update */ - total = add + hmac->dataLen; - if (total > NITROX_MAX_BUF_LEN) { - WOLFSSL_MSG("Too big msg for cavium hmac"); - return BUFFER_E; + #ifdef HAVE_CAVIUM_V + ret = CspHmacUpdate(hmac->asyncDev.nitrox.devId, blockMode, + DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, + hmac->asyncDev.nitrox.contextHandle, cav_type, + length, (Uint8*)msg, &hmac->asyncDev.nitrox.reqId); + #else + ret = CspHmacUpdate(blockMode, hmac->asyncDev.nitrox.contextHandle, + cav_type, length, msg, + &hmac->asyncDev.nitrox.reqId, hmac->asyncDev.nitrox.devId); + #endif } - tmp = XMALLOC(hmac->dataLen + add, hmac->heap, DYNAMIC_TYPE_HMAC); - if (tmp == NULL) { - WOLFSSL_MSG("Out of memory for cavium update"); - return MEMORY_E; - } - if (hmac->dataLen) - XMEMCPY(tmp, hmac->data, hmac->dataLen); - XMEMCPY(tmp + hmac->dataLen, msg, add); +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxHmacUpdate: ret %x, msg %p, length %d\n", ret, msg, length); +#endif - hmac->dataLen += add; - XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_HMAC); - hmac->data = tmp; + ret = NitroxTranslateResponseCode(ret); + if (ret != 0) { + return ret; + } return 0; } -int NitroxHmacFinal(Hmac* hmac, int type, byte* hash, word16 hashLen) +int NitroxHmacFinal(Hmac* hmac, byte* hash, word16 hashLen) { int ret; - int cav_type = NitroxHmacGetType(type); + int cav_type = NitroxHmacGetType(hmac->macType); + const int blockMode = CAVIUM_BLOCKING; if (cav_type == -1) { return NOT_COMPILED_IN; } /* init return codes */ - NitroxDevClear(&hmac->asyncDev); + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&hmac->asyncDev); #ifdef HAVE_CAVIUM_V - ret = CspHmac(hmac->asyncDev.nitrox.devId, CAVIUM_BLOCKING, - DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, cav_type, - hmac->keyLen, (byte*)hmac->ipad, hmac->dataLen, hmac->data, hashLen, - hash, &hmac->asyncDev.nitrox.reqId); + ret = CspHmacFinish(hmac->asyncDev.nitrox.devId, blockMode, + DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, + hmac->asyncDev.nitrox.contextHandle, cav_type, + 0, NULL, hashLen, hash, + &hmac->asyncDev.nitrox.reqId); #else (void)hashLen; - ret = CspHmac(CAVIUM_BLOCKING, cav_type, NULL, hmac->keyLen, - (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, + ret = CspHmacFinish(blockMode, hmac->asyncDev.nitrox.contextHandle, + cav_type, 0, NULL, hash, &hmac->asyncDev.nitrox.reqId, hmac->asyncDev.nitrox.devId); #endif + +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxHmacFinal: ret %x, hash %p, hashLen %d\n", ret, hash, hashLen); +#endif + ret = NitroxTranslateResponseCode(ret); if (ret != 0) { return ret; @@ -807,46 +1167,42 @@ int NitroxHmacFinal(Hmac* hmac, int type, byte* hash, word16 hashLen) int NitroxRngGenerateBlock(WC_RNG* rng, byte* output, word32 sz) { - int ret; - wolfssl_word offset = 0; - CavReqId requestId; + int ret = 0, cav_ret = 0; + word32 offset = 0; + CavReqId requestId; + const int blockMode = CAVIUM_BLOCKING; /* init return codes */ - NitroxDevClear(&rng->asyncDev); + if (blockMode == CAVIUM_REQ_MODE) + NitroxDevClear(&rng->asyncDev); + + while (sz > 0) { + word32 slen = sz; + if (slen > NITROX_MAX_BUF_LEN) + slen = NITROX_MAX_BUF_LEN; - while (sz > NITROX_MAX_BUF_LEN) { - word16 slen = (word16)NITROX_MAX_BUF_LEN; - #ifdef HAVE_CAVIUM_V - ret = CspTrueRandom(rng->asyncDev.nitrox.devId, CAVIUM_BLOCKING, - DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, slen, - output + offset, &requestId); - #else - ret = CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, - rng->asyncDev.nitrox.devId); - #endif - ret = NitroxTranslateResponseCode(ret); - if (ret != 0) { - return ret; - } - sz -= NITROX_MAX_BUF_LEN; - offset += NITROX_MAX_BUF_LEN; - } - if (sz) { - word16 slen = (word16)sz; #ifdef HAVE_CAVIUM_V - ret = CspTrueRandom(rng->asyncDev.nitrox.devId, CAVIUM_BLOCKING, - DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, slen, + cav_ret = CspTrueRandom(rng->asyncDev.nitrox.devId, blockMode, + DMA_DIRECT_DIRECT, CAVIUM_SSL_GRP, CAVIUM_DPORT, (word16)slen, output + offset, &requestId); #else - ret = CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId, + cav_ret = CspRandom(blockMode, (word16)slen, output + offset, &requestId, rng->asyncDev.nitrox.devId); #endif - ret = NitroxTranslateResponseCode(ret); + ret = NitroxTranslateResponseCode(cav_ret); if (ret != 0) { - return ret; + break; } + + sz -= slen; + offset += slen; } +#ifdef WOLFSSL_NITROX_DEBUG + printf("NitroxRngGenerateBlock: ret %x (%d), output %p, sz %d\n", + cav_ret, ret, output, offset); +#endif + return ret; } diff --git a/wolfcrypt/src/port/intel/quickassist.c b/wolfcrypt/src/port/intel/quickassist.c index aec28a6..1a9178b 100644 --- a/wolfcrypt/src/port/intel/quickassist.c +++ b/wolfcrypt/src/port/intel/quickassist.c @@ -2387,41 +2387,39 @@ int IntelQaSymMd5(WC_ASYNC_DEV* dev, byte* out, const byte* in, word32 sz) #endif /* !NO_MD5 */ #ifndef NO_HMAC - int IntelQaHmac(struct WC_ASYNC_DEV* dev, - int macType, byte* keyRaw, word16 keyLen, - byte* out, const byte* in, word32 sz) + int IntelQaHmacGetType(int macType, word32* hashAlgorithm) { - CpaCySymHashAlgorithm hashAlgorithm; + int ret = 0; switch (macType) { #ifndef NO_MD5 case WC_MD5: - hashAlgorithm = CPA_CY_SYM_HASH_MD5; + if (hashAlgorithm) *hashAlgorithm = CPA_CY_SYM_HASH_MD5; break; #endif #ifndef NO_SHA case WC_SHA: - hashAlgorithm = CPA_CY_SYM_HASH_SHA1; + if (hashAlgorithm) *hashAlgorithm = CPA_CY_SYM_HASH_SHA1; break; #endif #ifdef WOLFSSL_SHA224 case WC_SHA224: - hashAlgorithm = CPA_CY_SYM_HASH_SHA224; + if (hashAlgorithm) *hashAlgorithm = CPA_CY_SYM_HASH_SHA224; break; #endif #ifndef NO_SHA256 case WC_SHA256: - hashAlgorithm = CPA_CY_SYM_HASH_SHA256; + if (hashAlgorithm) *hashAlgorithm = CPA_CY_SYM_HASH_SHA256; break; #endif #ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA384 case WC_SHA384: - hashAlgorithm = CPA_CY_SYM_HASH_SHA384; + if (hashAlgorithm) *hashAlgorithm = CPA_CY_SYM_HASH_SHA384; break; #endif case WC_SHA512: - hashAlgorithm = CPA_CY_SYM_HASH_SHA512; + if (hashAlgorithm) *hashAlgorithm = CPA_CY_SYM_HASH_SHA512; break; #endif #ifdef HAVE_BLAKE2 @@ -2430,6 +2428,19 @@ int IntelQaSymMd5(WC_ASYNC_DEV* dev, byte* out, const byte* in, word32 sz) default: return NOT_COMPILED_IN; } + return ret; + } + + int IntelQaHmac(struct WC_ASYNC_DEV* dev, + int macType, byte* keyRaw, word16 keyLen, + byte* out, const byte* in, word32 sz) + { + int ret; + CpaCySymHashAlgorithm hashAlgorithm; + + ret = IntelQaHmacGetType(macType, &hashAlgorithm); + if (ret != 0) + return ret; return IntelQaSymHash(dev, out, in, sz, CPA_CY_SYM_HASH_MODE_AUTH, hashAlgorithm, keyRaw, keyLen); diff --git a/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h b/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h index fe0d30a..d72f78e 100644 --- a/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h +++ b/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h @@ -24,39 +24,43 @@ #ifdef HAVE_CAVIUM -#include - #ifndef HAVE_CAVIUM_V #include "cavium_sysdep.h" #endif #include "cavium_common.h" -#ifndef HAVE_CAVIUM_V - #include "cavium_ioctl.h" -#else - #include "cavium_sym_crypto.h" - #include "cavium_asym_crypto.h" -#endif -#include #define CAVIUM_SSL_GRP 0 #define CAVIUM_DPORT 256 /* Compatibility with older Cavium SDK's */ #ifndef HAVE_CAVIUM_V - typedef int CspHandle; + typedef int CspHandle; typedef word32 CavReqId; #define AES_128 AES_128_BIT #define AES_192 AES_192_BIT #define AES_256 AES_256_BIT + + #define MAX_TO_POLL 30 + typedef int context_type_t; + + struct CspMultiRequestStatusBuffer { + int count; + CspRequestStatusBuffer req[MAX_TO_POLL]; + }; + #define AES_CBC 0x3 + #define AES_GCM 0x7 #else + typedef int CspHandle; + typedef word64 CavReqId; #define CAVIUM_DEV_ID 0 #define CAVIUM_BLOCKING BLOCKING #define CAVIUM_NON_BLOCKING NON_BLOCKING #define CAVIUM_DIRECT DMA_DIRECT_DIRECT - typedef Uint64 CavReqId; #endif +typedef struct CspMultiRequestStatusBuffer CspMultiRequestStatusBuffer; + #ifdef WOLFSSL_ASYNC_CRYPT #define CAVIUM_REQ_MODE CAVIUM_NON_BLOCKING #else @@ -65,7 +69,7 @@ #ifdef WOLFSSL_ASYNC_CRYPT - #define CAVIUM_MAX_PENDING 90 + #define CAVIUM_MAX_PENDING 10 /* 90 */ #define CAVIUM_MAX_POLL MAX_TO_POLL #endif @@ -73,18 +77,18 @@ typedef struct CaviumNitroxDev { CspHandle devId; /* nitrox device id */ context_type_t type; /* Typically CONTEXT_SSL, but also ECC types */ - Uint64 contextHandle; /* nitrox context memory handle */ + word64 contextHandle; /* nitrox context memory handle */ CavReqId reqId; /* Current requestId */ } CaviumNitroxDev; struct WOLF_EVENT; struct WC_ASYNC_DEV; -struct WC_RNG; - +struct WC_BIGINT; /* Wrapper API's */ WOLFSSL_LOCAL int NitroxTranslateResponseCode(int ret); WOLFSSL_LOCAL CspHandle NitroxGetDeviceHandle(void); +WOLFSSL_LOCAL CspHandle NitroxOpenDeviceDefault(void); WOLFSSL_LOCAL CspHandle NitroxOpenDevice(int dma_mode, int dev_id); WOLFSSL_LOCAL int NitroxAllocContext(struct WC_ASYNC_DEV* dev, CspHandle devId, context_type_t type); @@ -94,7 +98,7 @@ WOLFSSL_LOCAL void NitroxCloseDevice(CspHandle devId); #if defined(WOLFSSL_ASYNC_CRYPT) WOLFSSL_LOCAL int NitroxCheckRequest(struct WC_ASYNC_DEV* dev, struct WOLF_EVENT* event); WOLFSSL_LOCAL int NitroxCheckRequests(struct WC_ASYNC_DEV* dev, - struct CspMultiRequestStatusBuffer* req_stat_buf); + CspMultiRequestStatusBuffer* req_stat_buf); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -116,6 +120,34 @@ WOLFSSL_LOCAL int NitroxCheckRequests(struct WC_ASYNC_DEV* dev, byte* out, word32 *outLen, struct RsaKey* key); #endif /* !NO_RSA */ +#if defined(HAVE_ECC) && defined(HAVE_CAVIUM_V) + struct ecc_key; + WOLFSSL_LOCAL int NitroxEccGetSize(struct ecc_key* key); + WOLFSSL_LOCAL int NitroxEccRsSplit(struct ecc_key* key, + struct WC_BIGINT* r, struct WC_BIGINT* s); + WOLFSSL_LOCAL int NitroxEccIsCurveSupported(struct ecc_key* key); + WOLFSSL_LOCAL int NitroxEccPad(struct WC_BIGINT* bi, word32 padTo); + #ifdef HAVE_ECC_DHE + WOLFSSL_LOCAL int NitroxEcdh(struct ecc_key* key, + struct WC_BIGINT* k, struct WC_BIGINT* xG, struct WC_BIGINT* yG, + byte* out, word32* outlen, struct WC_BIGINT* q); + #endif /* HAVE_ECC_DHE */ + #ifdef HAVE_ECC_SIGN + WOLFSSL_LOCAL int NitroxEcdsaSign(struct ecc_key* key, + struct WC_BIGINT* m, struct WC_BIGINT* d, + struct WC_BIGINT* k, + struct WC_BIGINT* r, struct WC_BIGINT* s, + struct WC_BIGINT* q, struct WC_BIGINT* n); + #endif /* HAVE_ECC_SIGN */ + #ifdef HAVE_ECC_VERIFY + WOLFSSL_LOCAL int NitroxEcdsaVerify(struct ecc_key* key, + struct WC_BIGINT* m, struct WC_BIGINT* xp, + struct WC_BIGINT* yp, struct WC_BIGINT* r, + struct WC_BIGINT* s, struct WC_BIGINT* q, + struct WC_BIGINT* n, int* stat); + #endif /* HAVE_ECC_VERIFY */ +#endif /* HAVE_ECC */ + #ifndef NO_AES struct Aes; #ifdef HAVE_AES_CBC @@ -126,13 +158,30 @@ WOLFSSL_LOCAL int NitroxCheckRequests(struct WC_ASYNC_DEV* dev, const byte* in, word32 length); #endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AES_CBC */ + + #ifdef HAVE_AESGCM + WOLFSSL_LOCAL int NitroxAesGcmEncrypt(struct Aes* aes, + byte* out, const byte* in, word32 sz, + const byte* key, word32 keySz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + #ifdef HAVE_AES_DECRYPT + WOLFSSL_LOCAL int NitroxAesGcmDecrypt(struct Aes* aes, + byte* out, const byte* in, word32 sz, + const byte* key, word32 keySz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + #endif /* HAVE_AES_DECRYPT */ + #endif /* HAVE_AESGCM */ #endif /* !NO_AES */ #ifndef NO_RC4 struct Arc4; - WOLFSSL_LOCAL void NitroxArc4SetKey(struct Arc4* arc4, const byte* key, + WOLFSSL_LOCAL int NitroxArc4SetKey(struct Arc4* arc4, const byte* key, word32 length); - WOLFSSL_LOCAL void NitroxArc4Process(struct Arc4* arc4, byte* out, + WOLFSSL_LOCAL int NitroxArc4Process(struct Arc4* arc4, byte* out, const byte* in, word32 length); #endif /* !NO_RC4 */ @@ -150,10 +199,11 @@ WOLFSSL_LOCAL int NitroxCheckRequests(struct WC_ASYNC_DEV* dev, struct Hmac; WOLFSSL_LOCAL int NitroxHmacUpdate(struct Hmac* hmac, const byte* msg, word32 length); - WOLFSSL_LOCAL int NitroxHmacFinal(struct Hmac* hmac, int type, byte* hash, + WOLFSSL_LOCAL int NitroxHmacFinal(struct Hmac* hmac, byte* hash, word16 hashLen); #endif /* NO_HMAC */ +struct WC_RNG; WOLFSSL_API int NitroxRngGenerateBlock(struct WC_RNG* rng, byte* output, word32 sz); diff --git a/wolfssl/wolfcrypt/port/intel/quickassist.h b/wolfssl/wolfcrypt/port/intel/quickassist.h index 27b641a..db9bba7 100644 --- a/wolfssl/wolfcrypt/port/intel/quickassist.h +++ b/wolfssl/wolfcrypt/port/intel/quickassist.h @@ -372,6 +372,7 @@ WOLFSSL_LOCAL int IntelQaGetCyInstanceCount(void); #endif /* !NO_DH */ #ifndef NO_HMAC + WOLFSSL_LOCAL int IntelQaHmacGetType(int macType, word32* hashAlgorithm); WOLFSSL_LOCAL int IntelQaHmac(struct WC_ASYNC_DEV* dev, int macType, byte* keyRaw, word16 keyLen, byte* out, const byte* in, word32 sz);