diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index cfd0b71486..bfe1b16a04 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -14236,6 +14236,14 @@ 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) + { + 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 747c22c70e..06e3c37596 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -82,6 +82,10 @@ 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 +#endif + #if defined(WOLFSSL_TI_CRYPT) #include #else @@ -2888,6 +2892,15 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt( } #endif +#if defined(MAX3266X_AES) + word32 keySize; + if (wc_AesGetKeySize(aes, &keySize) == 0) { + return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, MXC_AES_DATA_LEN, + outBlock, (unsigned int)keySize); + } +#endif + AesEncrypt_C(aes, inBlock, outBlock, r); return 0; @@ -3611,6 +3624,15 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( } /* else !wc_esp32AesSupportedKeyLen for ESP32 */ #endif +#if defined(MAX3266X_AES) + word32 keySize; + if (wc_AesGetKeySize(aes, &keySize) == 0) { + return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, MXC_AES_DATA_LEN, + outBlock, (unsigned int)keySize); + } +#endif + AesDecrypt_C(aes, inBlock, outBlock, r); return 0; @@ -4542,8 +4564,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); @@ -5374,6 +5396,82 @@ 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; + +#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + if (sz % AES_BLOCK_SIZE) { + return BAD_LENGTH_E; + } +#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, MXC_AES_DATA_LEN, out, + (unsigned int)keySize); + + /* store iv for next call */ + if (status == E_SUCCESS) { + XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + + return (status == E_SUCCESS) ? 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]; + +#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + if (sz % AES_BLOCK_SIZE) { + return BAD_LENGTH_E; + } +#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, MXC_AES_DATA_LEN, out, + keySize); + + + /* store iv for next call */ + if (status == E_SUCCESS) { + XMEMCPY(iv, temp_block, AES_BLOCK_SIZE); + } + + return (status == E_SUCCESS) ? 0 : -1; + } + #endif /* HAVE_AES_DECRYPT */ + + + #elif defined(WOLFSSL_PIC32MZ_CRYPT) int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) 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/maxim/README.md b/wolfcrypt/src/port/maxim/README.md index 55cb2a04c6..52ffdb9105 100644 --- a/wolfcrypt/src/port/maxim/README.md +++ b/wolfcrypt/src/port/maxim/README.md @@ -1,14 +1,114 @@ -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 microcontrollers. + +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 WC_C_DYNAMIC_FALLBACK` and `#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 specifing `#define MAX3266X_MATH`. + +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 change this error check: + +``` +// Check that we're performing a valid operation +if (clc >= 0x6) { + return E_INVALID; +} +``` +to +``` +// Check that we're performing a valid operation +if (clc >= 0b1111) { + return E_INVALID; +} +``` + +This bug has been reported to Analog Devices +[here](https://github.com/analogdevicesinc/msdk/issues/1089) +if you want to know more details on the issue. + + +## Supported Algos +Using these defines will replace software implentations 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-256 + +`#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` + +## Extra Information +For more Verbose info you can use `#define DEBUG_WOLFSSL` in combination with +`#define MAX3266X_VERBOSE` to see if errors are occuring 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 infromation 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..d13b860d8c --- /dev/null +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -0,0 +1,898 @@ +/* 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 + +#if defined(USE_FAST_MATH) + #error MXC Not Compatible with Fast Math + #include + #define MXC_WORD_SIZE DIGIT_BIT +#elif defined(WOLFSSL_SP_MATH_ALL) + #include + #define MXC_WORD_SIZE SP_WORD_SIZE +#endif + +#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) != EXIT_SUCCESS) { + 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; +} + + +/* Convert Error Codes Correctly */ +/* TODO: Convert to correct wolfCrypt Codes */ +/* TODO: Add wolfssl Message Statements to report HW issue on bad return */ +int wc_MXC_error(int *ret) +{ + switch(*ret){ + case E_SUCCESS: + return 0; + + case E_NULL_PTR: + return E_NULL_PTR; + + case E_INVALID: /* Process Failed */ + return E_INVALID; + + case E_BAD_PARAM: + return BAD_FUNC_ARG; + + case E_BAD_STATE: + return E_BAD_STATE; + + default: + *ret = WC_HW_E; /* If something else return HW Error */ + return *ret; + } +} + + +#if defined(MAX3266X_RNG) + +/* Use this RNG_FAILURE_E for RNG Errors*/ +int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) +{ + if (MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TRNG) != E_SUCCESS) { + MAX3266X_MSG("TRNG Device did not initialize"); + return RNG_FAILURE_E; + } + /* void return function */ + MXC_TPU_TRNG_Read(MXC_TRNG, output, sz); + MAX3266X_MSG("TRNG Hardware Used"); + return 0; +} +#endif /* MAX3266x_RNG */ + +#if defined(MAX3266X_AES) +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; + status = wolfSSL_CryptHwMutexLock(); + 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_CryptHwMutexUnLock(); + return WC_HW_E; + break; + } + wolfSSL_CryptHwMutexUnLock(); + if (status != 0) { + MAX3266X_MSG("AES HW Acceleration Error Occured"); + return WC_HW_E; + } + return 0; +} + +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; + status = wolfSSL_CryptHwMutexLock(); + 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_CryptHwMutexUnLock(); + return WC_HW_E; + break; + } + + wolfSSL_CryptHwMutexUnLock(); + if (status != 0) { + MAX3266X_MSG("AES HW Acceleration Error Occured"); + return WC_HW_E; + } + return 0; +} + +#endif + +#if defined(MAX3266X_SHA) + +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; +} + +int wc_MXC_TPU_SHA_Update(wc_MXC_Sha *hash, const unsigned char* data, + unsigned int size) +{ + void *p; + if (size != (0 || NULL)) { + 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 -1; + } + 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; + status = wc_MXC_TPU_SHA_GetDigest(hash, digest, algo); + /* True Case that msg is an empty string */ + if (status == 1) { + return 0; + } + /* False Case where msg needs to be processed */ + else if (status == 0) { + status = wolfSSL_CryptHwMutexLock(); + if (wc_MXC_error(&status) != 0) { + + 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_CryptHwMutexUnLock(); + if (wc_MXC_error(&status) != 0) { + MAX3266X_MSG("SHA HW Error Occured"); + return status; + } + } + /* Error Occured */ + return status; +} + +int wc_MXC_TPU_SHA_Final(wc_MXC_Sha *hash, unsigned char* digest, + MXC_TPU_HASH_TYPE algo) +{ + int status; + status = wc_MXC_TPU_SHA_GetHash(hash, digest, algo); + if (status != 0) { + return status; + } + XFREE(hash->msg, NULL, DYNAMIC_TYPE_TMP_BUFFER); + status = wc_MXC_TPU_SHA_Init(hash); + if (status != 0) { + return status; + } + return status; +} + +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; + XMEMCPY(dst->hash, src->hash, sizeof(dst->hash)); + return XMEMCMP(dst->hash, src->hash, sizeof(dst->hash)); +} + +void wc_MXC_TPU_SHA_Free(wc_MXC_Sha* hash) +{ + XFREE(hash->msg, NULL, DYNAMIC_TYPE_TMP_BUFFER); + hash->msg = NULL; + wc_MXC_TPU_SHA_Init(hash); + 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->msg == 0 && hash->size == 0 && digest != NULL) { + switch(algo) { + #ifndef NO_SHA256 + case MXC_TPU_HASH_SHA256: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA256, WC_SHA256_DIGEST_SIZE); + break; + #endif + default: + return BAD_FUNC_ARG; + } + return 1; /* True */ + } + return 0; /* False */ +} + +#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 + +#endif /* MAX3266X_SHA */ + +#if defined(MAX3266X_MATH) + +int wc_MXC_MAA_init(unsigned int len) +{ + int status; + MAX3266X_MSG("Setting Hardware Mutex and Starting MAA"); + status = wolfSSL_CryptHwMutexLock(); + if (status != EXIT_SUCCESS) { + return status; + } + status = MXC_TPU_MAA_Init(len); + return wc_MXC_error(&status); /* Return Status of Init */ +} + +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 */ + return WC_HW_E; + } + else if(wc_MXC_error(&status) != EXIT_SUCCESS) { + return status; + } + wolfSSL_CryptHwMutexUnLock(); + return status; +} + +/* Update used number for mp_int struct for results */ +int wc_MXC_MAA_adjustUsed(unsigned int *array, unsigned int length) +{ + int lastNonZeroIndex = -1; /* Track the last non-zero index */ + for (int i = 0; i < length; i++) { + if (array[i] != 0) { + lastNonZeroIndex = i; + } + } + return (lastNonZeroIndex + 1); +} + +unsigned int wc_MXC_MAA_Largest(unsigned int count, ...) +{ + va_list args; + va_start(args, count); + unsigned int largest = va_arg(args, unsigned int); + + for (int i = 1; i < count; i++) { + int num = va_arg(args, unsigned int); + if (num > largest) { + largest = num; + } + } + + va_end(args); + return largest; +} + +int wc_MXC_MAA_Fallback(unsigned int count, ...) +{ + va_list args; + va_start(args, count); + int num; + for (int 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 EXIT_FAILURE; + } + } + 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) +{ + 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 == WC_MXC_TPU_MAA_EXP)) || (mod == NULL)) { + return BAD_FUNC_ARG; + } + + /* Create an array to compare values to to check edge for error edge case */ + mp_digit *zero_tmp = XMALLOC(multiplier->size*(sizeof(mp_digit)), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + XMEMSET(zero_tmp, 0x00, multiplier->size*(sizeof(mp_digit))); + + /* Check for invalid arguments befor padding */ + switch((char)clc){ + case WC_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; + break; + } + + /* Padd out rest of data if used != length to ensure no */ + /* garbage is used in calculation */ + if ((exp != NULL) && (clc == WC_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 WC_MXC_TPU_MAA_SQ: + case WC_MXC_TPU_MAA_MUL: + case WC_MXC_TPU_MAA_SQMUL: + case WC_MXC_TPU_MAA_ADD: + case WC_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; + break; + } + + /* Padd 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 Multipler 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: + 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) { + XMEMSET(result->dp, 0x00, 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* multipler, mp_int* multiplicand, mp_int* exp, + mp_int* mod, mp_int* result, + MXC_TPU_MAA_TYPE clc) +{ + int ret; + int length; + /* Check if result shares struct pointer */ + mp_int* result_tmp_ptr; + mp_int result_tmp; + if ((multipler == 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 == WC_MXC_TPU_MAA_EXP) { + length = wc_MXC_MAA_Largest(5, multipler->used, multiplicand->used, + exp->used, mod->used, result->used); + } + else { + length = wc_MXC_MAA_Largest(4, multipler->used, multiplicand->used, + mod->used, result->used); + } + + /* Zero Pad everything if needed */ + ret = wc_MXC_MAA_zeroPad(multipler, multiplicand, exp, mod, result_tmp_ptr, + clc, length); + if (ret != EXIT_SUCCESS) { + MAX3266X_MSG("Zero Padding Failed"); + return ret; + } + + /* Init MAA HW */ + ret = wc_MXC_MAA_init(length*sizeof(mp_digit)*8); + if (ret != EXIT_SUCCESS) { + MAX3266X_MSG("HW Init Failed"); + return ret; + } + + /* Start Math And Cast to expect types for SDK */ + MAX3266X_MSG("Starting Computation in MAA"); + ret = MXC_TPU_MAA_Compute(clc, (char *)(multipler->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) != EXIT_SUCCESS) { + MAX3266X_MSG("HW Computation Error"); + return ret; + } + + ret = wc_MXC_MAA_Shutdown(); + if (ret != EXIT_SUCCESS) { + MAX3266X_MSG("HW Shutdown Failure"); + return ret; + } + + /* Copy tmp result if needed */ + if ((multipler == result) || (multiplicand == result) || (exp == result) || + (mod == result)) { + mp_copy(result_tmp_ptr, result); + } + + 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; + multiplicand.dp[0] = 0x01; + multiplicand.used = 1; + MAX3266X_MSG("Preparing exptmod MAA HW Call"); + return wc_MXC_MAA_math(base, &multiplicand, exp, mod, result, + WC_MXC_TPU_MAA_EXP); +} + +int wc_MXC_MAA_sqrmod(mp_int* multipler, mp_int* mod, mp_int* result) +{ + mp_int multiplicand; + multiplicand.dp[0] = 0x01; + multiplicand.used = 1; + MAX3266X_MSG("Preparing sqrmod MAA HW Call"); + return wc_MXC_MAA_math(multipler, &multiplicand, NULL, mod, result, + WC_MXC_TPU_MAA_SQ); +} + +int wc_MXC_MAA_mulmod(mp_int* multipler, mp_int* multiplicand, mp_int* mod, + mp_int* result) +{ + MAX3266X_MSG("Preparing mulmod MAA HW Call"); + return wc_MXC_MAA_math(multipler, multiplicand, NULL, mod, result, + WC_MXC_TPU_MAA_MUL); +} + +int wc_MXC_MAA_sqrmulmod(mp_int* multipler, mp_int* multiplicand, + mp_int* exp, mp_int* mod, mp_int* result) +{ + MAX3266X_MSG("Preparing sqrmulmod MAA HW Call"); + return wc_MXC_MAA_math(multipler, multiplicand, NULL, mod, result, + WC_MXC_TPU_MAA_SQMUL); +} + +int wc_MXC_MAA_addmod(mp_int* multipler, mp_int* multiplicand, mp_int* mod, + mp_int* result) +{ + MAX3266X_MSG("Preparing addmod MAA HW Call"); + return wc_MXC_MAA_math(multipler, multiplicand, NULL, mod, result, + WC_MXC_TPU_MAA_ADD); +} + +int wc_MXC_MAA_submod(mp_int* multipler, mp_int* multiplicand, mp_int* mod, + mp_int* result) +{ + MAX3266X_MSG("Preparing submod MAA HW Call"); + if ((mod->used < multipler->used) || (mod->used < multiplicand->used)) { + MAX3266X_MSG("HW Limitation: Defaulting back to software"); + return mxc_submod(multipler, multiplicand, mod, result); + } + else { + return wc_MXC_MAA_math(multipler, multiplicand, NULL, mod, result, + WC_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->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 avaliable 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) +{ + if (wc_MXC_MAA_Fallback(2, a->used, mod->used) != 0){ + return mxc_mod(a, mod, result); + } + else { + mp_int b; + b.dp[0] = 0x00; + b.used = 0x01; + return hw_submod(a, &b, mod, result); + } +} + +int hw_sqrmod(mp_int* base, mp_int* mod, mp_int* result) +{ + if (base->used == 0) { + mp_zero(result); + return 0; + } + return wc_MXC_MAA_sqrmod(base, mod, result); +} + +#endif + + +#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; + } + + if (MXC_RTC_SquareWaveStart(MXC_RTC_F_512HZ) == E_BUSY) { + return E_BUSY; + } + + if (MXC_RTC_Start() != E_NO_ERROR){ + return WC_HW_E; + } + + return 0; +} + +/* Reset the RTC */ +int wc_MXC_RTC_Reset(void) +{ + if (MXC_RTC_Stop() != E_NO_ERROR) { + return WC_HW_E; + } + 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 */ +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; + } + return ((double)rtc_seconds + ((double)rtc_subseconds / 4096)); +} + +#endif /* MAX3266X_RTC */ + + +#endif /* WOLFSSL_MAX32665 || WOLFSSL_MAX32666 */ \ No newline at end of file diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 061ea6b9b2..d532b4ee75 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,13 @@ 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) + { + (void)os; + 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/sha256.c b/wolfcrypt/src/sha256.c index ee534ff66c..a35dc4844b 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -89,7 +89,6 @@ on the specific device platform. #include #endif - /* determine if we are using Espressif SHA hardware acceleration */ #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW #if defined(WOLFSSL_ESP32_CRYPT) && \ @@ -122,7 +121,9 @@ on the specific device platform. #elif defined(WOLFSSL_PSOC6_CRYPTO) - +#elif defined(MAX3266X_SHA) + /* Already brought in by sha256.h */ + /* #include */ #else #include @@ -288,7 +289,6 @@ static int InitSha256(wc_Sha256* sha256) #ifdef HAVE_ARIA sha256->hSession = NULL; #endif - return 0; } #endif @@ -2469,7 +2469,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) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 7ff02abf41..0545f35e3e 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -40,6 +40,10 @@ #include #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include +#endif + #ifdef WOLFSSL_PSOC6_CRYPTO #include #endif @@ -247,6 +251,14 @@ int wolfCrypt_Init(void) } #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(); @@ -3128,6 +3140,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/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 3979c67441..490dadd9a0 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -116,7 +116,8 @@ 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 if BUILD_CRYPTOAUTHLIB nobase_include_HEADERS+= wolfssl/wolfcrypt/port/atmel/atmel.h diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x.h b/wolfssl/wolfcrypt/port/maxim/max3266x.h new file mode 100644 index 0000000000..9c74ddef5d --- /dev/null +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -0,0 +1,289 @@ +/* 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) + +/* 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 + #define MAX3266X_SHA + #define MAX3266X_ECDSA + #define MAX3266X_MATH +#endif + +#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 + #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) + #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 WC_MXC_TPU_MAA_EXP 0b0000 + #define WC_MXC_TPU_MAA_SQ 0b0010 + #define WC_MXC_TPU_MAA_MUL 0b0100 + #define WC_MXC_TPU_MAA_SQMUL 0b0110 + #define WC_MXC_TPU_MAA_ADD 0b1000 + #define WC_MXC_TPU_MAA_SUB 0b1010 + + /* 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_ECDSA) || 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 */ + /* Current SDK for TPU does not handle bit mask correctly */ + /* with expected enum values, so calue need to be set */ + /* manually to work with intended naming scheme */ + #define MXC_TPU_MAA_TYPE mxc_tpu_maa_clcsel_t + #define WC_MXC_TPU_MAA_EXP 0b0000 + #define WC_MXC_TPU_MAA_SQ 0b0010 + #define WC_MXC_TPU_MAA_MUL 0b0100 + #define WC_MXC_TPU_MAA_SQMUL 0b0110 + #define WC_MXC_TPU_MAA_ADD 0b1000 + #define WC_MXC_TPU_MAA_SUB 0b1010 + + #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); + + 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 + +#ifdef MAX3266X_SHA + + typedef struct { + unsigned char *msg; + unsigned int used; + unsigned int size; + unsigned char hash[WOLFSSL_MAX_HASH_SIZE]; + } wc_MXC_Sha; + + #if !defined(NO_SHA256) + typedef wc_MXC_Sha wc_Sha256; + #define WC_SHA256_TYPE_DEFINED + + /* 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 + + + 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 + +#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_ */ \ No newline at end of file diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 6ed5950265..0e05823022 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 diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index aa4632cf3e..311bb31273 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 diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 26978acfe0..eb32c7c0f0 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -1145,27 +1145,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 @@ -1188,6 +1183,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 0cf0eea656..95fa54c16c 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 */ 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