diff --git a/configure.ac b/configure.ac index 6cc2e2e10..86a244908 100644 --- a/configure.ac +++ b/configure.ac @@ -762,6 +762,19 @@ fi AM_CONDITIONAL([BUILD_ARMASM], [test "x$ENABLED_ARMASM" = "xyes"]) +# Xilinx hardened crypto +AC_ARG_ENABLE([xilinx], + [AS_HELP_STRING([--enable-xilinx],[Enable wolfSSL support for Xilinx hardened crypto(default: disabled)])], + [ ENABLED_XILINX=$enableval ], + [ ENABLED_XILINX=no ] + ) +if test "$ENABLED_XILINX" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_XILINX -DWOLFSSL_XILINX_CRYPT" +fi + +AM_CONDITIONAL([BUILD_XILINX], [test "x$ENABLED_XILINX" = "xyes"]) + # INTEL AES-NI AC_ARG_ENABLE([aesni], [AS_HELP_STRING([--enable-aesni],[Enable wolfSSL AES-NI support (default: disabled)])], @@ -3892,6 +3905,7 @@ echo " * ARM ASM: $ENABLED_ARMASM" echo " * AES Key Wrap: $ENABLED_AESKEYWRAP" echo " * Write duplicate: $ENABLED_WRITEDUP" echo " * Intel Quick Assist: $ENABLED_INTEL_QA" +echo " * Xilinx Hardware Acc.: $ENABLED_XILINX" echo "" echo "---" diff --git a/src/bio.c b/src/bio.c index aa02a9ada..6b123c19a 100644 --- a/src/bio.c +++ b/src/bio.c @@ -19,6 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#if !defined(WOLFSSL_BIO_INCLUDED) + #warning bio.c does not need to be compiled seperatly from ssl.c +#else + /*** TBD ***/ WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg) { @@ -444,3 +448,5 @@ long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) return 0; } +#endif /* WOLFSSL_BIO_INCLUDED */ + diff --git a/src/internal.c b/src/internal.c index 59b207fe3..82ca56f6d 100755 --- a/src/internal.c +++ b/src/internal.c @@ -5617,6 +5617,27 @@ ProtocolVersion MakeDTLSv1_2(void) { return (word32) Seconds_get(); } +#elif defined(WOLFSSL_XILINX) + #include "xrtcpsu.h" + + word32 LowResTimer(void) + { + XRtcPsu_Config* con; + XRtcPsu rtc; + + con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID); + if (con != NULL) { + if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) + == XST_SUCCESS) { + return (word32)XRtcPsu_GetCurrentTime(&rtc); + } + else { + WOLFSSL_MSG("Unable to initialize RTC"); + } + } + + return 0; + } #elif defined(WOLFSSL_UTASKER) diff --git a/src/ssl.c b/src/ssl.c index 0944b0f11..725d478f0 100755 --- a/src/ssl.c +++ b/src/ssl.c @@ -12819,6 +12819,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return SSL_SUCCESS; /* success */ } +#define WOLFSSL_EVP_INCLUDED #include "wolfcrypt/src/evp.c" @@ -23408,6 +23409,7 @@ WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x, } #endif /* NO_DSA */ +#define WOLFSSL_BIO_INCLUDED #include "src/bio.c" #endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 03e0cc5cf..68681f549 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -104,6 +104,11 @@ #endif #include #include +#include + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* only for stack size check */ #ifdef HAVE_STACK_SIZE @@ -779,30 +784,38 @@ static void* benchmarks_do(void* args) #endif #endif #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 #ifndef NO_SW_BENCH bench_sha3_224(0); #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) bench_sha3_224(1); #endif + #endif /* WOLFSSL_NOSHA3_224 */ + #ifndef WOLFSSL_NOSHA3_256 #ifndef NO_SW_BENCH bench_sha3_256(0); #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) bench_sha3_256(1); #endif + #endif /* WOLFSSL_NOSHA3_256 */ + #ifndef WOLFSSL_NOSHA3_384 #ifndef NO_SW_BENCH bench_sha3_384(0); #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) bench_sha3_384(1); #endif + #endif /* WOLFSSL_NOSHA3_384 */ + #ifndef WOLFSSL_NOSHA3_512 #ifndef NO_SW_BENCH bench_sha3_512(0); #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) bench_sha3_512(1); #endif + #endif /* WOLFSSL_NOSHA3_512 */ #endif #ifdef WOLFSSL_RIPEMD bench_ripemd(); @@ -2097,6 +2110,7 @@ exit: #ifdef WOLFSSL_SHA3 +#ifndef WOLFSSL_NOSHA3_224 void bench_sha3_224(int doAsync) { Sha3 hash[BENCH_MAX_PENDING]; @@ -2169,7 +2183,9 @@ exit: bench_async_end(); } +#endif /* WOLFSSL_NOSHA3_224 */ +#ifndef WOLFSSL_NOSHA3_256 void bench_sha3_256(int doAsync) { Sha3 hash[BENCH_MAX_PENDING]; @@ -2242,7 +2258,9 @@ exit: bench_async_end(); } +#endif /* WOLFSSL_NOSHA3_256 */ +#ifndef WOLFSSL_NOSHA3_384 void bench_sha3_384(int doAsync) { Sha3 hash[BENCH_MAX_PENDING]; @@ -2315,7 +2333,9 @@ exit: bench_async_end(); } +#endif /* WOLFSSL_NOSHA3_384 */ +#ifndef WOLFSSL_NOSHA3_512 void bench_sha3_512(int doAsync) { Sha3 hash[BENCH_MAX_PENDING]; @@ -2388,6 +2408,7 @@ exit: bench_async_end(); } +#endif /* WOLFSSL_NOSHA3_512 */ #endif diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 0d8361124..a9bc7b2c4 100755 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -3528,6 +3528,10 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) } #endif /* FREESCALE_LTC_AES_GCM */ +#if defined(WOLFSSL_XILINX_CRYPT) + wc_AesGcmSetKey_ex(aes, key, len, XSECURE_CSU_AES_KEY_SRC_KUP); +#endif + return ret; } @@ -3993,7 +3997,7 @@ static void GMULT(byte* X, byte* Y) } -static void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; @@ -4142,7 +4146,7 @@ static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE]) } -static void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; @@ -4237,7 +4241,7 @@ static void GMULT(word64* X, word64* Y) } -static void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { word64 x[2] = {0,0}; @@ -4374,7 +4378,7 @@ static void GMULT(word32* X, word32* Y) } -static void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, +void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { word32 x[4] = {0,0,0,0}; @@ -4473,6 +4477,7 @@ static void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, #endif /* end GCM_WORD32 */ +#if !defined(WOLFSSL_XILINX_CRYPT) int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz, @@ -4971,6 +4976,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, } #endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */ +#endif /* (WOLFSSL_XILINX_CRYPT) */ WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len) { diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6dab254cd..e94c131bf 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -188,8 +188,8 @@ ASN Options: #include #define XTIME(t1) windows_time((t1)) #define WOLFSSL_GMTIME - #else + /* default */ /* uses complete facility */ #include @@ -420,6 +420,34 @@ time_t XTIME(time_t * timer) #endif /* WOLFSSL_TIRTOS */ +#if defined(WOLFSSL_XILINX) +#include "xrtcpsu.h" + +time_t XTIME(time_t * timer) +{ + time_t sec = 0; + XRtcPsu_Config* con; + XRtcPsu rtc; + + con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID); + if (con != NULL) { + if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) == XST_SUCCESS) { + sec = (time_t)XRtcPsu_GetCurrentTime(&rtc); + } + else { + WOLFSSL_MSG("Unable to initialize RTC"); + } + } + + if (timer != NULL) + *timer = sec; + + return sec; +} + +#endif /* WOLFSSL_TIRTOS */ + + static INLINE word32 btoi(byte b) { return (word32)(b - 0x30); @@ -1878,6 +1906,12 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, GetInt(&key->dQ, input, inOutIdx, inSz) < 0 || GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E; +#ifdef WOLFSSL_XILINX_CRYPT + if (wc_InitRsaHw(key) != 0) { + return BAD_STATE_E; + } +#endif + return 0; } #endif /* HAVE_USER_RSA */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index aabe9fc08..be81be9c6 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -19,6 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#if !defined(WOLFSSL_EVP_INCLUDED) + #warning evp.c does not need to be compiled seperatly from ssl.c +#else + static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher); WOLFSSL_API int wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx, @@ -537,3 +541,5 @@ WOLFSSL_API int wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest) /* nothing to do */ return 0; } +#endif /* WOLFSSL_EVP_INCLUDED */ + diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index fd5c3ca47..21e4392e7 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -53,7 +53,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/arm/armv8-sha256.c \ wolfcrypt/src/port/nxp/ksdk_port.c \ wolfcrypt/src/port/atmel/atmel.c \ - wolfcrypt/src/port/atmel/README.md + wolfcrypt/src/port/atmel/README.md \ + wolfcrypt/src/port/xilinx/xil-sha3.c \ + wolfcrypt/src/port/xilinx/xil-aesgcm.c if BUILD_CAVIUM src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 466335eea..9b46f2d8b 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -1461,7 +1461,7 @@ static void GMULT(byte* X, byte* Y) } -static void GHASH(Aes* aes, const byte* a, word32 aSz, +void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; @@ -4100,7 +4100,7 @@ static void GMULT(byte* X, byte* Y) } -static void GHASH(Aes* aes, const byte* a, word32 aSz, +void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { byte x[AES_BLOCK_SIZE]; diff --git a/wolfcrypt/src/port/xilinx/xil-aesgcm.c b/wolfcrypt/src/port/xilinx/xil-aesgcm.c new file mode 100755 index 000000000..8d0e2f6b1 --- /dev/null +++ b/wolfcrypt/src/port/xilinx/xil-aesgcm.c @@ -0,0 +1,202 @@ +/* xil-aesgcm.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if !defined(NO_AES) && defined(WOLFSSL_XILINX_CRYPT) + +#include + + +#ifdef HAVE_AESGCM +/* Make calls to Xilinx hardened AES-GCM crypto */ + +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#include "xparameters.h" + +enum { + AEAD_NONCE_SZ = 12, + AES_GCM_AUTH_SZ = 16, /* AES-GCM Auth Tag length */ +}; + + +int wc_AesGcmSetKey_ex(Aes* aes, const byte* key, word32 len, word32 kup) +{ + XCsuDma_Config* con; + + if (aes == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + if (len != 32) { + WOLFSSL_MSG("Expecting a 256 bit key"); + return BAD_FUNC_ARG; + } + + if ((con = XCsuDma_LookupConfig(0)) == NULL) { + WOLFSSL_MSG("Failed to look up config"); + return MEMORY_E; + } + + /* XST_SUCCESS comes from Xilinx header file */ + if (XCsuDma_CfgInitialize(&(aes->dma), con, con->BaseAddress) != + XST_SUCCESS) { + WOLFSSL_MSG("Failied to initialize hardware"); + return MEMORY_E; + } + + aes->keylen = len; + aes->kup = kup; + XMEMCPY((byte*)(aes->key_init), key, len); + + return 0; +} + + + +int wc_AesGcmEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + byte* tmp; + byte scratch[AES_BLOCK_SIZE]; + byte initalCounter[AES_BLOCK_SIZE]; + + if ((in == NULL && sz > 0) || iv == NULL || authTag == NULL || + authTagSz > AES_GCM_AUTH_SZ) { + return BAD_FUNC_ARG; + } + + if (ivSz != AEAD_NONCE_SZ) { + WOLFSSL_MSG("Expecting an IV size of 12"); + return BAD_FUNC_ARG; + } + + /* API expects that output is size of input + 16 byte tag. A temporary + * buffer is created to keep AES encrypt from writing over the end of + * out buffer. */ + if (in != NULL) { + if (aes->keylen != 32) { + WOLFSSL_MSG("Expecting 256 bit AES key"); + return BAD_FUNC_ARG; + } + + tmp = (byte*)XMALLOC(sz + AES_GCM_AUTH_SZ, aes->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + return MEMORY_E; + } + + XSecure_AesInitialize(&(aes->xilAes), &(aes->dma), aes->kup, (word32*)iv, + aes->key_init); + XSecure_AesEncryptData(&(aes->xilAes), tmp, in, sz); + XMEMCPY(out, tmp, sz); + XMEMCPY(authTag, tmp + sz, authTagSz); + XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* handle completing tag with any additional data */ + if (authIn != NULL) { + /* @TODO avoid hashing out again since Xilinx call already does */ + XMEMSET(initalCounter, 0, AES_BLOCK_SIZE); + XMEMCPY(initalCounter, iv, ivSz); + initalCounter[AES_BLOCK_SIZE - 1] = 1; + GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); + wc_AesEncryptDirect(aes, scratch, initalCounter); + xorbuf(authTag, scratch, authTagSz); + } + + return 0; +} + + +int wc_AesGcmDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + byte* tag; + byte buf[AES_GCM_AUTH_SZ]; + byte scratch[AES_BLOCK_SIZE]; + byte initalCounter[AES_BLOCK_SIZE]; + + if (in == NULL || iv == NULL || authTag == NULL || + authTagSz < AES_GCM_AUTH_SZ) { + return BAD_FUNC_ARG; + } + + if (ivSz != AEAD_NONCE_SZ) { + WOLFSSL_MSG("Expecting an IV size of 12"); + return BAD_FUNC_ARG; + } + + /* account for additional data */ + if (authIn != NULL && authInSz > 0) { + XMEMSET(initalCounter, 0, AES_BLOCK_SIZE); + XMEMCPY(initalCounter, iv, ivSz); + initalCounter[AES_BLOCK_SIZE - 1] = 1; + tag = buf; + GHASH(aes, NULL, 0, in, sz, tag, AES_GCM_AUTH_SZ); + wc_AesEncryptDirect(aes, scratch, initalCounter); + xorbuf(tag, scratch, AES_GCM_AUTH_SZ); + } + else { + tag = authTag; + } + + /* calls to hardened crypto */ + XSecure_AesInitialize(&(aes->xilAes), &(aes->dma), aes->kup, + (word32*)iv, aes->key_init); + XSecure_AesDecryptData(&(aes->xilAes), out, in, sz, tag); + + /* account for additional data */ + if (authIn != NULL && authInSz > 0) { + GHASH(aes, authIn, authInSz, in, sz, tag, AES_GCM_AUTH_SZ); + wc_AesEncryptDirect(aes, scratch, initalCounter); + xorbuf(tag, scratch, AES_GCM_AUTH_SZ); + if (ConstantCompare(authTag, tag, authTagSz) != 0) { + return AES_GCM_AUTH_E; + } + } + + return 0; + +} +#endif /* HAVE_AESGCM */ + +#endif diff --git a/wolfcrypt/src/port/xilinx/xil-sha3.c b/wolfcrypt/src/port/xilinx/xil-sha3.c new file mode 100755 index 000000000..151d89522 --- /dev/null +++ b/wolfcrypt/src/port/xilinx/xil-sha3.c @@ -0,0 +1,158 @@ +/* xil-sha3.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + + +#if defined(WOLFSSL_SHA3) && defined(WOLFSSL_XILINX_CRYPT) + +#include +#include +#include + +#if !defined(WOLFSSL_NOSHA3_224) || !defined(WOLFSSL_NOSHA3_256) \ + || !defined(WOLFSSL_NOSHA3_512) + #error sizes of SHA3 other than 384 are not supported +#endif + +/* Initialize hardware for SHA3 operations + * + * sha SHA3 structure to initialize + * heap memory heap hint to use + * devId used for async operations (currently not supported here) + */ +int wc_InitSha3_384(Sha3* sha, void* heap, int devId) +{ + XCsuDma_Config* con; + + (void)heap; + (void)devId; + + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + if ((con = XCsuDma_LookupConfig(0)) == NULL) { + WOLFSSL_MSG("Unable to look up configure for SHA3"); + return BAD_STATE_E; + } + + /* XST_SUCCESS is success macro from Xilinx header */ + if (XCsuDma_CfgInitialize(&(sha->dma), con, con->BaseAddress) != + XST_SUCCESS) { + WOLFSSL_MSG("Unable to initialize CsuDma"); + return BAD_STATE_E; + } + + XSecure_Sha3Initialize(&(sha->hw), &(sha->dma)); + XSecure_Sha3Start(&(sha->hw)); + + return 0; +} + + +/* Update SHA3 state + * + * sha SHA3 structure to update + * data message to update SHA3 state with + * len length of data buffer + */ +int wc_Sha3_384_Update(Sha3* sha, const byte* data, word32 len) +{ + if (sha == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + XSecure_Sha3Update(&(sha->hw), (byte*)data, len); + + return 0; +} + + +/* Finalize SHA3 state and get digest + * + * sha SHA3 structure to get hash + * out digest out, expected to be large enough to hold SHA3 digest + */ +int wc_Sha3_384_Final(Sha3* sha, byte* out) +{ + if (sha == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + XSecure_Sha3Finish(&(sha->hw), out); + + return wc_InitSha3_384(sha, NULL, INVALID_DEVID); +} + + +/* Free SHA3 structure + * + * sha SHA3 structure to free + */ +void wc_Sha3_384_Free(Sha3* sha) +{ + (void)sha; + /* nothing to free yet */ +} + + +/* Get SHA3 digest without finalize SHA3 state + * + * sha SHA3 structure to get hash + * out digest out, expected to be large enough to hold SHA3 digest + */ +int wc_Sha3_384_GetHash(Sha3* sha, byte* out) +{ + Sha3 s; + + if (sha == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + + if (wc_Sha3_384_Copy(sha, &s) != 0) { + WOLFSSL_MSG("Unable to copy SHA3 structure"); + return MEMORY_E; + } + + return wc_Sha3_384_Final(&s, out); +} + + +/* Get copy of SHA3 structure + * + * src SHA3 structure to make copy of + * dst [out]structure to hold copy + */ +int wc_Sha3_384_Copy(Sha3* src, Sha3* dst) +{ + if (src == NULL || dst== NULL) { + return BAD_FUNC_ARG; + } + + XMEMCPY((byte*)dst, (byte*)src, sizeof(Sha3)); + return 0; +} + +#endif diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 55ed7eed6..fb4426aec 100755 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -251,6 +251,11 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) return ret; } +#ifdef WOLFSSL_XILINX_CRYPT + key->pubExp = 0; + key->mod = NULL; +#endif + return ret; } @@ -259,6 +264,82 @@ int wc_InitRsaKey(RsaKey* key, void* heap) return wc_InitRsaKey_ex(key, heap, INVALID_DEVID); } + +#ifdef WOLFSSL_XILINX_CRYPT +#define MAX_E_SIZE 4 +/* Used to setup hardware state + * + * key the RSA key to setup + * + * returns 0 on success + */ +int wc_InitRsaHw(RsaKey* key) +{ + unsigned char* m; /* RSA modulous */ + word32 e = 0; /* RSA public exponent */ + int mSz; + int eSz; + + if (key == NULL) { + return BAD_FUNC_ARG; + } + + mSz = mp_unsigned_bin_size(&(key->n)); + m = (unsigned char*)XMALLOC(mSz, key->heap, DYNAMIC_TYPE_KEY); + if (m == 0) { + return MEMORY_E; + } + + if (mp_to_unsigned_bin(&(key->n), m) != MP_OKAY) { + WOLFSSL_MSG("Unable to get RSA key modulous"); + XFREE(m, key->heap, DYNAMIC_TYPE_KEY); + return MP_READ_E; + } + + eSz = mp_unsigned_bin_size(&(key->e)); + if (eSz > MAX_E_SIZE) { + WOLFSSL_MSG("Expnonent of size 4 bytes expected"); + XFREE(m, key->heap, DYNAMIC_TYPE_KEY); + return BAD_FUNC_ARG; + } + + if (mp_to_unsigned_bin(&(key->e), (byte*)&e + (MAX_E_SIZE - eSz)) + != MP_OKAY) { + XFREE(m, key->heap, DYNAMIC_TYPE_KEY); + WOLFSSL_MSG("Unable to get RSA key exponent"); + return MP_READ_E; + } + + /* check for existing mod buffer to avoid memory leak */ + if (key->mod != NULL) { + XFREE(key->mod, key->heap, DYNAMIC_TYPE_KEY); + } + + key->pubExp = e; + key->mod = m; + + if (XSecure_RsaInitialize(&(key->xRsa), key->mod, NULL, + (byte*)&(key->pubExp)) != XST_SUCCESS) { + WOLFSSL_MSG("Unable to initialize RSA on hardware"); + XFREE(m, key->heap, DYNAMIC_TYPE_KEY); + return BAD_STATE_E; + } + +#ifdef WOLFSSL_XILINX_PATCH + /* currently a patch of xsecure_rsa.c for 2048 bit keys */ + if (wc_RsaEncryptSize(key) == 256) { + if (XSecure_RsaSetSize(&(key->xRsa), 2048) != XST_SUCCESS) { + WOLFSSL_MSG("Unable to set RSA key size on hardware"); + XFREE(m, key->heap, DYNAMIC_TYPE_KEY); + return BAD_STATE_E; + } + } +#endif + + return 0; +} +#endif /* WOLFSSL_XILINX_CRYPT */ + int wc_FreeRsaKey(RsaKey* key) { int ret = 0; @@ -293,6 +374,11 @@ int wc_FreeRsaKey(RsaKey* key) mp_clear(&key->e); mp_clear(&key->n); +#ifdef WOLFSSL_XILINX_CRYPT + XFREE(key->mod, key->heap, DYNAMIC_TYPE_KEY); + key->mod = NULL; +#endif + return ret; } @@ -986,6 +1072,55 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out, return ret; } +#if defined(WOLFSSL_XILINX_CRYPT) +/* + * Xilinx hardened crypto acceleration. + * + * Returns 0 on success and negative values on error. + */ +static int wc_RsaFunctionXil(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng) +{ + int ret = 0; + word32 keyLen, len; + (void)rng; + + keyLen = wc_RsaEncryptSize(key); + if (keyLen > *outLen) { + WOLFSSL_MSG("Output buffer is not big enough"); + return BAD_FUNC_ARG; + } + + if (inLen != keyLen) { + WOLFSSL_MSG("Expected that inLen equals RSA key length"); + return BAD_FUNC_ARG; + } + + switch(type) { + case RSA_PRIVATE_DECRYPT: + case RSA_PRIVATE_ENCRYPT: + /* Currently public exponent is loaded by default. + * In SDK 2017.1 RSA exponent values are expected to be of 4 bytes + * leading to private key operations with Xsecure_RsaDecrypt not being + * supported */ + ret = RSA_WRONG_TYPE_E; + break; + case RSA_PUBLIC_ENCRYPT: + case RSA_PUBLIC_DECRYPT: + if (XSecure_RsaDecrypt(&(key->xRsa), in, out) != XST_SUCCESS) { + ret = BAD_STATE_E; + } + break; + default: + ret = RSA_WRONG_TYPE_E; + } + + *outLen = keyLen; + + return ret; +} +#endif /* WOLFSSL_XILINX_CRYPT */ + static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, word32* outLen, int type, RsaKey* key, WC_RNG* rng) { @@ -1103,9 +1238,14 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, } case RSA_PUBLIC_ENCRYPT: case RSA_PUBLIC_DECRYPT: + #ifdef WOLFSSL_XILINX_CRYPT + ret = wc_RsaFunctionXil(in, inLen, out, outLen, type, key, rng); + goto done; + #else if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY) ERROR_OUT(MP_EXPTMOD_E); break; + #endif default: ERROR_OUT(RSA_WRONG_TYPE_E); } @@ -1565,7 +1705,6 @@ int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } - #ifndef WC_NO_RSA_OAEP int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, int type, @@ -1832,6 +1971,12 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return err; } +#ifdef WOLFSSL_XILINX_CRYPT + if (wc_InitRsaHw(key) != 0) { + return BAD_STATE_E; + } +#endif + return 0; } #endif /* WOLFSSL_KEY_GEN */ diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index a217531e9..26c1a4337 100755 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -26,7 +26,7 @@ #include -#ifdef WOLFSSL_SHA3 +#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT) #include #include diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 0da437aaa..08c7e9574 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -301,7 +301,7 @@ int mp_test(void); #endif int logging_test(void); int mutex_test(void); -#ifdef USE_WOLFSSL_MEMORY +#if defined(USE_WOLFSSL_MEMORY) && !defined(FREERTOS) int memcb_test(void); #endif @@ -852,7 +852,7 @@ int wolfcrypt_test(void* args) else printf( "mutex test passed!\n"); -#ifdef USE_WOLFSSL_MEMORY +#if defined(USE_WOLFSSL_MEMORY) && !defined(FREERTOS) if ( (ret = memcb_test()) != 0) return err_sys("memcb test failed!\n", ret); else @@ -1784,6 +1784,7 @@ int sha384_test(void) #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA3 +#ifndef WOLFSSL_NOSHA3_224 static int sha3_224_test(void) { Sha3 sha; @@ -1835,7 +1836,9 @@ static int sha3_224_test(void) return 0; } +#endif /* WOLFSSL_NOSHA3_224 */ +#ifndef WOLFSSL_NOSHA3_256 static int sha3_256_test(void) { Sha3 sha; @@ -1889,7 +1892,9 @@ static int sha3_256_test(void) return 0; } +#endif /* WOLFSSL_NOSHA3_256 */ +#ifndef WOLFSSL_NOSHA3_384 static int sha3_384_test(void) { Sha3 sha; @@ -1945,7 +1950,9 @@ static int sha3_384_test(void) return 0; } +#endif /* WOLFSSL_NOSHA3_384 */ +#ifndef WOLFSSL_NOSHA3_512 static int sha3_512_test(void) { Sha3 sha; @@ -2003,19 +2010,28 @@ static int sha3_512_test(void) return 0; } +#endif /* WOLFSSL_NOSHA3_512 */ int sha3_test(void) { int ret; +#ifndef WOLFSSL_NOSHA3_224 if ((ret = sha3_224_test()) != 0) return ret; +#endif +#ifndef WOLFSSL_NOSHA3_256 if ((ret = sha3_256_test()) != 0) return ret; +#endif +#ifndef WOLFSSL_NOSHA3_384 if ((ret = sha3_384_test()) != 0) return ret; +#endif +#ifndef WOLFSSL_NOSHA3_512 if ((ret = sha3_512_test()) != 0) return ret; +#endif return 0; } @@ -4533,7 +4549,8 @@ int aesgcm_test(void) }; #if !defined(HAVE_FIPS) && !defined(HAVE_INTEL_QA) && \ - !defined(STM32F2_CRYPTO) && !defined(STM32F4_CRYPTO) + !defined(STM32F2_CRYPTO) && !defined(STM32F4_CRYPTO) && \ + !defined(WOLFSSL_XILINX_CRYPT) /* Test Case 12, uses same plaintext and AAD data. */ const byte k2[] = { @@ -4615,7 +4632,8 @@ int aesgcm_test(void) /* FIPS, QAT and STM32F2/4 HW Crypto only support 12-byte IV */ #if !defined(HAVE_FIPS) && !defined(HAVE_INTEL_QA) && \ - !defined(STM32F2_CRYPTO) && !defined(STM32F4_CRYPTO) + !defined(STM32F2_CRYPTO) && !defined(STM32F4_CRYPTO) && \ + !defined(WOLFSSL_XILINX_CRYPT) XMEMSET(resultT, 0, sizeof(resultT)); XMEMSET(resultC, 0, sizeof(resultC)); XMEMSET(resultP, 0, sizeof(resultP)); @@ -13689,7 +13707,7 @@ int mutex_test(void) return 0; } -#ifdef USE_WOLFSSL_MEMORY +#if defined(USE_WOLFSSL_MEMORY) && !defined(FREERTOS) static int malloc_cnt = 0; static int realloc_cnt = 0; static int free_cnt = 0; diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index e5c7dbf49..4a561a5c5 100755 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -48,6 +48,10 @@ #endif /* WOLFSSL_AESNI */ +#ifdef WOLFSSL_XILINX_CRYPT +#include "xsecure_aes.h" +#endif + #endif /* HAVE_FIPS */ #ifdef __cplusplus @@ -99,6 +103,12 @@ typedef struct Aes { #ifdef WOLFSSL_PIC32MZ_CRYPT word32 key_ce[AES_BLOCK_SIZE*2/sizeof(word32)] ; word32 iv_ce [AES_BLOCK_SIZE /sizeof(word32)] ; +#endif +#ifdef WOLFSSL_XILINX_CRYPT + XSecure_Aes xilAes; + XCsuDma dma; + word32 key_init[8]; + word32 kup; #endif void* heap; /* memory hint to use */ } Aes; @@ -153,6 +163,10 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* iv, int dir); #endif #ifdef HAVE_AESGCM +#ifdef WOLFSSL_XILINX_CRYPT + WOLFSSL_API int wc_AesGcmSetKey_ex(Aes* aes, const byte* key, word32 len, + word32 kup); +#endif WOLFSSL_API int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len); WOLFSSL_API int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, @@ -169,6 +183,8 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz, const byte* authIn, word32 authInSz, byte* authTag, word32 authTagSz); + WOLFSSL_LOCAL void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, + word32 cSz, byte* s, word32 sSz); #endif /* HAVE_AESGCM */ #ifdef HAVE_AESCCM WOLFSSL_API int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz); diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 66115c932..a2a741f34 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -68,7 +68,8 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/ti/ti-ccm.h \ wolfssl/wolfcrypt/port/nrf51.h \ wolfssl/wolfcrypt/port/nxp/ksdk_port.h \ - wolfssl/wolfcrypt/port/atmel/atmel.h + wolfssl/wolfcrypt/port/atmel/atmel.h \ + wolfssl/wolfcrypt/port/xilinx/xil-sha3.h if BUILD_ASYNCCRYPT nobase_include_HEADERS+= wolfssl/wolfcrypt/async.h diff --git a/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h b/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h new file mode 100755 index 000000000..062deca01 --- /dev/null +++ b/wolfssl/wolfcrypt/port/xilinx/xil-sha3.h @@ -0,0 +1,45 @@ +/* xil-sha3.h + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLF_XIL_CRYPT_SHA3_H +#define WOLF_XIL_CRYPT_SHA3_H + +#ifdef WOLFSSL_SHA3 +#include "xsecure_sha.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Sha3 digest */ +typedef struct Sha3 { + XSecure_Sha3 hw; + XCsuDma dma; +} Sha3; + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_SHA3 */ +#endif /* WOLF_XIL_CRYPT_SHA3_H */ + diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 30938fd16..41ec55bda 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -46,6 +46,10 @@ /* header file needed for OAEP padding */ #include +#ifdef WOLFSSL_XILINX_CRYPT +#include "xsecure_rsa.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -99,6 +103,11 @@ struct RsaKey { CertSignCtx certSignCtx; /* context info for cert sign (MakeSignature) */ #endif #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLFSSL_XILINX_CRYPT + word32 pubExp; /* to keep values in scope they are here in struct */ + byte* mod; + XSecure_Rsa xRsa; +#endif byte dataIsAlloc; }; @@ -112,6 +121,9 @@ struct RsaKey { WOLFSSL_API int wc_InitRsaKey(RsaKey* key, void* heap); WOLFSSL_API int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId); WOLFSSL_API int wc_FreeRsaKey(RsaKey* key); +#ifdef WOLFSSL_XILINX_CRYPT +WOLFSSL_LOCAL int wc_InitRsaHw(RsaKey* key); +#endif /* WOLFSSL_XILINX_CRYPT */ WOLFSSL_LOCAL int wc_RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen, int type, RsaKey* key, WC_RNG* rng); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 58d1bd2c6..be9b478c6 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -150,6 +150,12 @@ /* Uncomment next line if building for RIOT-OS */ /* #define WOLFSSL_RIOT_OS */ +/* Uncomment next line if building for using XILINX hardened crypto */ +/* #define WOLFSSL_XILINX_CRYPT */ + +/* Uncomment next line if building for using XILINX */ +/* #define WOLFSSL_XILINX */ + #include #ifdef WOLFSSL_USER_SETTINGS @@ -1236,6 +1242,28 @@ extern void uITRON4_free(void *p) ; #endif /* WOLFSSL_QL */ +#if defined(WOLFSSL_XILINX) + #define USER_TIME /* XTIME in asn.c */ + #define NO_WOLFSSL_DIR + #define NO_DEV_RANDOM + #define HAVE_AESGCM +#endif + +#if defined(WOLFSSL_XILINX_CRYPT) + #if defined(WOLFSSL_ARMASM) + #error can not use both ARMv8 instructions and XILINX hardened crypto + #endif + #if defined(WOLFSSL_SHA3) + /* only SHA3-384 is supported */ + #undef WOLFSSL_NOSHA3_224 + #undef WOLFSSL_NOSHA3_256 + #undef WOLFSSL_NOSHA3_512 + #define WOLFSSL_NOSHA3_224 + #define WOLFSSL_NOSHA3_256 + #define WOLFSSL_NOSHA3_512 + #endif +#endif /*(WOLFSSL_XILINX_CRYPT)*/ + #if !defined(XMALLOC_USER) && !defined(MICRIUM_MALLOC) && \ !defined(WOLFSSL_LEANPSK) && !defined(NO_WOLFSSL_MEMORY) && \ !defined(XMALLOC_OVERRIDE) @@ -1598,11 +1626,10 @@ extern void uITRON4_free(void *p) ; /* both CURVE and ED small math should be enabled */ #ifdef CURVED25519_SMALL - #define CURVE25519_SMALL - #define ED25519_SMALL + #define CURVE25519_SMALL + #define ED25519_SMALL #endif - /* warning for not using harden build options (default with ./configure) */ #ifndef WC_NO_HARDEN #if (defined(USE_FAST_MATH) && !defined(TFM_TIMING_RESISTANT)) || \ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 4d8ef1f64..8ef8d4678 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -83,7 +83,7 @@ typedef struct Sha256 { #endif /* FREESCALE_LTC_SHA */ } Sha256; -#else /* WOLFSSL_TI_HASH */ +#else #include "wolfssl/wolfcrypt/port/ti/ti-hash.h" #endif diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index 28f5af7a7..c48d76c47 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -62,6 +62,9 @@ enum { }; +#ifdef WOLFSSL_XILINX_CRYPT + #include "wolfssl/wolfcrypt/port/xilinx/xil-sha3.h" +#else /* Sha3 digest */ typedef struct Sha3 { /* State data that is processed for each block. */ @@ -77,7 +80,7 @@ typedef struct Sha3 { WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ } Sha3; - +#endif #endif /* HAVE_FIPS */ WOLFSSL_API int wc_InitSha3_224(Sha3*, void*, int);