diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 69a6d0f6e0..60f500c432 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -220,6 +220,9 @@ #ifdef HAVE_RENESAS_SYNC #include #endif + #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include + #endif #endif #ifdef WOLFSSL_ASYNC_CRYPT @@ -3167,8 +3170,9 @@ static void* benchmarks_do(void* args) #endif #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \ defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC) || \ - defined(HAVE_RENESAS_SYNC) || defined(WOLFSSL_CAAM)) && \ - !defined(NO_HW_BENCH) + defined(HAVE_RENESAS_SYNC) || defined(WOLFSSL_CAAM)) || \ + ((defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ + defined(WOLF_CRYPTO_CB)) && !defined(NO_HW_BENCH) bench_aes_aad_options_wrap(bench_aesgcm, 1); #endif #ifndef NO_SW_BENCH @@ -14254,6 +14258,15 @@ void bench_sphincsKeySign(byte level, byte optim) return (double)tv.SECONDS + (double)tv.MILLISECONDS / 1000; } +#elif (defined(WOLFSSL_MAX3266X_OLD) || defined(WOLFSSL_MAX3266X)) \ + && defined(MAX3266X_RTC) + + double current_time(int reset) + { + (void)reset; + return wc_MXC_RTC_Time(); + } + #elif defined(FREESCALE_KSDK_BM) double current_time(int reset) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index aaafbf4019..4c9a8d1811 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -82,6 +82,17 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #include #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include +#ifdef MAX3266X_CB + /* Revert back to SW so HW CB works */ + /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */ + #include + /* Turn off MAX3266X_AES in the context of this file when using CB */ + #undef MAX3266X_AES +#endif +#endif + #if defined(WOLFSSL_TI_CRYPT) #include #else @@ -2205,7 +2216,8 @@ static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock, } #if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \ - !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) + !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \ + !defined(MAX3266X_AES) /* Encrypt a number of blocks using AES. * * @param [in] aes AES object. @@ -2789,6 +2801,12 @@ extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz); static WARN_UNUSED_RESULT int wc_AesEncrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#if defined(MAX3266X_AES) + word32 keySize; +#endif +#if defined(MAX3266X_CB) + int ret_cb; +#endif word32 r; if (aes == NULL) { @@ -2892,6 +2910,26 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt( } #endif +#if defined(MAX3266X_AES) + if (wc_AesGetKeySize(aes, &keySize) == 0) { + return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, AES_BLOCK_SIZE, + outBlock, (unsigned int)keySize); + } +#endif +#ifdef MAX3266X_CB /* Can do a basic ECB block */ + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, + AES_BLOCK_SIZE); + if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret_cb; + /* fall-through when unavailable */ + } +#endif + AesEncrypt_C(aes, inBlock, outBlock, r); return 0; @@ -3172,7 +3210,8 @@ static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock, } #if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \ - !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) + !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \ + !defined(MAX3266X_AES) /* Decrypt a number of blocks using AES. * * @param [in] aes AES object. @@ -3539,6 +3578,12 @@ static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz) static WARN_UNUSED_RESULT int wc_AesDecrypt( Aes* aes, const byte* inBlock, byte* outBlock) { +#if defined(MAX3266X_AES) + word32 keySize; +#endif +#if defined(MAX3266X_CB) + int ret_cb; +#endif word32 r; if (aes == NULL) { @@ -3615,6 +3660,27 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( } /* else !wc_esp32AesSupportedKeyLen for ESP32 */ #endif +#if defined(MAX3266X_AES) + if (wc_AesGetKeySize(aes, &keySize) == 0) { + return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, AES_BLOCK_SIZE, + outBlock, (unsigned int)keySize); + } +#endif + +#ifdef MAX3266X_CB /* Can do a basic ECB block */ + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, + AES_BLOCK_SIZE); + if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret_cb; + /* fall-through when unavailable */ + } +#endif + AesDecrypt_C(aes, inBlock, outBlock, r); return 0; @@ -4103,7 +4169,8 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) XMEMCPY(rk, key, keySz); #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ - (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) + (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \ + !defined(MAX3266X_AES) /* Always reverse words when using only SW */ { ByteReverseWords(rk, rk, keySz); @@ -4250,7 +4317,7 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) } /* switch */ ForceZero(&temp, sizeof(temp)); -#if defined(HAVE_AES_DECRYPT) +#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES) if (dir == AES_DECRYPTION) { unsigned int j; @@ -4546,8 +4613,8 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #ifndef WC_AES_BITSLICED #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ - (!defined(WOLFSSL_ESP32_CRYPT) || \ - defined(NO_WOLFSSL_ESP32_CRYPT_AES)) + (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \ + && !defined(MAX3266X_AES) /* software */ ByteReverseWords(aes->key, aes->key, keylen); @@ -5378,6 +5445,91 @@ int wc_AesSetIV(Aes* aes, const byte* iv) } #endif /* HAVE_AES_DECRYPT */ +#elif defined(MAX3266X_AES) + int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + word32 keySize; + int status; + byte *iv; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + /* Always enforce a length check */ + if (sz % AES_BLOCK_SIZE) { + #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + return BAD_LENGTH_E; + #else + return BAD_FUNC_ARG; + #endif + } + if (sz == 0) { + return 0; + } + + iv = (byte*)aes->reg; + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key, + MXC_TPU_MODE_CBC, sz, out, + (unsigned int)keySize); + /* store iv for next call */ + if (status == 0) { + XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + return (status == 0) ? 0 : -1; + } + + #ifdef HAVE_AES_DECRYPT + int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + word32 keySize; + int status; + byte *iv; + byte temp_block[AES_BLOCK_SIZE]; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + /* Always enforce a length check */ + if (sz % AES_BLOCK_SIZE) { + #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + return BAD_LENGTH_E; + #else + return BAD_FUNC_ARG; + #endif + } + if (sz == 0) { + return 0; + } + + iv = (byte*)aes->reg; + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + /* get IV for next call */ + XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key, + MXC_TPU_MODE_CBC, sz, out, + keySize); + + /* store iv for next call */ + if (status == 0) { + XMEMCPY(iv, temp_block, AES_BLOCK_SIZE); + } + return (status == 0) ? 0 : -1; + } + #endif /* HAVE_AES_DECRYPT */ + + + #elif defined(WOLFSSL_PIC32MZ_CRYPT) int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) @@ -11405,6 +11557,48 @@ int wc_AesGetKeySize(Aes* aes, word32* keySize) #elif defined(WOLFSSL_RISCV_ASM) /* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */ +#elif defined(MAX3266X_AES) + +int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + int status; + word32 keySize; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) + return BAD_FUNC_ARG; + + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, sz, out, keySize); + + return status; +} + +#ifdef HAVE_AES_DECRYPT +int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + int status; + word32 keySize; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) + return BAD_FUNC_ARG; + + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, sz, out, keySize); + + return status; +} +#endif /* HAVE_AES_DECRYPT */ + #elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) /* Software AES - ECB */ diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index d510bb4382..23355493e9 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -55,7 +55,6 @@ #ifdef WOLFSSL_CAAM #include #endif - /* TODO: Consider linked list with mutex */ #ifndef MAX_CRYPTO_DEVID_CALLBACKS #define MAX_CRYPTO_DEVID_CALLBACKS 8 diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index e6a93af6d4..675415f843 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -139,7 +139,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c \ wolfcrypt/src/port/Renesas/README.md \ wolfcrypt/src/port/cypress/psoc6_crypto.c \ - wolfcrypt/src/port/liboqs/liboqs.c + wolfcrypt/src/port/liboqs/liboqs.c \ + wolfcrypt/src/port/maxim/max3266x.c $(ASYNC_FILES): $(AM_V_at)touch $(srcdir)/$@ diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 4a3e3dc24f..87df6f0895 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -44,6 +44,17 @@ #endif #endif +#ifdef WOLF_CRYPTO_CB + #include + +/* Enable Hardware Callback */ +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + /* Revert back to SW so HW CB works */ + /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */ + #include +#endif +#endif + #include #include @@ -14928,6 +14939,20 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int crypto_cb_ret = + wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, + authTag, authTagSz, authIn, authInSz); + if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return crypto_cb_ret; + /* fall-through when unavailable */ + } +#endif + XMEMCPY(B+1, nonce, nonceSz); lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz; B[0] = (authInSz > 0 ? 64 : 0) @@ -15000,6 +15025,20 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int crypto_cb_ret = + wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz, + authTag, authTagSz, authIn, authInSz); + if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return crypto_cb_ret; + /* fall-through when unavailable */ + } +#endif + o = out; oSz = inSz; XMEMCPY(B+1, nonce, nonceSz); @@ -16534,7 +16573,14 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, return BAD_FUNC_ARG; } #endif - +#ifdef WOLF_CRYPTO_CB + if (aes->devId != INVALID_DEVID) { + if (keylen > sizeof(aes->devKey)) { + return BAD_FUNC_ARG; + } + XMEMCPY(aes->devKey, userKey, keylen); + } +#endif #ifdef WOLFSSL_AES_COUNTER aes->left = 0; #endif /* WOLFSSL_AES_COUNTER */ @@ -16584,6 +16630,20 @@ static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) return KEYUSAGE_E; } +#ifdef MAX3266X_CB /* Can do a basic ECB block */ + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, + AES_BLOCK_SIZE); + if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return ret_cb; + } + /* fall-through when unavailable */ + } +#endif + AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds); return 0; @@ -16598,6 +16658,19 @@ static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) return KEYUSAGE_E; } +#ifdef MAX3266X_CB /* Can do a basic ECB block */ + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, + AES_BLOCK_SIZE); + if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret_cb; + /* fall-through when unavailable */ + } +#endif + AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds); return 0; @@ -16652,6 +16725,18 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) #endif } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz); + if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return crypto_cb_ret; + /* fall-through when unavailable */ + } +#endif + AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds, (unsigned char*)aes->reg); @@ -16681,6 +16766,18 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #endif } + #ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz); + if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return crypto_cb_ret; + /* fall-through when unavailable */ + } + #endif + AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds, (unsigned char*)aes->reg); @@ -16703,6 +16800,18 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E); return KEYUSAGE_E; } + #ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz); + if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return crypto_cb_ret; + /* fall-through when unavailable */ + } + #endif + tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; /* consume any unused bytes left in aes->tmp */ @@ -17080,6 +17189,13 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) return BAD_FUNC_ARG; } + + #ifdef WOLF_CRYPTO_CB + if (aes->devId != INVALID_DEVID) { + XMEMCPY(aes->devKey, key, len); + } + #endif + XMEMSET(iv, 0, AES_BLOCK_SIZE); ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); @@ -17241,6 +17357,20 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, return KEYUSAGE_E; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int crypto_cb_ret = + wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag, + authTagSz, authIn, authInSz); + if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return crypto_cb_ret; + /* fall-through when unavailable */ + } +#endif + XMEMSET(initialCounter, 0, AES_BLOCK_SIZE); if (ivSz == GCM_NONCE_MID_SZ) { XMEMCPY(initialCounter, iv, ivSz); @@ -17329,6 +17459,20 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (aes->devId != INVALID_DEVID) + #endif + { + int crypto_cb_ret = + wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz, + authTag, authTagSz, authIn, authInSz); + if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return crypto_cb_ret; + /* fall-through when unavailable */ + } +#endif + XMEMSET(initialCounter, 0, AES_BLOCK_SIZE); if (ivSz == GCM_NONCE_MID_SZ) { XMEMCPY(initialCounter, iv, ivSz); diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 45d4292a54..dabe7af9c3 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -57,6 +57,10 @@ #include #endif +#ifdef WOLF_CRYPTO_CB + #include +#endif + #if defined(FREESCALE_MMCAU_SHA) #ifdef FREESCALE_MMCAU_CLASSIC_SHA #include "cau_api.h" @@ -1513,25 +1517,44 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) { + int ret = 0; if (sha256 == NULL) return BAD_FUNC_ARG; + ret = InitSha256(sha256); + if (ret != 0) + return ret; sha256->heap = heap; #ifdef WOLF_CRYPTO_CB sha256->devId = devId; + sha256->devCtx = NULL; #endif - (void)devId; - return InitSha256(sha256); +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Init(&(sha256->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + (void)devId; + return ret; } int wc_InitSha256(wc_Sha256* sha256) { - return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha256_ex(sha256, NULL, devId); } void wc_Sha256Free(wc_Sha256* sha256) { +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha256->mxcCtx)); +#endif (void)sha256; } @@ -1541,6 +1564,18 @@ int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (sha256->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + } +#endif + return Sha256Update(sha256, data, len); } @@ -1573,6 +1608,18 @@ int wc_Sha256Final(wc_Sha256* sha256, byte* hash) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (sha256->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + } +#endif + ret = Sha256Final(sha256, hash); if (ret != 0) return ret; @@ -1621,6 +1668,13 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) XMEMCPY(dst, src, sizeof(wc_Sha256)); +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + return ret; } diff --git a/wolfcrypt/src/port/arm/armv8-sha512.c b/wolfcrypt/src/port/arm/armv8-sha512.c index 145f6b5ebb..5a0691bee3 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512.c +++ b/wolfcrypt/src/port/arm/armv8-sha512.c @@ -172,6 +172,10 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId, #ifdef WOLFSSL_SMALL_STACK_CACHE sha512->W = NULL; #endif +#ifdef WOLF_CRYPTO_CB + sha512->devId = devId; + sha512->devCtx = NULL; +#endif if (type == WC_HASH_TYPE_SHA512) { ret = InitSha512(sha512); @@ -201,6 +205,12 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId, int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) { +#ifdef MAX3266X_SHA_CB + if (wc_MXC_TPU_SHA_Init(&(sha512->mxcCtx)) != 0) { + return BAD_FUNC_ARG; + } +#endif + return InitSha512_Family(sha512, heap, devId, WC_HASH_TYPE_SHA512); } @@ -508,6 +518,18 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (sha512->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + } +#endif + return Sha512Update(sha512, data, len); } @@ -626,13 +648,20 @@ static int Sha512_Family_Final(wc_Sha512* sha512, byte* hash, return BAD_FUNC_ARG; #ifdef WOLF_CRYPTO_CB - if (sha512->devId != INVALID_DEVID) { - ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, hash); - if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + #ifndef WOLF_CRYPTO_CB_FIND + if (sha512->devId != INVALID_DEVID) + #endif + { + byte localHash[WC_SHA512_DIGEST_SIZE]; + ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, localHash); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + XMEMCPY(hash, localHash, digestSz); return ret; + } /* fall-through when unavailable */ } #endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) { #if defined(HAVE_INTEL_QA) @@ -661,7 +690,12 @@ int wc_Sha512Final(wc_Sha512* sha512, byte* hash) int wc_InitSha512(wc_Sha512* sha512) { - return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID); + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha512_ex(sha512, NULL, devId); } void wc_Sha512Free(wc_Sha512* sha512) @@ -673,6 +707,11 @@ void wc_Sha512Free(wc_Sha512* sha512) XFREE(sha512->W, NULL, DYNAMIC_TYPE_TMP_BUFFER); sha512->W = NULL; #endif + +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha512->mxcCtx)); +#endif + } #ifdef OPENSSL_EXTRA @@ -724,6 +763,18 @@ int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (sha384->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha384Hash(sha384, data, len, NULL); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + } +#endif + return Sha512Update((wc_Sha512*)sha384, data, len); } @@ -757,6 +808,18 @@ int wc_Sha384Final(wc_Sha384* sha384, byte* hash) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (sha384->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Sha384Hash(sha384, NULL, 0, hash); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + } +#endif + ret = Sha512Final((wc_Sha512*)sha384); if (ret != 0) return ret; @@ -782,7 +845,16 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) #ifdef WOLFSSL_SMALL_STACK_CACHE sha384->W = NULL; #endif - +#ifdef WOLF_CRYPTO_CB + sha384->devId = devId; + sha384->devCtx = NULL; +#endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Init(&(sha384->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif (void)devId; return ret; @@ -790,7 +862,12 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) int wc_InitSha384(wc_Sha384* sha384) { - return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID); + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha384_ex(sha384, NULL, devId); } void wc_Sha384Free(wc_Sha384* sha384) @@ -802,6 +879,11 @@ void wc_Sha384Free(wc_Sha384* sha384) XFREE(sha384->W, NULL, DYNAMIC_TYPE_TMP_BUFFER); sha384->W = NULL; #endif + +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha384->mxcCtx)); +#endif + } #endif /* WOLFSSL_SHA384 */ @@ -880,6 +962,13 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) dst->flags |= WC_HASH_FLAG_ISCOPY; #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + return ret; } @@ -1037,6 +1126,13 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) dst->flags |= WC_HASH_FLAG_ISCOPY; #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + return ret; } diff --git a/wolfcrypt/src/port/maxim/README.md b/wolfcrypt/src/port/maxim/README.md index 55cb2a04c6..3919ffd0f9 100644 --- a/wolfcrypt/src/port/maxim/README.md +++ b/wolfcrypt/src/port/maxim/README.md @@ -1,14 +1,144 @@ -wolfSSL using Analog Devices MAXQ1065 or MAX1080 +wolfSSL using Analog Devices MAXQ1065, MAX1080, MAX32665 or MAX32666 ================================================ ## Overview wolfSSL can be configured to use the MAXQ1065 or MAX1080 cryptographic -controllers. Product datasheets, user guides and other resources can be found at +controllers. wolfSSL can also be configure to utilize the TPU +(crypto accelerator), MAA (math accelerator), and TRNG available on select +MAX32665 and MAX32666 microcontroller. + +Product datasheets, user guides and other resources can be found at Analog Devices website: https://www.analog.com +# MAX32665/MAX32666 +## Build and Usage + +wolfSSL supports the [Maxim SDK](https://github.com/analogdevicesinc/msdk), to +utilize the TPU and MAA located on the devices. + +Building is supported by adding `#define WOLFSSL_MAX3266X` to `user_settings.h`. +wolfSSL supports the usage of the older style API Maxim provides with the +`#define WOLFSSL_MAX3266X_OLD` to `user_settings.h`. + +When using `WOLFSSL_MAX3266X` or `WOLFSSL_MAX3266X_OLD` you will also need to +add `#define WOLFSSL_SP_MATH_ALL` to `user_settings.h`. + +If you want to be more specific on what hardware acceleration you want to use, +this can be done by adding any combination of these defines: +``` +#define MAX3266X_RNG - Allows usage of TRNG device +#define MAX3266X_AES - Allows usage of TPU for AES Acceleration +#define MAX3266X_SHA - Allows usage of TPU for Hash Acceleration +#define MAX3266X_MATH - Allows usage of MAA for MOD based Math Acceleration +``` +For this you will still need to use `#define WOLFSSL_MAX3266X` or `#define WOLFSSL_MAX3266X_OLD`. +When you use a specific hardware define like `#define MAX3266X_RNG` this will +mean only the TRNG device is being used, and all other operations will use the +default software implementations. + +The other prerequisite is that a change needs to be made to the Maxim SDK. This +is to use the MAA Math Accelerator, this change only needs to be made if you are +using `#define WOLFSSL_MAX3266X` or `define WOLFSSL_MAX3266X_OLD` by themselves +or you are specifying `#define MAX3266X_MATH`. This is only needed if you are +not using the latest Maxim SDK. + +In the SDK you will need to find the underlying function that +`MXC_TPU_MAA_Compute()` from `tpu.h` compute calls in the newer SDK. In the +older SDK this function is called `MAA_Compute()` in `maa.h`. In the underlying +function you will need to this: + +``` +MXC_SETFIELD(tpu->maa_ctrl, MXC_F_TPU_REVA_MAA_CTRL_CLC, clc); +``` +to +``` +MXC_SETFIELD(tpu->maa_ctrl, MXC_F_TPU_REVA_MAA_CTRL_CLC, + clc << MXC_F_TPU_REVA_MAA_CTRL_CLC_POS); +``` + +This bug has been reported to Analog Devices and a PR has been made +[here](https://github.com/analogdevicesinc/msdk/pull/1104) +if you want to know more details on the issue, or use a patch. + + +## Supported Algos +Using these defines will replace software implementations with a call to the +hardware. + +`#define MAX3266X_RNG` +- Uses entropy from TRNG to seed HASHDRBG + +`#define MAX3266X_AES`: + +- AES-CBC: 128, 192, 256 +- AES-ECB: 128, 192, 256 + +`#define MAX3266X_SHA`: + +- SHA-1 +- SHA-224 +- SHA-256 +- SHA-384 +- SHA-512 + +Please note that when using `MAX3266X_SHA` there will be a limitation when +attempting to do a larger sized hash as the SDK for the hardware currently +expects a the whole msg buffer to be given. + +`#define MAX3266X_MATH` (Replaces math operation calls for algos +like RSA and ECC key generation): + +- mod: `a mod m = r` +- addmod: `(a+b)mod m = r` +- submod: `(a-b)mod m = r` +- mulmod: `(a*b)mod m = r` +- sqrmod: `(b^2)mod m = r` +- exptmod: `(b^e)mod m = r` + +## Crypto Callback Support +This port also supports using the Crypto Callback functionality in wolfSSL. +When `WOLF_CRYPTO_CB` is defined in `user_settings.h` along with +`WOLFSSL_MAX3266X` or `WOLFSSL_MAX3266X_OLD` it will build the library to allow +the ability to switch between hardware and software implementations. + +Crypto Callbacks only support using the hardware for these Algorithms: + +- AES ECB: 128, 192, 256 +- AES CBC: 128, 192, 256 +- SHA-1 +- SHA-256 +- SHA-384 +- SHA-512 + +When using `WOLF_CRYPTO_CB` and `WOLFSSL_MAX3266X` or `WOLFSSL_MAX3266X_OLD`, +`MAX3266X_MATH` is turned off and is is currently not supported to use with +`WOLF_CRYPTO_CB`. + +The Hardware of the port will be used by default when no devId is set. +To use software versions of the support Callback Algorithms the devId will need +to be set to `INVALID_DEVID`. + +For more information about Crypto Callbacks and how to use them please refer to +the [wolfSSL manual](https://www.wolfssl.com/documentation/manuals/wolfssl/chapter06.html). + +## Extra Information +For more Verbose info you can use `#define DEBUG_WOLFSSL` in combination with +`#define MAX3266X_VERBOSE` to see if errors are occurring during the hardware +setup/ + +To reproduce benchmark numbers you can use `#define MAX3266X_RTC`. +Do note that this will only work with `#define WOLFSSL_MAX3266X` and not +`#define WOLFSSL_MAX3266X_OLD`. This is only meant for benchmark reproduction +and not for any other application. Please implement your own rtc/time code for +anything else. + +For more information about the TPU, MAA, and TRNG please refer to the +[MAX32665/MAX32666 User Guide: UG6971](https://www.analog.com/media/en/technical-documentation/user-guides/max32665max32666-user-guide.pdf) + +# MAXQ1065/MAX1080 ## Build and Usage Please use the appropriate SDK or Evkit to build wolfSSL. diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c new file mode 100644 index 0000000000..6dc324df0e --- /dev/null +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -0,0 +1,1552 @@ +/* max3266x.c + * + * Copyright (C) 2006-2024 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_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + +#include +#include + +#include +#include +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#ifdef WOLF_CRYPTO_CB + #include +#endif + +#if defined(USE_FAST_MATH) || defined(USE_INTEGER_HEAP_MATH) + #error MXC Not Compatible with Fast Math or Heap Math + #include + #define MXC_WORD_SIZE DIGIT_BIT +#elif defined(WOLFSSL_SP_MATH_ALL) + #include + #define MXC_WORD_SIZE SP_WORD_SIZE +#else + #error MXC HW port needs #define WOLFSSL_SP_MATH_ALL +#endif + +/* Max size MAA can handle */ +#define MXC_MAA_MAX_SIZE (2048 / MXC_WORD_SIZE) + +int wc_MXC_TPU_Init(void) +{ + /* Initialize the TPU device */ + if (MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TRNG) != 0) { + MAX3266X_MSG("Device did not initialize"); + return RNG_FAILURE_E; + } + return 0; +} + +int wc_MXC_TPU_Shutdown(void) +{ + /* Shutdown the TPU device */ +#if defined(WOLFSSL_MAX3266X_OLD) + MXC_TPU_Shutdown(); /* Is a void return in older SDK */ +#else + if (MXC_TPU_Shutdown(MXC_SYS_PERIPH_CLOCK_TRNG) != 0) { + MAX3266X_MSG("Device did not shutdown"); + return RNG_FAILURE_E; + } +#endif + MAX3266X_MSG("TPU Hardware Shutdown"); + return 0; +} + + +#ifdef WOLF_CRYPTO_CB +int wc_MxcAesCryptoCb(wc_CryptoInfo* info) +{ + switch (info->cipher.type) { +#ifdef HAVE_AES_CBC + case WC_CIPHER_AES_CBC: + if (info->cipher.enc == 1) { + return wc_MxcCb_AesCbcEncrypt(info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + } + #ifdef HAVE_AES_DECRYPT + else if (info->cipher.enc == 0) { + return wc_MxcCb_AesCbcDecrypt(info->cipher.aescbc.aes, + info->cipher.aescbc.out, + info->cipher.aescbc.in, + info->cipher.aescbc.sz); + } + #endif + break; /* Break out and return error */ +#endif +#ifdef HAVE_AES_ECB + case WC_CIPHER_AES_ECB: + if (info->cipher.enc == 1) { + return wc_MxcCb_AesEcbEncrypt(info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + } + #ifdef HAVE_AES_DECRYPT + else if (info->cipher.enc == 0) { + return wc_MxcCb_AesEcbDecrypt(info->cipher.aesecb.aes, + info->cipher.aesecb.out, + info->cipher.aesecb.in, + info->cipher.aesecb.sz); + } + #endif + break; /* Break out and return error */ +#endif + default: + /* Is not ECB/CBC/GCM */ + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } + /* Just in case code breaks of switch statement return error */ + return BAD_FUNC_ARG; +} + +#ifdef MAX3266X_SHA_CB + +int wc_MxcShaCryptoCb(wc_CryptoInfo* info) +{ + switch (info->hash.type) { + #ifndef NO_SHA + case WC_HASH_TYPE_SHA: + MAX3266X_MSG("SHA-1 CB:"); + /* Update Case */ + if (info->hash.in != NULL && info->hash.digest == NULL) { + MAX3266X_MSG("Update CB"); + return wc_MXC_TPU_SHA_Update(&(info->hash.sha1->mxcCtx), + info->hash.in, info->hash.inSz); + } + /* Sha 1 Final Case */ + if (info->hash.in == NULL && info->hash.digest != NULL) { + MAX3266X_MSG("Final CB"); + return wc_MXC_TPU_SHA_Final(&(info->hash.sha1->mxcCtx), + info->hash.digest, + MXC_TPU_HASH_SHA1); + } + break; /* Break Out and Return Error */ + #endif + #ifdef WOLFSSL_SHA224 + case WC_HASH_TYPE_SHA224: + MAX3266X_MSG("SHA-224 CB:"); + /* Update Case */ + if (info->hash.in != NULL && info->hash.digest == NULL) { + MAX3266X_MSG("Update CB"); + return wc_MXC_TPU_SHA_Update(&(info->hash.sha224->mxcCtx), + info->hash.in, info->hash.inSz); + } + /* Sha 256 Final Case */ + if (info->hash.in == NULL && info->hash.digest != NULL) { + MAX3266X_MSG("Final CB"); + return wc_MXC_TPU_SHA_Final(&(info->hash.sha224->mxcCtx), + info->hash.digest, + MXC_TPU_HASH_SHA224); + } + break; /* Break Out and Return Error */ + #endif + #ifndef NO_SHA256 + case WC_HASH_TYPE_SHA256: + MAX3266X_MSG("SHA-256 CB:"); + /* Update Case */ + if (info->hash.in != NULL && info->hash.digest == NULL) { + MAX3266X_MSG("Update CB"); + return wc_MXC_TPU_SHA_Update(&(info->hash.sha256->mxcCtx), + info->hash.in, info->hash.inSz); + } + /* Sha 256 Final Case */ + if (info->hash.in == NULL && info->hash.digest != NULL) { + MAX3266X_MSG("Final CB"); + return wc_MXC_TPU_SHA_Final(&(info->hash.sha256->mxcCtx), + info->hash.digest, + MXC_TPU_HASH_SHA256); + } + break; /* Break Out and Return Error */ + #endif + #ifdef WOLFSSL_SHA384 + case WC_HASH_TYPE_SHA384: + MAX3266X_MSG("SHA-384 CB:"); + /* Update Case */ + if (info->hash.in != NULL && info->hash.digest == NULL) { + MAX3266X_MSG("Update CB"); + return wc_MXC_TPU_SHA_Update(&(info->hash.sha384->mxcCtx), + info->hash.in, info->hash.inSz); + } + /* Sha 384 Final Case */ + if (info->hash.in == NULL && info->hash.digest != NULL) { + MAX3266X_MSG("Final CB"); + return wc_MXC_TPU_SHA_Final(&(info->hash.sha384->mxcCtx), + info->hash.digest, + MXC_TPU_HASH_SHA384); + } + break; /* Break Out and Return Error */ + #endif + #ifdef WOLFSSL_SHA512 + case WC_HASH_TYPE_SHA512: + MAX3266X_MSG("SHA-512 CB:"); + /* Update Case */ + if (info->hash.in != NULL && info->hash.digest == NULL) { + MAX3266X_MSG("Update CB"); + return wc_MXC_TPU_SHA_Update(&(info->hash.sha512->mxcCtx), + info->hash.in, info->hash.inSz); + } + /* Sha 512 Final Case */ + if (info->hash.in == NULL && info->hash.digest != NULL) { + MAX3266X_MSG("Final CB"); + return wc_MXC_TPU_SHA_Final(&(info->hash.sha512->mxcCtx), + info->hash.digest, + MXC_TPU_HASH_SHA512); + } + break; /* Break Out and Return Error */ + #endif + default: + /* Hash type not supported */ + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } + if (info->hash.inSz == 0) { + return 0; /* Dont need to Update when Size is Zero */ + } + return BAD_FUNC_ARG; +} +#endif /* MAX3266X_SHA_CB */ + +/* Determines AES Type for Callback */ +/* General Callback Function to determine ALGO Type */ +int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + int ret; + (void)ctx; + + if (info == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef DEBUG_CRYPTOCB + wc_CryptoCb_InfoString(info); +#endif + + switch (info->algo_type) { + case WC_ALGO_TYPE_CIPHER: + MAX3266X_MSG("Using MXC AES HW Callback:"); + ret = wc_MxcAesCryptoCb(info); /* Determine AES HW or SW */ + break; +#ifdef MAX3266X_SHA_CB + case WC_ALGO_TYPE_HASH: + MAX3266X_MSG("Using MXC SHA HW Callback:"); + ret = wc_MxcShaCryptoCb(info); /* Determine SHA HW or SW */ + break; +#endif /* MAX3266X_SHA_CB */ + default: + MAX3266X_MSG("Callback not support with MXC, using SW"); + /* return this to bypass HW and use SW */ + ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } + + return ret; +} +#endif + +/* Convert Error Codes Correctly and Report HW error when */ +/* using #define MAX3266X_VERBOSE */ +int wc_MXC_error(int *ret) +{ + if (ret == NULL) { + /* In case somehow pointer to the return code is NULL */ + return BAD_FUNC_ARG; + } + switch (*ret) { + case E_SUCCESS: + return 0; + + case E_INVALID: /* Process Failed */ + MAX3266X_MSG("HW Reported: E_INVALID Error"); + *ret = WC_HW_E; + break; + + case E_NULL_PTR: + MAX3266X_MSG("HW Reported: E_NULL_PTR Error"); + *ret = BAD_FUNC_ARG; + break; + + case E_BAD_PARAM: + MAX3266X_MSG("HW Reported: E_BAD_PARAM Error"); + *ret = BAD_FUNC_ARG; + break; + + case E_BAD_STATE: + MAX3266X_MSG("HW Reported: E_BAD_STATE Error"); + *ret = WC_HW_E; + break; + + default: + MAX3266X_MSG("HW Reported an Unknown Error"); + *ret = WC_HW_E; /* If something else return HW Error */ + break; + } + return *ret; +} + + +#if defined(MAX3266X_RNG) +/* Simple call to SDK's TRNG HW */ +int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) +{ + int status; + if (output == NULL) { + return BAD_FUNC_ARG; + } + status = wolfSSL_HwRngMutexLock(); /* Lock Mutex needed since */ + /* calling TPU init */ + if (status != 0) { + return status; + } + status = MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TRNG); + if (status == 0) { + /* void return function */ + MXC_TPU_TRNG_Read(MXC_TRNG, output, sz); + MAX3266X_MSG("TRNG Hardware Used"); + } + else { + MAX3266X_MSG("TRNG Device did not initialize"); + status = RNG_FAILURE_E; + } + wolfSSL_HwRngMutexUnLock(); /* Unlock Mutex no matter status value */ + return status; +} +#endif /* MAX3266X_RNG */ + +#if defined(MAX3266X_AES) +/* Generic call to the SDK's AES 1 shot Encrypt based on inputs given */ +int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, + const unsigned char* enc_key, + MXC_TPU_MODE_TYPE mode, unsigned int data_size, + unsigned char* out, unsigned int keySize) +{ + int status; + if (in == NULL || iv == NULL || enc_key == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + status = wolfSSL_HwAesMutexLock(); + MAX3266X_MSG("AES HW Encryption"); + if (status != 0) { + MAX3266X_MSG("Hardware Mutex Failure"); + return status; + } + switch (keySize) { + case MXC_AES_KEY_128_LEN: + MXC_TPU_Cipher_Config(mode, MXC_TPU_CIPHER_AES128); + status = MXC_TPU_Cipher_AES_Encrypt((const char*)in, + (const char*)iv, (const char*)enc_key, + MXC_TPU_CIPHER_AES128, mode, data_size, (char*)out); + MAX3266X_MSG("AES HW Acceleration Used: 128 Bit"); + break; + case MXC_AES_KEY_192_LEN: + MXC_TPU_Cipher_Config(mode, MXC_TPU_CIPHER_AES192); + status = MXC_TPU_Cipher_AES_Encrypt((const char*)in, + (const char*)iv, (const char*)enc_key, + MXC_TPU_CIPHER_AES192, mode, data_size, (char*)out); + MAX3266X_MSG("AES HW Acceleration Used: 192 Bit"); + break; + case MXC_AES_KEY_256_LEN: + MXC_TPU_Cipher_Config(mode, MXC_TPU_CIPHER_AES256); + status = MXC_TPU_Cipher_AES_Encrypt((const char*)in, + (const char*)iv, (const char*)enc_key, + MXC_TPU_CIPHER_AES256, mode, data_size, (char*)out); + MAX3266X_MSG("AES HW Acceleration Used: 256 Bit"); + break; + default: + MAX3266X_MSG("AES HW ERROR: Length Not Supported"); + wolfSSL_HwAesMutexUnLock(); + return BAD_FUNC_ARG; + } + wolfSSL_HwAesMutexUnLock(); + if (status != 0) { + MAX3266X_MSG("AES HW Acceleration Error Occurred"); + return WC_HW_E; + } + return status; +} + + +/* Encrypt AES Crypto Callbacks*/ +#if defined(WOLF_CRYPTO_CB) + +#ifdef HAVE_AES_ECB +int wc_MxcCb_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + int status; + word32 keySize; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->devKey, + MXC_TPU_MODE_ECB, sz, out, keySize); + + return status; +} +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AES_CBC +int wc_MxcCb_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + word32 keySize; + int status; + byte *iv; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + /* Always enforce a length check */ + if (sz % AES_BLOCK_SIZE) { + #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + return BAD_LENGTH_E; + #else + return BAD_FUNC_ARG; + #endif + } + if (sz == 0) { + return 0; + } + + iv = (byte*)aes->reg; + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->devKey, + MXC_TPU_MODE_CBC, sz, out, + (unsigned int)keySize); + /* store iv for next call */ + if (status == 0) { + XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + return (status == 0) ? 0 : -1; +} +#endif /* HAVE_AES_CBC */ +#endif /* WOLF_CRYPTO_CB */ + +#ifdef HAVE_AES_DECRYPT +/* Generic call to the SDK's AES 1 shot decrypt based on inputs given */ +int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, + const unsigned char* dec_key, + MXC_TPU_MODE_TYPE mode, unsigned int data_size, + unsigned char* out, unsigned int keySize) +{ + int status; + if (in == NULL || iv == NULL || dec_key == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + status = wolfSSL_HwAesMutexLock(); + if (status != 0) { + return status; + } + switch (keySize) { + case MXC_AES_KEY_128_LEN: + MXC_TPU_Cipher_Config(mode, MXC_TPU_CIPHER_AES128); + status = MXC_TPU_Cipher_AES_Decrypt((const char*)in, + (const char*)iv, (const char*)dec_key, + MXC_TPU_CIPHER_AES128, mode, data_size, (char*)out); + MAX3266X_MSG("AES HW Acceleration Used: 128 Bit"); + break; + case MXC_AES_KEY_192_LEN: + MXC_TPU_Cipher_Config(mode, MXC_TPU_CIPHER_AES192); + status = MXC_TPU_Cipher_AES_Decrypt((const char*)in, + (const char*)iv, (const char*)dec_key, + MXC_TPU_CIPHER_AES192, mode, data_size, (char*)out); + MAX3266X_MSG("AES HW Acceleration Used: 192 Bit"); + break; + case MXC_AES_KEY_256_LEN: + MXC_TPU_Cipher_Config(mode, MXC_TPU_CIPHER_AES256); + status = MXC_TPU_Cipher_AES_Decrypt((const char*)in, + (const char*)iv, (const char*)dec_key, + MXC_TPU_CIPHER_AES256, mode, data_size, (char*)out); + MAX3266X_MSG("AES HW Acceleration Used: 256 Bit"); + break; + default: + MAX3266X_MSG("AES HW ERROR: Length Not Supported"); + wolfSSL_HwAesMutexUnLock(); + return BAD_FUNC_ARG; + } + wolfSSL_HwAesMutexUnLock(); + if (status != 0) { + MAX3266X_MSG("AES HW Acceleration Error Occurred"); + return WC_HW_E; + } + return status; +} + +/* Decrypt Aes Crypto Callbacks*/ +#if defined(WOLF_CRYPTO_CB) + +#ifdef HAVE_AES_ECB +int wc_MxcCb_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + int status; + word32 keySize; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->devKey, + MXC_TPU_MODE_ECB, sz, out, keySize); + + return status; +} +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AES_CBC +int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + word32 keySize; + int status; + byte *iv; + byte temp_block[AES_BLOCK_SIZE]; + + if ((in == NULL) || (out == NULL) || (aes == NULL)) { + return BAD_FUNC_ARG; + } + + /* Always enforce a length check */ + if (sz % AES_BLOCK_SIZE) { + #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + return BAD_LENGTH_E; + #else + return BAD_FUNC_ARG; + #endif + } + if (sz == 0) { + return 0; + } + + iv = (byte*)aes->reg; + status = wc_AesGetKeySize(aes, &keySize); + if (status != 0) { + return status; + } + + /* get IV for next call */ + XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->devKey, + MXC_TPU_MODE_CBC, sz, out, + keySize); + + /* store iv for next call */ + if (status == 0) { + XMEMCPY(iv, temp_block, AES_BLOCK_SIZE); + } + return (status == 0) ? 0 : -1; +} +#endif /* HAVE_AES_CBC */ +#endif /* WOLF_CRYPTO_CB */ +#endif /* HAVE_AES_DECRYPT */ +#endif /* MAX3266X_AES */ + +#if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) + +int wc_MXC_TPU_SHA_Init(wc_MXC_Sha *hash) +{ + if (hash == NULL) { + return BAD_FUNC_ARG; /* Appropriate error handling for null argument */ + } + hash->msg = NULL; + hash->used = 0; + hash->size = 0; + return 0; +} + +/* Used to update the msg. Currently the SDK only supports 1 shots, so the */ +/* hash->msg buffer needs to be updated and resized. hash->msg will keep the */ +/* unhashed msg and produce a digest when wc_MXC_TPU_SHA_Final or */ +/* wc_MXC_TPU_SHA_GetHash is called */ +int wc_MXC_TPU_SHA_Update(wc_MXC_Sha *hash, const unsigned char* data, + unsigned int size) +{ + void *p; + /* Only update if size is not 0 */ + if (size == 0) { + return 0; + } + /* Check for NULL pointers After Size Check */ + if (hash == NULL || data == NULL) { + return BAD_FUNC_ARG; + } + if (hash->size < hash->used+size) { + if (hash->msg == NULL) { + p = XMALLOC(hash->used+size, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + #ifdef WOLFSSL_NO_REALLOC + p = XMALLOC(hash->used + size, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (p != NULL) { + XMEMCPY(p, hash->msg, hash->used); + XFREE(hash->msg, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + #else + p = XREALLOC(hash->msg, hash->used+size, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + #endif + } + if (p == NULL) { + return MEMORY_E; + } + hash->msg = p; + hash->size = hash->used+size; + } + XMEMCPY(hash->msg+hash->used, data, size); + hash->used += size; + if (hash->msg == NULL) { + return BAD_FUNC_ARG; + } + return 0; +} + +int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, + MXC_TPU_HASH_TYPE algo) +{ + int status; + if (hash == NULL || digest == NULL) { + return BAD_FUNC_ARG; + } + status = wc_MXC_TPU_SHA_GetDigest(hash, digest, algo); + /* True Case that msg is an empty string */ + if (status == 1) { + /* Hardware cannot handle the case of an empty string */ + /* so in the case of this we will provide the hash via software */ + return 0; + } + /* False Case where msg needs to be processed */ + else if (status == 0) { + status = wolfSSL_HwHashMutexLock(); /* Set Mutex */ + if (status != 0) { /* Mutex Call Check */ + return status; + } + MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TPU); + MXC_TPU_Hash_Config(algo); + status = MXC_TPU_Hash_SHA((const char *)hash->msg, algo, hash->size, + (char *)digest); + MAX3266X_MSG("SHA HW Acceleration Used"); + wolfSSL_HwHashMutexUnLock(); /* Release Mutex */ + if (wc_MXC_error(&status) != 0) { + MAX3266X_MSG("SHA HW Error Occurred"); + return status; + } + } + /* Error Occurred */ + return status; +} + +/* Calls GetHash to determine the digest and then reinitialize the hash */ +/* struct */ +int wc_MXC_TPU_SHA_Final(wc_MXC_Sha *hash, unsigned char* digest, + MXC_TPU_HASH_TYPE algo) +{ + int status; + if (hash == NULL || digest == NULL) { + return BAD_FUNC_ARG; + } + status = wc_MXC_TPU_SHA_GetHash(hash, digest, algo); + /* Free hash->msg no matter result */ + XFREE(hash->msg, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (status != 0) { + return status; + } + status = wc_MXC_TPU_SHA_Init(hash); + if (status != 0) { + return status; + } + return status; +} + +/* Copies Struct values from SRC struct to DST struct */ +int wc_MXC_TPU_SHA_Copy(wc_MXC_Sha* src, wc_MXC_Sha* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + dst->used = src->used; + dst->size = src->size; + if (dst->msg == src->msg && src->msg != 0) { + /* Allocate new memory for dst->msg if it points to the same location */ + /* as src->msg */ + dst->msg = (unsigned char*)XMALLOC(src->size, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) { + return MEMORY_E; /* Handle memory allocation failure */ + } + } + XMEMCPY(dst->msg, src->msg, src->size); + return 0; +} + +/* Free the given struct's msg buffer and then reinitialize the struct to 0 */ +/* returns void to match other wc_Sha*Free api */ +void wc_MXC_TPU_SHA_Free(wc_MXC_Sha* hash) +{ + if (hash == NULL) { + return; /* Hash Struct is Null already, dont edit potentially */ + /* undefined memory */ + } + XFREE(hash->msg, NULL, DYNAMIC_TYPE_TMP_BUFFER); + wc_MXC_TPU_SHA_Init(hash); /* sets hash->msg to null + zero's attributes */ + return; +} + +/* Acts as a True/False if true it will provide the stored digest */ +/* for the edge case of an empty string */ +int wc_MXC_TPU_SHA_GetDigest(wc_MXC_Sha *hash, unsigned char* digest, + MXC_TPU_HASH_TYPE algo) +{ + if (hash == NULL || digest == NULL) { + return BAD_FUNC_ARG; + } + if (hash->msg == 0 && hash->size == 0) { + switch (algo) { + #ifndef NO_SHA + case MXC_TPU_HASH_SHA1: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA1, WC_SHA_DIGEST_SIZE); + break; + #endif /* NO_SHA */ + #ifdef WOLFSSL_SHA224 + case MXC_TPU_HASH_SHA224: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA224, WC_SHA224_DIGEST_SIZE); + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case MXC_TPU_HASH_SHA256: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA256, WC_SHA256_DIGEST_SIZE); + break; + #endif /* NO_SHA256 */ + #ifdef WOLFSSL_SHA384 + case MXC_TPU_HASH_SHA384: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA384, WC_SHA384_DIGEST_SIZE); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case MXC_TPU_HASH_SHA512: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA512, WC_SHA512_DIGEST_SIZE); + break; + #endif /* WOLFSSL_SHA512 */ + default: + return BAD_FUNC_ARG; + } + return 1; /* True */ + } + return 0; /* False */ +} + +#ifndef MAX3266X_SHA_CB +#if !defined(NO_SHA) + +WOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + (void)heap; + (void)devId; + return wc_MXC_TPU_SHA_Init((wc_MXC_Sha *)sha); +} + +WOLFSSL_API int wc_ShaUpdate(wc_Sha* sha, const unsigned char* data, + unsigned int len) +{ + return wc_MXC_TPU_SHA_Update(sha, data, len); +} + +WOLFSSL_API int wc_ShaFinal(wc_Sha* sha, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_Final((wc_MXC_Sha *)sha, hash, + MXC_TPU_HASH_SHA1); +} + +WOLFSSL_API int wc_ShaGetHash(wc_Sha* sha, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_GetHash((wc_MXC_Sha *)sha, hash, + MXC_TPU_HASH_SHA1); +} + +WOLFSSL_API int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) +{ + return wc_MXC_TPU_SHA_Copy((wc_MXC_Sha *)src, (wc_MXC_Sha *)dst); +} + +WOLFSSL_API void wc_ShaFree(wc_Sha* sha) +{ + wc_MXC_TPU_SHA_Free((wc_MXC_Sha *)sha); + return; +} + +#endif /* NO_SHA */ + +#if defined(WOLFSSL_SHA224) + +WOLFSSL_API int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId) +{ + if (sha224 == NULL) { + return BAD_FUNC_ARG; + } + (void)heap; + (void)devId; + return wc_MXC_TPU_SHA_Init((wc_MXC_Sha *)sha224); +} + +WOLFSSL_API int wc_InitSha224(wc_Sha224* sha224) +{ + return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha224Update(wc_Sha224* sha224, const unsigned char* data, + unsigned int len) +{ + return wc_MXC_TPU_SHA_Update(sha224, data, len); +} + +WOLFSSL_API int wc_Sha224Final(wc_Sha224* sha224, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_Final((wc_MXC_Sha *)sha224, hash, + MXC_TPU_HASH_SHA224); +} + +WOLFSSL_API int wc_Sha224GetHash(wc_Sha224* sha224, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_GetHash((wc_MXC_Sha *)sha224, hash, + MXC_TPU_HASH_SHA224); +} + +WOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst) +{ + return wc_MXC_TPU_SHA_Copy((wc_MXC_Sha *)src, (wc_MXC_Sha *)dst); +} + +WOLFSSL_API void wc_Sha224Free(wc_Sha224* sha224) +{ + wc_MXC_TPU_SHA_Free((wc_MXC_Sha *)sha224); + return; +} + +#endif /* WOLFSSL_SHA224 */ + +#if !defined(NO_SHA256) + +WOLFSSL_API int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) +{ + if (sha256 == NULL) { + return BAD_FUNC_ARG; + } + (void)heap; + (void)devId; + return wc_MXC_TPU_SHA_Init((wc_MXC_Sha *)sha256); +} + +WOLFSSL_API int wc_InitSha256(wc_Sha256* sha256) +{ + return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha256Update(wc_Sha256* sha256, const unsigned char* data, + unsigned int len) +{ + return wc_MXC_TPU_SHA_Update(sha256, data, len); +} + +WOLFSSL_API int wc_Sha256Final(wc_Sha256* sha256, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_Final((wc_MXC_Sha *)sha256, hash, + MXC_TPU_HASH_SHA256); +} + +WOLFSSL_API int wc_Sha256GetHash(wc_Sha256* sha256, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_GetHash((wc_MXC_Sha *)sha256, hash, + MXC_TPU_HASH_SHA256); +} + +WOLFSSL_API int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) +{ + return wc_MXC_TPU_SHA_Copy((wc_MXC_Sha *)src, (wc_MXC_Sha *)dst); +} + +WOLFSSL_API void wc_Sha256Free(wc_Sha256* sha256) +{ + wc_MXC_TPU_SHA_Free((wc_MXC_Sha *)sha256); + return; +} + +#endif /* NO_SHA256 */ + +#if defined(WOLFSSL_SHA384) + +WOLFSSL_API int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) +{ + if (sha384 == NULL) { + return BAD_FUNC_ARG; + } + (void)heap; + (void)devId; + return wc_MXC_TPU_SHA_Init((wc_MXC_Sha *)sha384); +} + +WOLFSSL_API int wc_InitSha384(wc_Sha384* sha384) +{ + return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha384Update(wc_Sha384* sha384, const unsigned char* data, + unsigned int len) +{ + return wc_MXC_TPU_SHA_Update(sha384, data, len); +} + +WOLFSSL_API int wc_Sha384Final(wc_Sha384* sha384, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_Final((wc_MXC_Sha *)sha384, hash, + MXC_TPU_HASH_SHA384); +} + +WOLFSSL_API int wc_Sha384GetHash(wc_Sha384* sha384, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_GetHash((wc_MXC_Sha *)sha384, hash, + MXC_TPU_HASH_SHA384); +} + +WOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) +{ + return wc_MXC_TPU_SHA_Copy((wc_MXC_Sha *)src, (wc_MXC_Sha *)dst); +} + +WOLFSSL_API void wc_Sha384Free(wc_Sha384* sha384) +{ + wc_MXC_TPU_SHA_Free((wc_MXC_Sha *)sha384); + return; +} + +#endif /* WOLFSSL_SHA384 */ + +#if defined(WOLFSSL_SHA512) + +WOLFSSL_API int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) +{ + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + (void)heap; + (void)devId; + return wc_MXC_TPU_SHA_Init((wc_MXC_Sha *)sha512); +} + +WOLFSSL_API int wc_InitSha512(wc_Sha512* sha512) +{ + return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha512Update(wc_Sha512* sha512, const unsigned char* data, + unsigned int len) +{ + return wc_MXC_TPU_SHA_Update(sha512, data, len); +} + +WOLFSSL_API int wc_Sha512Final(wc_Sha512* sha512, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_Final((wc_MXC_Sha *)sha512, hash, + MXC_TPU_HASH_SHA512); +} + +WOLFSSL_API int wc_Sha512GetHash(wc_Sha512* sha512, unsigned char* hash) +{ + return wc_MXC_TPU_SHA_GetHash((wc_MXC_Sha *)sha512, hash, + MXC_TPU_HASH_SHA512); +} + +WOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) +{ + return wc_MXC_TPU_SHA_Copy((wc_MXC_Sha *)src, (wc_MXC_Sha *)dst); +} + +WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha512) +{ + wc_MXC_TPU_SHA_Free((wc_MXC_Sha *)sha512); + return; +} + +#endif /* WOLFSSL_SHA512 */ +#endif /* !MAX3266X_SHA_CB*/ +#endif /* MAX3266X_SHA || MAX3266X_SHA_CB */ + +#if defined(MAX3266X_MATH) + +/* Sets mutex and initializes hardware according to needed operation size */ +int wc_MXC_MAA_init(unsigned int len) +{ + int status; + MAX3266X_MSG("Setting Hardware Mutex and Starting MAA"); + status = wolfSSL_HwPkMutexLock(); + if (status == 0) { + status = MXC_TPU_MAA_Init(len); + } + return wc_MXC_error(&status); /* Return Status of Init */ +} + +/* Unlocks mutex and preforms graceful shutdown of hardware */ +int wc_MXC_MAA_Shutdown(void) +{ + int status; + MAX3266X_MSG("Unlocking Hardware Mutex and Shutting Down MAA"); + status = MXC_TPU_MAA_Shutdown(); + if (status == E_BAD_PARAM) { /* Miss leading, Send WC_HW_ERROR */ + /* This is returned when MAA cannot stop */ + status = WC_HW_E; + } + wolfSSL_HwPkMutexUnLock(); /* Always call Unlock in shutdown */ + return wc_MXC_error(&status); +} + +/* Update used number for mp_int struct for results */ +int wc_MXC_MAA_adjustUsed(unsigned int *array, unsigned int length) +{ + int i, lastNonZeroIndex; + lastNonZeroIndex = -1; /* Track the last non-zero index */ + for (i = 0; i < length; i++) { + if (array[i] != 0) { + lastNonZeroIndex = i; + } + } + return (lastNonZeroIndex + 1); +} + +/* Determines the size of operation that needs to happen */ +unsigned int wc_MXC_MAA_Largest(unsigned int count, ...) +{ + va_list args; + int i; + unsigned int largest, num; + va_start(args, count); + largest = va_arg(args, unsigned int); + for (i = 1; i < count; i++) { + num = va_arg(args, unsigned int); + if (num > largest) { + largest = num; + } + } + va_end(args); + return largest; +} + +/* Determines if we need to fallback to Software */ +int wc_MXC_MAA_Fallback(unsigned int count, ...) +{ + va_list args; + int num, i; + va_start(args, count); + for (i = 0; i < count; i++) { + num = va_arg(args, unsigned int); + if (num > MXC_MAA_MAX_SIZE) { + MAX3266X_MSG("HW Falling Back to Software"); + return 1; + } + } + va_end(args); + MAX3266X_MSG("HW Can Handle Input"); + return 0; +} + +/* Have to zero pad the entire data array up to 256 bytes(2048 bits) */ +/* If length > 256 bytes then error */ +int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, + mp_int* exp, mp_int* mod, mp_int* result, + MXC_TPU_MAA_TYPE clc, unsigned int length) +{ + mp_digit* zero_tmp; + MAX3266X_MSG("Zero Padding Buffers for Hardware"); + if (length > MXC_MAA_MAX_SIZE) { + MAX3266X_MSG("Hardware cannot exceed 2048 bit input"); + return BAD_FUNC_ARG; + } + if ((result == NULL) || (multiplier == NULL) || (multiplicand == NULL) || + ((exp == NULL) && (clc == MXC_TPU_MAA_EXP)) || (mod == NULL)) { + return BAD_FUNC_ARG; + } + + /* Create an array to compare values to to check edge for error edge case */ + zero_tmp = (mp_digit*)XMALLOC(multiplier->size*sizeof(mp_digit), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (zero_tmp == NULL) { + MAX3266X_MSG("NULL pointer found after XMALLOC call"); + return MEMORY_E; + } + XMEMSET(zero_tmp, 0x00, multiplier->size*sizeof(mp_digit)); + + /* Check for invalid arguments befor padding */ + switch ((char)clc) { + case MXC_TPU_MAA_EXP: + /* Cannot be 0 for a^e mod m operation */ + if (XMEMCMP(zero_tmp, exp, (exp->used*sizeof(mp_digit))) == 0) { + XFREE(zero_tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + MAX3266X_MSG("Cannot use Value 0 for Exp"); + return BAD_FUNC_ARG; + } + + /* Pad out rest of data if used != length to ensure no */ + /* garbage is used in calculation */ + if ((exp != NULL) && (clc == MXC_TPU_MAA_EXP)) { + if ((exp->dp != NULL) && (exp->used < length)) { + MAX3266X_MSG("Zero Padding Exp Buffer"); + XMEMSET(exp->dp + exp->used, 0x00, + sizeof(int) *(length - exp->used)); + } + } + + /* Fall through to check mod is not 0 */ + case MXC_TPU_MAA_SQ: + case MXC_TPU_MAA_MUL: + case MXC_TPU_MAA_SQMUL: + case MXC_TPU_MAA_ADD: + case MXC_TPU_MAA_SUB: + /* Cannot be 0 for mod m value */ + if (XMEMCMP(zero_tmp, mod, (exp->used*sizeof(mp_digit))) == 0) { + XFREE(zero_tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + MAX3266X_MSG("Cannot use Value 0 for Exp"); + return BAD_FUNC_ARG; + } + + /* Pad out rest of data if used != length to ensure no */ + /* garbage is used in calculation */ + if ((multiplier->dp != NULL) && (multiplier->used < length)) { + MAX3266X_MSG("Zero Padding Multiplier Buffer"); + XMEMSET(multiplier->dp + multiplier->used, 0x00, + sizeof(int) * (length - multiplier->used)); + } + if ((multiplicand->dp != NULL) && (multiplicand->used < length)) { + MAX3266X_MSG("Zero Padding Multiplicand Buffer"); + XMEMSET(multiplicand->dp + multiplicand->used, 0x00, + sizeof(int) * (length - multiplicand->used)); + } + if ((mod->dp != NULL) && (mod->used < length)) { + MAX3266X_MSG("Zero Padding Mod Buffer"); + XMEMSET(mod->dp + mod->used, 0x00, + sizeof(int) *(length - mod->used)); + } + break; + default: + /* Free the zero array used to check values */ + XFREE(zero_tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return BAD_FUNC_ARG; /* Invalid clc given */ + } + /* Free the zero array used to check values */ + XFREE(zero_tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + /* Make sure result is 0 padded */ + if (result->dp != NULL) { + ForceZero(result->dp, sizeof(int)*(length)); + result->used = length; + } + else if (result == NULL) { + return BAD_FUNC_ARG; /* Cannot be null */ + } + return 0; +} + + + +/* General Control Over MAA Hardware to handle all needed Cases */ +int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, + mp_int* mod, mp_int* result, + MXC_TPU_MAA_TYPE clc) +{ + int ret; + int length; + mp_int* result_tmp_ptr; + mp_int result_tmp; + if (multiplier == NULL || multiplicand == NULL || mod == NULL || + (exp == NULL && clc == MXC_TPU_MAA_EXP) || result == NULL) { + return BAD_FUNC_ARG; + } + + /* Check if result shares struct pointer */ + if ((multiplier == result) || (multiplicand == result) || (exp == result) || + (mod == result)) { + MAX3266X_MSG("Creating Temp Result Buffer for Hardware"); + result_tmp_ptr = &result_tmp; /* Assign point to temp struct */ + } + else { + result_tmp_ptr = result; /* No Shared Point to directly assign */ + } + if (result_tmp_ptr == NULL) { + MAX3266X_MSG("tmp ptr is null"); + return MP_VAL; + } + + if (clc == MXC_TPU_MAA_EXP) { + length = wc_MXC_MAA_Largest(5, multiplier->used, multiplicand->used, + exp->used, mod->used, result->used); + } + else { + length = wc_MXC_MAA_Largest(4, multiplier->used, multiplicand->used, + mod->used, result->used); + } + + /* Zero Pad everything if needed */ + ret = wc_MXC_MAA_zeroPad(multiplier, multiplicand, exp, mod, result_tmp_ptr, + clc, length); + if (ret != 0) { + MAX3266X_MSG("Zero Padding Failed"); + return ret; + } + + /* Init MAA HW */ + ret = wc_MXC_MAA_init(length*sizeof(mp_digit)*8); + if (ret != 0) { + MAX3266X_MSG("HW Init Failed"); + wolfSSL_HwPkMutexUnLock(); + return ret; + } + + /* Start Math And Cast to expect types for SDK */ + MAX3266X_MSG("Starting Computation in MAA"); + ret = MXC_TPU_MAA_Compute(clc, (char *)(multiplier->dp), + (char *)(multiplicand->dp), + (char *)(exp->dp), (char *)(mod->dp), + (int *)(result_tmp_ptr->dp), + (length*sizeof(mp_digit))); + MAX3266X_MSG("MAA Finished Computation"); + if (wc_MXC_error(&ret) != 0) { + MAX3266X_MSG("HW Computation Error"); + wolfSSL_HwPkMutexUnLock(); + return ret; + } + + ret = wc_MXC_MAA_Shutdown(); + if (ret != 0) { + MAX3266X_MSG("HW Shutdown Failure"); + /* Shutdown will always call wolfSSL_HwPkMutexUnLock(); */ + /* before returning */ + return ret; + } + + /* Copy tmp result if needed */ + if ((multiplier == result) || (multiplicand == result) || (exp == result) || + (mod == result)) { + mp_copy(result_tmp_ptr, result); + ForceZero(result_tmp_ptr, sizeof(result_tmp_ptr)); /* force zero */ + } + + result->used = wc_MXC_MAA_adjustUsed(result->dp, length); + return ret; +} + + + +int wc_MXC_MAA_expmod(mp_int* base, mp_int* exp, mp_int* mod, + mp_int* result) +{ + mp_int multiplicand; + if (base == NULL || exp == NULL || mod == NULL || result == NULL) { + return BAD_FUNC_ARG; + } + XMEMSET(&multiplicand, 0, sizeof(mp_int)); + multiplicand.dp[0] = 0x01; + multiplicand.used = mod->used; + MAX3266X_MSG("Preparing exptmod MAA HW Call"); + return wc_MXC_MAA_math(base, &multiplicand, exp, mod, result, + MXC_TPU_MAA_EXP); +} + +int wc_MXC_MAA_sqrmod(mp_int* multiplier, mp_int* mod, mp_int* result) +{ + mp_int multiplicand; + if (multiplier == NULL || mod == NULL || result == NULL) { + return BAD_FUNC_ARG; + } + XMEMSET(&multiplicand, 0, sizeof(mp_int)); + multiplicand.dp[0] = 0x01; + multiplicand.used = mod->used; + MAX3266X_MSG("Preparing sqrmod MAA HW Call"); + return wc_MXC_MAA_math(multiplier, &multiplicand, NULL, mod, result, + MXC_TPU_MAA_SQ); +} + +int wc_MXC_MAA_mulmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, + mp_int* result) +{ + if (multiplier == NULL || multiplicand == NULL || mod == NULL || + result == NULL) { + return BAD_FUNC_ARG; + } + MAX3266X_MSG("Preparing mulmod MAA HW Call"); + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, + MXC_TPU_MAA_MUL); +} + +int wc_MXC_MAA_sqrmulmod(mp_int* multiplier, mp_int* multiplicand, + mp_int* exp, mp_int* mod, mp_int* result) +{ + if (multiplier == NULL || multiplicand == NULL || exp == NULL || + mod == NULL || result == NULL) { + return BAD_FUNC_ARG; + } + MAX3266X_MSG("Preparing sqrmulmod MAA HW Call"); + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, + MXC_TPU_MAA_SQMUL); +} + +int wc_MXC_MAA_addmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, + mp_int* result) +{ + if (multiplier == NULL || multiplicand == NULL || mod == NULL || + result == NULL) { + return BAD_FUNC_ARG; + } + MAX3266X_MSG("Preparing addmod MAA HW Call"); + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, + MXC_TPU_MAA_ADD); +} + +int wc_MXC_MAA_submod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, + mp_int* result) +{ + if (multiplier == NULL || multiplicand == NULL || mod == NULL || + result == NULL) { + return BAD_FUNC_ARG; + } + MAX3266X_MSG("Preparing submod MAA HW Call"); + if ((mod->used < multiplier->used) || (mod->used < multiplicand->used)) { + MAX3266X_MSG("HW Limitation: Defaulting back to software"); + return mxc_submod(multiplier, multiplicand, mod, result); + } + else { + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, + MXC_TPU_MAA_SUB); + } +} + +/* General Function to call hardware control */ +int hw_mulmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, + mp_int* result) +{ + if (multiplier == NULL || multiplicand == NULL || mod == NULL || + result == NULL) { + return MP_VAL; + } + if ((multiplier->used == 0) || (multiplicand->used == 0)) { + mp_zero(result); + return 0; + } + else { + if (wc_MXC_MAA_Fallback(3, multiplier->used, mod->used, + multiplicand->used) != 0) { + return mxc_mulmod(multiplier, multiplicand, mod, result); + } + else { + return wc_MXC_MAA_mulmod(multiplier, multiplicand, mod, result); + } + } +} + +int hw_addmod(mp_int* a, mp_int* b, mp_int* mod, mp_int* result) +{ + int err = MP_OKAY; + /* Validate parameters. */ + if ((a == NULL) || (b == NULL) || (mod == NULL) || (result == NULL)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + if (wc_MXC_MAA_Fallback(3, a->used, b->used, mod->used) != 0) { + err = mxc_addmod(a, b, mod, result); + } + else { + err = wc_MXC_MAA_addmod(a, b, mod, result); + } + } + return err; +} + + +int hw_submod(mp_int* a, mp_int* b, mp_int* mod, mp_int* result) +{ + int err = MP_OKAY; + /* Validate parameters. */ + if ((a == NULL) || (b == NULL) || (mod == NULL) || (result == NULL)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + if (wc_MXC_MAA_Fallback(3, a->used, b->used, mod->used) != 0) { + err = mxc_submod(a, b, mod, result); + } + else{ + err = wc_MXC_MAA_submod(a, b, mod, result); + } + } + return err; +} + +int hw_exptmod(mp_int* base, mp_int* exp, mp_int* mod, mp_int* result) +{ + int err = MP_OKAY; + /* Validate parameters. */ + if ((base == NULL) || (exp == NULL) || (mod == NULL) || (result == NULL)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + if ((mod->used < exp->used) || (mod->used < base->used)) { + err = mxc_exptmod(base, exp, mod, result); + } + else if (wc_MXC_MAA_Fallback(3, base->used, exp->used, mod->used) + != 0) { + return mxc_exptmod(base, exp, mod, result); + } + else{ + err = wc_MXC_MAA_expmod(base, exp, mod, result); + } + } + return err; +} + + +/* No mod function available with hardware, however preform a submod */ +/* (a - 0) mod m will essentially preform the same operation as a mod m */ +int hw_mod(mp_int* a, mp_int* mod, mp_int* result) +{ + mp_int b; + if (a == NULL || mod == NULL || result == NULL) { + return MP_VAL; + } + if (wc_MXC_MAA_Fallback(2, a->used, mod->used) != 0) { + return mxc_mod(a, mod, result); + } + XMEMSET(&b, 0, sizeof(mp_int)); + b.used = mod->used; /* assume mod is determining size */ + return hw_submod(a, &b, mod, result); +} + +int hw_sqrmod(mp_int* base, mp_int* mod, mp_int* result) +{ + if (base == NULL || mod == NULL || result == NULL) { + return MP_VAL; + } + if (base->used == 0) { + mp_zero(result); + return 0; + } + return wc_MXC_MAA_sqrmod(base, mod, result); +} + +#endif /* MAX3266X_MATH */ + +#if defined(MAX3266X_RTC) +/* Initialize the RTC */ +int wc_MXC_RTC_Init(void) +{ + /* RTC Init for benchmark */ + if (MXC_RTC_Init(0, 0) != E_NO_ERROR) { + return WC_HW_E; + } + /* Disable the Interrupt */ + if (MXC_RTC_DisableInt(MXC_RTC_INT_EN_LONG) == E_BUSY) { + return WC_HW_E; + } + /* Start Clock for RTC */ + if (MXC_RTC_SquareWaveStart(MXC_RTC_F_512HZ) == E_BUSY) { + return E_BUSY; + } + /* Begin RTC count */ + if (MXC_RTC_Start() != E_NO_ERROR) { + return WC_HW_E; + } + return 0; +} + +/* Reset the RTC */ +int wc_MXC_RTC_Reset(void) +{ + /* Stops Counts */ + if (MXC_RTC_Stop() != E_NO_ERROR) { + return WC_HW_E; + } + /* Restart RTC via Init */ + if (wc_MXC_RTC_Init() != E_NO_ERROR) { + return WC_HW_E; + } + return 0; +} + +/* Function to handle RTC read retries */ +void wc_MXC_RTC_GetRTCValue(int32_t (*rtcGetFunction)(uint32_t*), + uint32_t* outValue, int32_t* err) +{ + *err = rtcGetFunction(outValue); /* Initial attempt to get the value */ + while (*err != E_NO_ERROR) { + *err = rtcGetFunction(outValue); /* Retry if the error persists */ + } +} + +/* Function to provide the current time as a double */ +/* Returns seconds and millisecond */ +double wc_MXC_RTC_Time(void) +{ + int32_t err; + uint32_t rtc_seconds, rtc_subseconds; + + /* Retrieve sub-seconds from RTC */ + wc_MXC_RTC_GetRTCValue((int32_t (*)(uint32_t*))MXC_RTC_GetSubSeconds, + &rtc_subseconds, &err); + if (err != E_NO_ERROR) { + return (double)err; + } + /* Retrieve seconds from RTC */ + wc_MXC_RTC_GetRTCValue((int32_t (*)(uint32_t*))MXC_RTC_GetSeconds, + &rtc_seconds, &err); + if (err != E_NO_ERROR) { + return (double)err; + } + /* Per the device documentation, subsecond register holds up to 1 second */ + /* subsecond register is size 2^12, so divide by 4096 to get milliseconds */ + return ((double)rtc_seconds + ((double)rtc_subseconds / 4096)); +} + +#endif /* MAX3266X_RTC */ + +#endif /* WOLFSSL_MAX32665 || WOLFSSL_MAX32666 */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index f1022edea4..d6c32f6923 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -136,6 +136,8 @@ This library contains implementation for the random number generator. #elif defined(WOLFSSL_GETRANDOM) #include #include +#elif defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include "wolfssl/wolfcrypt/port/maxim/max3266x.h" #else /* include headers that may be needed to get good seed */ #include @@ -3834,6 +3836,38 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return maxq10xx_random(output, sz); } +#elif defined(MAX3266X_RNG) + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + #ifdef WOLFSSL_MAX3266X + int status; + #endif /* WOLFSSL_MAX3266X */ + static int initDone = 0; + (void)os; + if (initDone == 0) { + #ifdef WOLFSSL_MAX3266X + status = wolfSSL_HwRngMutexLock(); + if (status != 0) { + return status; + } + #endif /* WOLFSSL_MAX3266X */ + if(MXC_TRNG_HealthTest() != 0) { + #ifdef DEBUG_WOLFSSL + WOLFSSL_MSG("TRNG HW Health Test Failed"); + #endif /* DEBUG_WOLFSSL */ + #ifdef WOLFSSL_MAX3266X + wolfSSL_HwRngMutexUnLock(); + #endif /* WOLFSSL_MAX3266X */ + return WC_HW_E; + } + #ifdef WOLFSSL_MAX3266X + wolfSSL_HwRngMutexUnLock(); + #endif /* WOLFSSL_MAX3266X */ + initDone = 1; + } + return wc_MXC_TRNG_Random(output, sz); + } + #elif defined(WOLFSSL_GETRANDOM) /* getrandom() was added to the Linux kernel in version 3.17. diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 44db748225..78ce918e26 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -308,6 +308,10 @@ !defined(WOLFSSL_QNX_CAAM) /* wolfcrypt/src/port/caam/caam_sha.c */ +#elif defined(MAX3266X_SHA) + /* Already brought in by sha.h */ + /* #include */ + #elif defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) || \ defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) @@ -560,6 +564,13 @@ int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) sha->devCtx = NULL; #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Init(&(sha->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + #ifdef WOLFSSL_USE_ESP32_CRYPT_HASH_HW if (sha->ctx.mode != ESP32_SHA_INIT) { /* it may be interesting to see old values during debugging */ @@ -1035,6 +1046,8 @@ int wc_InitSha(wc_Sha* sha) #if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) +#ifndef MAX3266X_SHA + void wc_ShaFree(wc_Sha* sha) { if (sha == NULL) @@ -1051,6 +1064,9 @@ void wc_ShaFree(wc_Sha* sha) #ifdef WOLFSSL_PIC32MZ_HASH wc_ShaPic32Free(sha); #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha->mxcCtx)); +#endif #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) se050_hash_free(&sha->se050Ctx); #endif @@ -1066,6 +1082,7 @@ void wc_ShaFree(wc_Sha* sha) #endif } +#endif /* !MAX3266X_SHA */ #endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ #endif /* !WOLFSSL_TI_HASH */ @@ -1080,6 +1097,8 @@ void wc_ShaFree(wc_Sha* sha) #if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) +#ifndef MAX3266X_SHA + /* wc_ShaGetHash get hash value */ int wc_ShaGetHash(wc_Sha* sha, byte* hash) { @@ -1144,12 +1163,20 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) esp_sha_ctx_copy(src, dst); #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif return ret; } #endif /* WOLFSSL_RENESAS_RX64_HASH */ +#endif /* !MAX3266X_SHA */ #endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ #endif /* !defined(WOLFSSL_RENESAS_TSIP_TLS) && \ !defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY) || diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 136369151a..c9c3b100bb 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -122,7 +122,9 @@ on the specific device platform. #elif defined(WOLFSSL_PSOC6_CRYPTO) - +#elif defined(MAX3266X_SHA) + /* Already brought in by sha256.h */ + /* #include */ #else #include @@ -277,10 +279,6 @@ static int InitSha256(wc_Sha256* sha256) #endif #endif -#ifdef WOLF_CRYPTO_CB - sha256->devId = wc_CryptoCb_DefaultDevID(); -#endif - #ifdef WOLFSSL_MAXQ10XX_CRYPTO XMEMSET(&sha256->maxq_ctx, 0, sizeof(sha256->maxq_ctx)); #endif @@ -1094,6 +1092,12 @@ static int InitSha256(wc_Sha256* sha256) sha256->devId = devId; sha256->devCtx = NULL; #endif + #ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Init(&(sha256->mxcCtx)); + if (ret != 0) { + return ret; + } + #endif #ifdef WOLFSSL_SMALL_STACK_CACHE sha256->W = NULL; #endif @@ -1963,6 +1967,9 @@ static int InitSha256(wc_Sha256* sha256) #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ +#elif defined(MAX3266X_SHA) + /* implemented in wolfcrypt/src/port/maxim/max3266x.c */ + #elif defined(WOLFSSL_RENESAS_RX64_HASH) /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */ @@ -2241,6 +2248,10 @@ void wc_Sha256Free(wc_Sha256* sha256) } #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha256->mxcCtx)); +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256) wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256); #endif /* WOLFSSL_ASYNC_CRYPT */ @@ -2353,6 +2364,9 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ +#elif defined(MAX3266X_SHA) + /* implemented in wolfcrypt/src/port/maxim/max3266x.c */ + #else int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash) @@ -2487,7 +2501,8 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ #elif defined(WOLFSSL_RENESAS_RX64_HASH) /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */ - +#elif defined(MAX3266X_SHA) + /* Implemented in wolfcrypt/src/port/maxim/max3266x.c */ #else int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash) @@ -2538,6 +2553,13 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) wc_MAXQ10XX_Sha256Copy(src); #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + #ifdef WOLFSSL_SMALL_STACK_CACHE dst->W = NULL; #endif diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 77313f7a2a..7f3e745c60 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -96,6 +96,11 @@ #include #endif +#if defined(MAX3266X_SHA) + /* Already brought in by sha512.h */ + /* #include */ +#endif + #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) #if defined(__GNUC__) && ((__GNUC__ < 4) || \ (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)) @@ -149,6 +154,9 @@ !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ +#elif defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) int wc_InitSha512(wc_Sha512* sha512) { @@ -765,6 +773,12 @@ int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) sha512->ctx.mode = ESP32_SHA_INIT; #endif +#ifdef MAX3266X_SHA_CB + if (wc_MXC_TPU_SHA_Init(&(sha512->mxcCtx)) != 0){ + return BAD_FUNC_ARG; + } +#endif + return InitSha512_Family(sha512, heap, devId, InitSha512); } @@ -1158,6 +1172,9 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */ #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) +#elif defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + #else static WC_INLINE int Sha512Final(wc_Sha512* sha512) @@ -1318,6 +1335,9 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512) !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ +#elif defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + #else static int Sha512FinalRaw(wc_Sha512* sha512, byte* hash, size_t digestSz) @@ -1394,6 +1414,10 @@ int wc_Sha512Final(wc_Sha512* sha512, byte* hash) #endif /* WOLFSSL_KCAPI_HASH */ +#if defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + +#else #if !defined(WOLFSSL_SE050) || !defined(WOLFSSL_SE050_HASH) int wc_InitSha512(wc_Sha512* sha512) { @@ -1436,12 +1460,18 @@ void wc_Sha512Free(wc_Sha512* sha512) } #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha512->mxcCtx)); +#endif + #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512); #endif /* WOLFSSL_ASYNC_CRYPT */ ForceZero(sha512, sizeof(*sha512)); } +#endif + #if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) \ && !defined(WOLFSSL_KCAPI_HASH) /* Apply SHA512 transformation to the data */ @@ -1560,6 +1590,9 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ +#elif defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + #else static int InitSha384(wc_Sha384* sha384) @@ -1736,6 +1769,13 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) sha384->ctx.mode = ESP32_SHA_INIT; #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Init(&(sha384->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + ret = InitSha384(sha384); if (ret != 0) { return ret; @@ -1755,6 +1795,10 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) #endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA512 || WOLFSSL_KCAPI_HASH */ +#if defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + +#else int wc_InitSha384(wc_Sha384* sha384) { int devId = INVALID_DEVID; @@ -1810,9 +1854,14 @@ void wc_Sha384Free(wc_Sha384* sha384) } #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha384->mxcCtx)); +#endif + ForceZero(sha384, sizeof(*sha384)); } +#endif #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 @@ -1824,6 +1873,9 @@ void wc_Sha384Free(wc_Sha384* sha384) !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ +#elif defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + #else static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash, @@ -1927,6 +1979,13 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) } #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + return ret; } @@ -2115,6 +2174,8 @@ int wc_Sha512_256Transform(wc_Sha512* sha, const unsigned char* data) #elif defined(WOLFSSL_RENESAS_RSIP) && \ !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */ +#elif defined(MAX3266X_SHA) + /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ #else int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash) @@ -2214,6 +2275,13 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) } #endif +#ifdef MAX3266X_SHA_CB + ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx)); + if (ret != 0) { + return ret; + } +#endif + return ret; } diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a2e1dcdfed..772231ba0d 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -44,6 +44,13 @@ #include #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include +#ifdef WOLF_CRYPTO_CB + #include +#endif +#endif + #ifdef WOLFSSL_PSOC6_CRYPTO #include #endif @@ -251,6 +258,22 @@ int wolfCrypt_Init(void) } #endif + /* Crypto Callbacks only works on AES for MAX32666/5 HW */ + #if defined(MAX3266X_AES) && defined(WOLF_CRYPTO_CB) + ret = wc_CryptoCb_RegisterDevice(WOLFSSL_MAX3266X_DEVID, wc_MxcCryptoCb, + NULL); + if(ret != 0) { + return ret; + } + #endif + #if defined(MAX3266X_RTC) + ret = wc_MXC_RTC_Init(); + if (ret != 0) { + WOLFSSL_MSG("MXC RTC Init Failed"); + return WC_HW_E; + } + #endif + #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \ defined(WOLFSSL_ATECC608A) ret = atmel_init(); @@ -1350,6 +1373,196 @@ int wolfSSL_CryptHwMutexUnLock(void) #endif /* WOLFSSL_CRYPT_HW_MUTEX */ +#if WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX) +/* Mutex for protection of cryptography hardware */ +#ifndef NO_RNG_MUTEX +static wolfSSL_Mutex wcCryptHwRngMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwRngMutex); +#endif /* NO_RNG_MUTEX */ +#ifndef NO_AES_MUTEX +static wolfSSL_Mutex wcCryptHwAesMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwAesMutex); +#endif /* NO_AES_MUTEX */ +#ifndef NO_HASH_MUTEX +static wolfSSL_Mutex wcCryptHwHashMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwHashMutex); +#endif /* NO_HASH_MUTEX */ +#ifndef NO_PK_MUTEX +static wolfSSL_Mutex wcCryptHwPkMutex \ + WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwPkMutex); +#endif /* NO_PK_MUTEX */ + +#ifndef WOLFSSL_MUTEX_INITIALIZER +#ifndef NO_RNG_MUTEX +static int wcCryptHwRngMutexInit = 0; +#endif /* NO_RNG_MUTEX */ +#ifndef NO_AES_MUTEX +static int wcCryptHwAesMutexInit = 0; +#endif /* NO_AES_MUTEX */ +#ifndef NO_HASH_MUTEX +static int wcCryptHwHashMutexInit = 0; +#endif /* NO_HASH_MUTEX */ +#ifndef NO_PK_MUTEX +static int wcCryptHwPkMutexInit = 0; +#endif /* NO_PK_MUTEX */ +#endif /* WOLFSSL_MUTEX_INITIALIZER */ + + +/* Allows ability to switch to different mutex based on enum type */ +/* hw_mutex_algo, expects the dereferenced Ptrs to be set to NULL */ +static int hwAlgoPtrSet(hw_mutex_algo hwAlgo, wolfSSL_Mutex** wcHwAlgoMutexPtr, + int** wcHwAlgoInitPtr) +{ + if (*wcHwAlgoMutexPtr != NULL || *wcHwAlgoInitPtr != NULL) { + return BAD_FUNC_ARG; + } + switch (hwAlgo) { + #ifndef NO_RNG_MUTEX + case rng_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwRngMutex; + *wcHwAlgoInitPtr = &wcCryptHwRngMutexInit; + break; + #endif + #ifndef NO_AES_MUTEX + case aes_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwAesMutex; + *wcHwAlgoInitPtr = &wcCryptHwAesMutexInit; + break; + #endif + #ifndef NO_HASH_MUTEX + case hash_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwHashMutex; + *wcHwAlgoInitPtr = &wcCryptHwHashMutexInit; + break; + #endif + #ifndef NO_PK_MUTEX + case pk_mutex: + *wcHwAlgoMutexPtr = &wcCryptHwPkMutex; + *wcHwAlgoInitPtr = &wcCryptHwPkMutexInit; + break; + #endif + default: + return BAD_FUNC_ARG; + } + return 0; +} + +static int hwAlgoMutexInit(hw_mutex_algo hwAlgo) +{ + int ret = 0; +#ifndef WOLFSSL_MUTEX_INITIALIZER + wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL; + int* wcHwAlgoInitPtr = NULL; + ret = hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr); + if (ret != 0) { + return ret; + } + if (*wcHwAlgoInitPtr == 0) { + ret = wc_InitMutex(wcHwAlgoMutexPtr); + if (ret == 0) { + *wcHwAlgoInitPtr = 1; + } + } +#endif + return ret; +} + +static int hwAlgoMutexLock(hw_mutex_algo hwAlgo) +{ + /* Make sure HW Mutex has been initialized */ + int ret = 0; + wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL; + int* wcHwAlgoInitPtr = NULL; + ret = hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr); + if (ret != 0) { + return ret; + } + ret = hwAlgoMutexInit(hwAlgo); + if (ret == 0) { + ret = wc_LockMutex(wcHwAlgoMutexPtr); + } + return ret; +} + +static int hwAlgoMutexUnLock(hw_mutex_algo hwAlgo) +{ + wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL; + int* wcHwAlgoInitPtr = NULL; + if (hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr) != 0) { + return BAD_FUNC_ARG; + } + if (*wcHwAlgoInitPtr) { + return wc_UnLockMutex(wcHwAlgoMutexPtr); + } + else { + return BAD_MUTEX_E; + } +} + +/* Wrap around generic hwAlgo* functions and use correct */ +/* global mutex to determine if it can be unlocked/locked */ +#ifndef NO_RNG_MUTEX +int wolfSSL_HwRngMutexInit(void) +{ + return hwAlgoMutexInit(rng_mutex); +} +int wolfSSL_HwRngMutexLock(void) +{ + return hwAlgoMutexLock(rng_mutex); +} +int wolfSSL_HwRngMutexUnLock(void) +{ + return hwAlgoMutexUnLock(rng_mutex); +} +#endif /* NO_RNG_MUTEX */ + +#ifndef NO_AES_MUTEX +int wolfSSL_HwAesMutexInit(void) +{ + return hwAlgoMutexInit(aes_mutex); +} +int wolfSSL_HwAesMutexLock(void) +{ + return hwAlgoMutexLock(aes_mutex); +} +int wolfSSL_HwAesMutexUnLock(void) +{ + return hwAlgoMutexUnLock(aes_mutex); +} +#endif /* NO_AES_MUTEX */ + +#ifndef NO_HASH_MUTEX +int wolfSSL_HwHashMutexInit(void) +{ + return hwAlgoMutexInit(hash_mutex); +} +int wolfSSL_HwHashMutexLock(void) +{ + return hwAlgoMutexLock(hash_mutex); +} +int wolfSSL_HwHashMutexUnLock(void) +{ + return hwAlgoMutexUnLock(hash_mutex); +} +#endif /* NO_HASH_MUTEX */ + +#ifndef NO_PK_MUTEX +int wolfSSL_HwPkMutexInit(void) +{ + return hwAlgoMutexInit(pk_mutex); +} +int wolfSSL_HwPkMutexLock(void) +{ + return hwAlgoMutexLock(pk_mutex); +} +int wolfSSL_HwPkMutexUnLock(void) +{ + return hwAlgoMutexUnLock(pk_mutex); +} +#endif /* NO_PK_MUTEX */ + +#endif /* WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX) */ + /* ---------------------------------------------------------------------------*/ /* Mutex Ports */ /* ---------------------------------------------------------------------------*/ @@ -3149,6 +3362,9 @@ time_t mqx_time(time_t* timer) #endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */ +#if defined(MAX3266X_RTC) + #define XTIME wc_MXC_RTC_Time +#endif #if defined(WOLFSSL_TIRTOS) && defined(USER_TIME) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c14d712e2a..7be838e607 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -390,6 +390,9 @@ const byte const_byte_array[] = "A+Gd\0\0\0"; #ifdef HAVE_RENESAS_SYNC #include #endif + #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include + #endif #endif #ifdef _MSC_VER diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 3979c67441..d091946c0c 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -116,7 +116,9 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/Renesas/renesas_sync.h \ wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h \ wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h \ - wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h + wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h \ + wolfssl/wolfcrypt/port/maxim/max3266x.h \ + wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h if BUILD_CRYPTOAUTHLIB nobase_include_HEADERS+= wolfssl/wolfcrypt/port/atmel/atmel.h diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h b/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h new file mode 100644 index 0000000000..e25dba7bb8 --- /dev/null +++ b/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h @@ -0,0 +1,73 @@ +/* max3266x-cryptocb.h + * + * Copyright (C) 2006-2024 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 _WOLFPORT_MAX3266X_CRYPTO_CB_H_ +#define _WOLFPORT_MAX3266X_CRYPTO_CB_H_ + +#if (defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ + defined(WOLF_CRYPTO_CB) +#ifndef WOLFSSL_MAX3266X_DEVID + #define WOLFSSL_MAX3266X_DEVID 9 +#endif +#define WC_USE_DEVID WOLFSSL_MAX3266X_DEVID +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + + WOLFSSL_LOCAL int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, + void* ctx); +#ifdef HAVE_AES_ECB + WOLFSSL_LOCAL int wc_MxcCb_AesEcbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif +#ifdef HAVE_AES_CBC + WOLFSSL_LOCAL int wc_MxcCb_AesCbcEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif + +#ifdef HAVE_AES_DECRYPT +#ifdef HAVE_AES_ECB + WOLFSSL_LOCAL int wc_MxcCb_AesEcbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif +#ifdef HAVE_AES_CBC + WOLFSSL_LOCAL int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif +#endif /* HAVE_AES_DECRYPT */ + + + WOLFSSL_LOCAL int wc_MXC_Sha256Update(wc_MXC_Sha* sha256, + const unsigned char* data, + unsigned int len); + WOLFSSL_LOCAL int wc_MXC_Sha256Final(wc_MXC_Sha* sha256, + unsigned char* hash); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* (WOLFSSL_MAX3266X || WOLFSSL_MAX3266X_OLD) && WOLF_CRYPTO_CB) */ +#endif /* _WOLFPORT_MAX3266X_CRYPTO_CB_H_ */ diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x.h b/wolfssl/wolfcrypt/port/maxim/max3266x.h new file mode 100644 index 0000000000..10c1188b44 --- /dev/null +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -0,0 +1,388 @@ +/* max3266x.h + * + * Copyright (C) 2006-2024 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 _WOLFPORT_MAX3266X_H_ +#define _WOLFPORT_MAX3266X_H_ + +#include + +#ifndef WOLFSSL_MAX_HASH_SIZE + #define WOLFSSL_MAX_HASH_SIZE 64 +#endif + +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + +/* Some extra conditions when using callbacks */ +#if defined(WOLF_CRYPTO_CB) + #define MAX3266X_CB + #ifdef MAX3266X_MATH + #error Cannot have MAX3266X_MATH and MAX3266X_CB + #endif + #ifdef MAX3266X_SHA + #undef MAX3266X_SHA /* Turn Off Normal Sha Definition */ + #define MAX3266X_SHA_CB /* Turn On Callback for SHA */ + #endif +#endif + +/* Default to all HW acceleration on unless specified in user_settings */ +#if !defined(MAX3266X_RNG) && !defined(MAX3266X_AES) && \ + !defined(MAX3266X_AESGCM) && !defined(MAX3266X_SHA) && \ + !defined(MAX3266X_MATH) + #define MAX3266X_RNG + #define MAX3266X_AES + #ifndef MAX3266X_CB + #define MAX3266X_SHA /* SHA is Supported, but need new definitions */ + #define MAX3266X_MATH /* MATH is not supported with callbacks */ + #endif + #ifdef MAX3266X_CB + #define MAX3266X_SHA_CB /* Turn on Callback for SHA */ + #endif +#endif + +/* Crypto HW can be used in parallel on this device */ +/* Sets up new Mutexing if desired */ +#ifdef WOLFSSL_ALGO_HW_MUTEX + /* SDK only supports using RNG in parallel with crypto HW */ + /* AES, HASH, and PK must share some mutex */ + #define NO_AES_MUTEX + #define NO_HASH_MUTEX + #define NO_PK_MUTEX +#endif /* WOLFSSL_ALGO_HW_MUTEX */ + +#if defined(WOLFSSL_MAX3266X_OLD) + /* Support for older SDK API Maxim provides */ + + /* These are needed for older SDK */ + #define TARGET MAX32665 + #define TARGET_REV 0x4131 + #include "mxc_sys.h" + + + + #if defined(MAX3266X_RNG) + #include "trng.h" /* Provides TRNG Drivers */ + #define MXC_TPU_TRNG_Read TRNG_Read + #warning "TRNG Health Test not available in older Maxim SDK" + #define MXC_TRNG_HealthTest(...) 0 + #endif + #if defined(MAX3266X_AES) + #include "cipher.h" /* Provides Drivers for AES */ + /* AES Defines */ + #define MXC_TPU_CIPHER_TYPE tpu_ciphersel_t + #define MXC_TPU_CIPHER_AES128 TPU_CIPHER_AES128 + #define MXC_TPU_CIPHER_AES192 TPU_CIPHER_AES192 + #define MXC_TPU_CIPHER_AES256 TPU_CIPHER_AES256 + + #define MXC_TPU_MODE_TYPE tpu_modesel_t + #define MXC_TPU_MODE_ECB TPU_MODE_ECB + #define MXC_TPU_MODE_CBC TPU_MODE_CBC + #define MXC_TPU_MODE_CFB TPU_MODE_CFB + #define MXC_TPU_MODE_CTR TPU_MODE_CTR + + /* AES Functions */ + #define MXC_TPU_Cipher_Config TPU_Cipher_Config + #define MXC_TPU_Cipher_AES_Encrypt TPU_AES_Encrypt + #define MXC_TPU_Cipher_AES_Decrypt TPU_AES_Decrypt + + #endif + #if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) + #include "hash.h" /* Proivdes Drivers for SHA */ + /* SHA Defines */ + #define MXC_TPU_HASH_TYPE tpu_hashfunsel_t + #define MXC_TPU_HASH_SHA1 TPU_HASH_SHA1 + #define MXC_TPU_HASH_SHA224 TPU_HASH_SHA224 + #define MXC_TPU_HASH_SHA256 TPU_HASH_SHA256 + #define MXC_TPU_HASH_SHA384 TPU_HASH_SHA384 + #define MXC_TPU_HASH_SHA512 TPU_HASH_SHA512 + + /* SHA Functions */ + #define MXC_TPU_Hash_Config TPU_Hash_Config + #define MXC_TPU_Hash_SHA TPU_SHA + + #endif + #if defined(MAX3266X_MATH) + #include "maa.h" /* Provides Drivers for math acceleration for */ + /* ECDSA and RSA Acceleration */ + /* MAA Defines */ + #define MXC_TPU_MAA_TYPE tpu_maa_clcsel_t + #define MXC_TPU_MAA_EXP TPU_MAA_EXP + #define MXC_TPU_MAA_SQ TPU_MAA_SQ + #define MXC_TPU_MAA_MUL TPU_MAA_MUL + #define MXC_TPU_MAA_SQMUL TPU_MAA_SQMUL + #define MXC_TPU_MAA_ADD TPU_MAA_ADD + #define MXC_TPU_MAA_SUB TPU_MAA_SUB + + /* MAA Functions */ + #define MXC_TPU_MAA_Compute MAA_Compute + #define MXC_TPU_MAA_Shutdown MAA_Shutdown + #define MXC_TPU_MAA_Init MAA_Init + #define MXC_TPU_MAA_Reset MAA_Reset + + #endif + + /* TPU Functions */ + #define MXC_TPU_Init SYS_TPU_Init + #define MXC_TPU_Shutdown SYS_TPU_Shutdown + #define MXC_SYS_PERIPH_CLOCK_TPU SYS_PERIPH_CLOCK_TPU + + #define MXC_SYS_PERIPH_CLOCK_TPU SYS_PERIPH_CLOCK_TPU + #define MXC_SYS_PERIPH_CLOCK_TRNG SYS_PERIPH_CLOCK_TRNG + +#else + /* Defaults to expect newer SDK */ + #if defined(MAX3266X_RNG) + #include "trng.h" /* Provides Drivers for TRNG */ + #endif + #if defined(MAX3266X_AES) || defined(MAX3266X_SHA) || \ + defined(MAX3266X_MATH) || defined(MAX3266X_RSA) || \ + defined(MAX3266X_RNG) + #include "tpu.h" /* SDK Drivers for the TPU unit */ + /* Handles AES, SHA, and */ + /* MAA driver to accelerate RSA/ECDSA */ + + /* AES Defines */ + #define MXC_TPU_CIPHER_TYPE mxc_tpu_ciphersel_t + #define MXC_TPU_MODE_TYPE mxc_tpu_modesel_t + + /* SHA Defines */ + #define MXC_TPU_HASH_TYPE mxc_tpu_hashfunsel_t + + /* MAA Defines */ + #define MXC_TPU_MAA_TYPE mxc_tpu_maa_clcsel_t + + + #endif + +#endif + + +/* Provide Driver for RTC if specified, meant for wolfCrypt benchmark only */ +#if defined(MAX3266X_RTC) + #if defined(WOLFSSL_MAX3266X_OLD) + #error Not Implemented with old SDK + #endif + #include "time.h" + #include "rtc.h" + #define MXC_SECS_PER_MIN (60) + #define MXC_SECS_PER_HR (60 * MXC_SECS_PER_MIN) + #define MXC_SECS_PER_DAY (24 * MXC_SECS_PER_HR) +#endif + +/* Variable Definitions */ +#ifdef __cplusplus + extern "C" { +#endif + + WOLFSSL_LOCAL int wc_MXC_TPU_Init(void); + WOLFSSL_LOCAL int wc_MXC_TPU_Shutdown(void); + /* Convert Errors to wolfCrypt Codes */ + WOLFSSL_LOCAL int wc_MXC_error(int *ret); + +#ifdef MAX3266X_RTC + WOLFSSL_LOCAL int wc_MXC_RTC_Init(void); + WOLFSSL_LOCAL int wc_MXC_RTC_Reset(void); + WOLFSSL_LOCAL double wc_MXC_RTC_Time(void); +#endif + +#ifdef MAX3266X_VERBOSE + #ifndef DEBUG_WOLFSSL + #error Need "#define DEBUG_WOLFSSL" to do use "#define MAX3266X_VERBOSE" + #else + #define MAX3266X_MSG(...) WOLFSSL_MSG(__VA_ARGS__) + #endif +#else + #define MAX3266X_MSG(...) /* Compile out Verbose MSGs */ +#endif + +#ifdef MAX3266X_RNG + WOLFSSL_LOCAL int wc_MXC_TRNG_Random(unsigned char* output, + unsigned int sz); +#endif + +#ifdef MAX3266X_AES + WOLFSSL_LOCAL int wc_MXC_TPU_AesEncrypt(const unsigned char* in, + const unsigned char* iv, + const unsigned char* enc_key, + MXC_TPU_MODE_TYPE mode, + unsigned int data_size, + unsigned char* out, unsigned int keySize); +#ifdef HAVE_AES_DECRYPT + WOLFSSL_LOCAL int wc_MXC_TPU_AesDecrypt(const unsigned char* in, + const unsigned char* iv, + const unsigned char* enc_key, + MXC_TPU_MODE_TYPE mode, + unsigned int data_size, + unsigned char* out, unsigned int keySize); +#endif /* HAVE_AES_DECRYPT */ +#endif /* MAX3266X_AES */ + +#if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) + + typedef struct { + unsigned char *msg; + unsigned int used; + unsigned int size; + #ifdef WOLFSSL_HASH_FLAGS + unsigned int flags; /* enum wc_HashFlags in hash.h */ + #endif + } wc_MXC_Sha; + + #if !defined(NO_SHA) + #ifndef MAX3266X_SHA_CB + typedef wc_MXC_Sha wc_Sha; + #define WC_SHA_TYPE_DEFINED + #endif /* !MAX3266X_SHA_CB */ + + /* Define the SHA digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA1[20] = { + 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, + 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, + 0xaf, 0xd8, 0x07, 0x09}; + #endif /* NO_SHA */ + + #if defined(WOLFSSL_SHA224) + #ifndef MAX3266X_SHA_CB + typedef wc_MXC_Sha wc_Sha224; + #define WC_SHA224_TYPE_DEFINED + #endif /* !MAX3266X_SHA_CB */ + + /* Define the SHA-224 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA224[28] = { + 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, + 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4, + 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a, + 0xc5, 0xb3, 0xe4, 0x2f}; + #endif /* WOLFSSL_SHA224 */ + + #if !defined(NO_SHA256) + #ifndef MAX3266X_SHA_CB + typedef wc_MXC_Sha wc_Sha256; + #define WC_SHA256_TYPE_DEFINED + #endif /* !MAX3266X_SHA_CB */ + + /* Define the SHA-256 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA256[32] = { + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, + 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, + 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, + 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; + #endif /* NO_SHA256 */ + + #if defined(WOLFSSL_SHA384) + #ifndef MAX3266X_SHA_CB + typedef wc_MXC_Sha wc_Sha384; + #define WC_SHA384_TYPE_DEFINED + #endif /* !MAX3266X_SHA_CB */ + + /* Define the SHA-384 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA384[48] = { + 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, + 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, + 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, + 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, + 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, + 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b}; + #endif /* WOLFSSL_SHA384 */ + + #if defined(WOLFSSL_SHA512) + #ifndef MAX3266X_SHA_CB + typedef wc_MXC_Sha wc_Sha512; + typedef wc_MXC_Sha wc_Sha512_224; + typedef wc_MXC_Sha wc_Sha512_256; + #define WC_SHA512_TYPE_DEFINED + #endif /* !MAX3266X_SHA_CB */ + + /* Does not support these SHA512 Macros */ + #ifndef WOLFSSL_NOSHA512_224 + #warning "MAX3266X Port does not support SHA-512/224" + #define WOLFSSL_NOSHA512_224 + #endif + #ifndef WOLFSSL_NOSHA512_256 + #warning "MAX3266X Port does not support SHA-512/256" + #define WOLFSSL_NOSHA512_256 + #endif + + /* Define the SHA-512 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA512[64] = { + 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, + 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, + 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, + 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, + 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, + 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, + 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, + 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e}; + #endif /* WOLFSSL_SHA512 */ + + + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Init(wc_MXC_Sha *hash); + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Update(wc_MXC_Sha *hash, + const unsigned char* data, + unsigned int size); + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Final(wc_MXC_Sha *hash, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo); + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo); + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Copy(wc_MXC_Sha* src, wc_MXC_Sha* dst); + WOLFSSL_LOCAL void wc_MXC_TPU_SHA_Free(wc_MXC_Sha* hash); + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_GetDigest(wc_MXC_Sha *hash, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo); + + +#endif /* defined(MAX3266X_SHA) && !defined(WOLF_CRYPTO_CB) */ + +#if defined(MAX3266X_MATH) + #define WOLFSSL_USE_HW_MP + /* Setup mapping to fallback if edge case is encountered */ + #if defined(USE_FAST_MATH) + #define mxc_mod fp_mod + #define mxc_addmod fp_addmod + #define mxc_submod fp_submod + #define mxc_mulmod fp_mulmod + #define mxc_exptmod fp_exptmod + #define mxc_sqrmod fp_sqrmod + #elif defined(WOLFSSL_SP_MATH_ALL) + #define mxc_mod sp_mod + #define mxc_addmod sp_addmod + #define mxc_submod sp_submod + #define mxc_mulmod sp_mulmod + #define mxc_exptmod sp_exptmod + #define mxc_sqrmod sp_sqrmod + #else + #error Need to use WOLFSSL_SP_MATH_ALL + #endif + +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* WOLFSSL_MAX32665 || WOLFSSL_MAX32666 */ +#endif /* _WOLFPORT_MAX3266X_H_ */ diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 6ed5950265..dd9d8b90ac 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -76,6 +76,9 @@ #if defined(WOLFSSL_SILABS_SE_ACCEL) #include #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include +#endif #if !defined(NO_OLD_SHA_NAMES) #define SHA WC_SHA @@ -160,6 +163,9 @@ struct wc_Sha { int devId; void* devCtx; /* generic crypto callback context */ #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_Sha mxcCtx; +#endif #ifdef WOLFSSL_IMXRT1170_CAAM caam_hash_ctx_t ctx; caam_handle_t hndl; diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index aa4632cf3e..c435cf061c 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -146,6 +146,10 @@ enum { #include "wolfssl/wolfcrypt/port/Renesas/renesas-rx64-hw-crypt.h" #else +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include "wolfssl/wolfcrypt/port/maxim/max3266x.h" +#endif + #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" #endif @@ -209,6 +213,9 @@ struct wc_Sha256 { #ifdef WOLFSSL_DEVCRYPTO_HASH WC_CRYPTODEV ctx; #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_Sha mxcCtx; +#endif #if defined(WOLFSSL_DEVCRYPTO_HASH) || defined(WOLFSSL_HASH_KEEP) byte* msg; word32 used; diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 4b2dd2a194..9bcebdc62a 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -135,6 +135,9 @@ enum { #include "mcapi.h" #include "mcapi_error.h" #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include "wolfssl/wolfcrypt/port/maxim/max3266x.h" +#endif /* wc_Sha512 digest */ struct wc_Sha512 { #ifdef WOLFSSL_PSOC6_CRYPTO @@ -185,6 +188,9 @@ struct wc_Sha512 { int devId; void* devCtx; /* generic crypto callback context */ #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_Sha mxcCtx; +#endif #ifdef WOLFSSL_HASH_FLAGS word32 flags; /* enum wc_HashFlags in hash.h */ #endif diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 53075c5c6a..2a9a88014a 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -1150,27 +1150,22 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp); #define mp_div_2 sp_div_2 #define mp_add sp_add #define mp_sub sp_sub -#define mp_addmod sp_addmod -#define mp_submod sp_submod + #define mp_addmod_ct sp_addmod_ct #define mp_submod_ct sp_submod_ct #define mp_xor_ct sp_xor_ct #define mp_lshd sp_lshd #define mp_rshd sp_rshd #define mp_div sp_div -#define mp_mod sp_mod #define mp_mul sp_mul -#define mp_mulmod sp_mulmod #define mp_invmod sp_invmod #define mp_invmod_mont_ct sp_invmod_mont_ct #define mp_exptmod_ex sp_exptmod_ex -#define mp_exptmod sp_exptmod #define mp_exptmod_nct sp_exptmod_nct #define mp_div_2d sp_div_2d #define mp_mod_2d sp_mod_2d #define mp_mul_2d sp_mul_2d #define mp_sqr sp_sqr -#define mp_sqrmod sp_sqrmod #define mp_unsigned_bin_size sp_unsigned_bin_size #define mp_read_unsigned_bin sp_read_unsigned_bin @@ -1193,6 +1188,17 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp); #define mp_memzero_add sp_memzero_add #define mp_memzero_check sp_memzero_check +/* Allow for Hardware Based Mod Math */ +/* Avoid redeclaration warnings */ +#ifndef WOLFSSL_USE_HW_MP + #define mp_mod sp_mod + #define mp_addmod sp_addmod + #define mp_submod sp_submod + #define mp_mulmod sp_mulmod + #define mp_exptmod sp_exptmod + #define mp_sqrmod sp_sqrmod +#endif + #ifdef WOLFSSL_DEBUG_MATH #define mp_dump(d, a, v) sp_print(a, d) #endif diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 7373e0550a..cb8d0f732d 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -54,6 +54,10 @@ #endif #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include +#endif + #ifdef WOLFSSL_LINUXKM #include "../../linuxkm/linuxkm_wc_port.h" #endif /* WOLFSSL_LINUXKM */ @@ -418,7 +422,8 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); /* Enable crypt HW mutex for Freescale MMCAU, PIC32MZ or STM32 */ #if defined(FREESCALE_MMCAU) || defined(WOLFSSL_MICROCHIP_PIC32MZ) || \ - defined(STM32_CRYPTO) || defined(STM32_HASH) || defined(STM32_RNG) + defined(STM32_CRYPTO) || defined(STM32_HASH) || defined(STM32_RNG) || \ + defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) #ifndef WOLFSSL_CRYPT_HW_MUTEX #define WOLFSSL_CRYPT_HW_MUTEX 1 #endif @@ -433,9 +438,9 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); however it's recommended to call this directly on Hw init to avoid possible race condition where two calls to wolfSSL_CryptHwMutexLock are made at the same time. */ - int wolfSSL_CryptHwMutexInit(void); - int wolfSSL_CryptHwMutexLock(void); - int wolfSSL_CryptHwMutexUnLock(void); + WOLFSSL_LOCAL int wolfSSL_CryptHwMutexInit(void); + WOLFSSL_LOCAL int wolfSSL_CryptHwMutexLock(void); + WOLFSSL_LOCAL int wolfSSL_CryptHwMutexUnLock(void); #else /* Define stubs, since HW mutex is disabled */ #define wolfSSL_CryptHwMutexInit() 0 /* Success */ @@ -443,6 +448,74 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); #define wolfSSL_CryptHwMutexUnLock() (void)0 /* Success */ #endif /* WOLFSSL_CRYPT_HW_MUTEX */ +#if defined(WOLFSSL_ALGO_HW_MUTEX) && (defined(NO_RNG_MUTEX) && \ + defined(NO_AES_MUTEX) && defined(NO_HASH_MUTEX) && defined(NO_PK_MUTEX)) + #error WOLFSSL_ALGO_HW_MUTEX does not support having all mutexs off +#endif +/* To support HW that can do different Crypto in parallel */ +#if WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX) + typedef enum { + #ifndef NO_RNG_MUTEX + rng_mutex, + #endif + #ifndef NO_AES_MUTEX + aes_mutex, + #endif + #ifndef NO_HASH_MUTEX + hash_mutex, + #endif + #ifndef NO_PK_MUTEX + pk_mutex, + #endif + } hw_mutex_algo; +#endif + +/* If algo mutex is off, or WOLFSSL_ALGO_HW_MUTEX is not define, default */ +/* to using the generic wolfSSL_CryptHwMutex */ +#if (!defined(NO_RNG_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + WOLFSSL_LOCAL int wolfSSL_HwRngMutexInit(void); + WOLFSSL_LOCAL int wolfSSL_HwRngMutexLock(void); + WOLFSSL_LOCAL int wolfSSL_HwRngMutexUnLock(void); +#else + #define wolfSSL_HwRngMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwRngMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwRngMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_RNG_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + +#if (!defined(NO_AES_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + WOLFSSL_LOCAL int wolfSSL_HwAesMutexInit(void); + WOLFSSL_LOCAL int wolfSSL_HwAesMutexLock(void); + WOLFSSL_LOCAL int wolfSSL_HwAesMutexUnLock(void); +#else + #define wolfSSL_HwAesMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwAesMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwAesMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_AES_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + +#if (!defined(NO_HASH_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + WOLFSSL_LOCAL int wolfSSL_HwHashMutexInit(void); + WOLFSSL_LOCAL int wolfSSL_HwHashMutexLock(void); + WOLFSSL_LOCAL int wolfSSL_HwHashMutexUnLock(void); +#else + #define wolfSSL_HwHashMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwHashMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwHashMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_HASH_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + +#if (!defined(NO_PK_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ + WOLFSSL_CRYPT_HW_MUTEX + WOLFSSL_LOCAL int wolfSSL_HwPkMutexInit(void); + WOLFSSL_LOCAL int wolfSSL_HwPkMutexLock(void); + WOLFSSL_LOCAL int wolfSSL_HwPkMutexUnLock(void); +#else + #define wolfSSL_HwPkMutexInit wolfSSL_CryptHwMutexInit + #define wolfSSL_HwPkMutexLock wolfSSL_CryptHwMutexLock + #define wolfSSL_HwPkMutexUnLock wolfSSL_CryptHwMutexUnLock +#endif /* !defined(NO_PK_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX) */ + /* Mutex functions */ WOLFSSL_API int wc_InitMutex(wolfSSL_Mutex* m); WOLFSSL_API wolfSSL_Mutex* wc_InitAndAllocMutex(void); diff --git a/wolfssl/wolfcrypt/wolfmath.h b/wolfssl/wolfcrypt/wolfmath.h index fe01ed5cd8..e012ff6551 100644 --- a/wolfssl/wolfcrypt/wolfmath.h +++ b/wolfssl/wolfcrypt/wolfmath.h @@ -52,6 +52,10 @@ This library provides big integer math functions. #include #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include +#endif + #ifndef MIN #define MIN(x,y) ((x)<(y)?(x):(y)) #endif @@ -118,6 +122,28 @@ WOLFSSL_API int wc_export_int(mp_int* mp, byte* buf, word32* len, WOLFSSL_API const char *wc_GetMathInfo(void); #endif +/* Support for generic Hardware based Math Functions */ +#ifdef WOLFSSL_USE_HW_MP + +WOLFSSL_LOCAL int hw_mod(mp_int* multiplier, mp_int* mod, mp_int* result); +WOLFSSL_LOCAL int hw_mulmod(mp_int* multiplier, mp_int* multiplicand, + mp_int* mod, mp_int* result); +WOLFSSL_LOCAL int hw_addmod(mp_int* a, mp_int* b, mp_int* mod, mp_int* result); +WOLFSSL_LOCAL int hw_submod(mp_int* a, mp_int* b, mp_int* mod, mp_int* result); +WOLFSSL_LOCAL int hw_exptmod(mp_int* base, mp_int* exp, mp_int* mod, + mp_int* result); +WOLFSSL_LOCAL int hw_sqrmod(mp_int* base, mp_int* mod, mp_int* result); + +/* One to one mappings */ +#define mp_mod hw_mod +#define mp_addmod hw_addmod +#define mp_submod hw_submod +#define mp_mulmod hw_mulmod +#define mp_exptmod hw_exptmod +#define mp_sqrmod hw_sqrmod + +#endif + #ifdef __cplusplus } /* extern "C" */ #endif