From 2e8cf39feb7a30c500463ba9ff885eabcbed9c8d Mon Sep 17 00:00:00 2001 From: msi-debian Date: Mon, 8 Jul 2024 08:51:24 -0600 Subject: [PATCH 1/8] Initial PR for MAX32665 and MAX32666 TPU HW Support --- wolfcrypt/benchmark/benchmark.c | 8 + wolfcrypt/src/aes.c | 111 ++- wolfcrypt/src/include.am | 3 +- wolfcrypt/src/port/maxim/README.md | 103 ++- wolfcrypt/src/port/maxim/max3266x.c | 906 ++++++++++++++++++++++++ wolfcrypt/src/random.c | 9 + wolfcrypt/src/sha256.c | 7 +- wolfcrypt/src/wc_port.c | 15 + wolfssl/wolfcrypt/include.am | 3 +- wolfssl/wolfcrypt/port/maxim/max3266x.h | 289 ++++++++ wolfssl/wolfcrypt/sha.h | 3 + wolfssl/wolfcrypt/sha256.h | 4 + wolfssl/wolfcrypt/sp_int.h | 18 +- wolfssl/wolfcrypt/wc_port.h | 4 + wolfssl/wolfcrypt/wolfmath.h | 26 + 15 files changed, 1493 insertions(+), 16 deletions(-) create mode 100644 wolfcrypt/src/port/maxim/max3266x.c create mode 100644 wolfssl/wolfcrypt/port/maxim/max3266x.h diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 69a6d0f6e0..32e7a1283f 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -14254,6 +14254,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 aaafbf4019..fd8679b394 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 @@ -2789,6 +2793,9 @@ 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 word32 r; if (aes == NULL) { @@ -2892,6 +2899,14 @@ 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 + AesEncrypt_C(aes, inBlock, outBlock, r); return 0; @@ -3539,6 +3554,9 @@ 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 word32 r; if (aes == NULL) { @@ -3615,6 +3633,14 @@ 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 + AesDecrypt_C(aes, inBlock, outBlock, r); return 0; @@ -4103,7 +4129,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 +4277,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 +4573,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 +5405,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, 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]; + +#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, 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) 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..fa8cd1cddf 100644 --- a/wolfcrypt/src/port/maxim/README.md +++ b/wolfcrypt/src/port/maxim/README.md @@ -1,14 +1,113 @@ -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 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..ca2a508fbb --- /dev/null +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -0,0 +1,906 @@ +/* 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) != 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; +} + + +/* 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) != 0) { + 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 0; +} + +void wc_MXC_TPU_SHA_Free(wc_MXC_Sha* hash) +{ + 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->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) + +/* Sets mutex and initializes hardware according to need operation size */ +int wc_MXC_MAA_init(unsigned int len) +{ + int status; + MAX3266X_MSG("Setting Hardware Mutex and Starting MAA"); + status = wolfSSL_CryptHwMutexLock(); + if (status != 0) { + return status; + } + 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 */ + return WC_HW_E; + } + else if(wc_MXC_error(&status) != 0) { + 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 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 == 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 */ + zero_tmp = (mp_digit*)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) { + 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* multipler, 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; + /* Check if result shares struct pointer */ + 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 != 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_CryptHwMutexUnLock(); + 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) != 0) { + MAX3266X_MSG("HW Computation Error"); + wolfSSL_CryptHwMutexUnLock(); + return ret; + } + + ret = wc_MXC_MAA_Shutdown(); + if (ret != 0) { + MAX3266X_MSG("HW Shutdown Failure"); + wolfSSL_CryptHwMutexUnLock(); + return ret; + } + + /* Copy tmp result if needed */ + if ((multipler == 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; + 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, + WC_MXC_TPU_MAA_EXP); +} + +int wc_MXC_MAA_sqrmod(mp_int* multipler, mp_int* mod, mp_int* result) +{ + mp_int multiplicand; + 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(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) +{ + mp_int b; + 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->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 f1022edea4..42e385af77 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 136369151a..b7ee935f46 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 @@ -2487,7 +2489,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 a2e1dcdfed..3b87dec5ca 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -44,6 +44,10 @@ #include #endif +#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) + #include +#endif + #ifdef WOLFSSL_PSOC6_CRYPTO #include #endif @@ -251,6 +255,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(); @@ -3149,6 +3161,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 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..7e4567f961 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 From d714e55a2bfd1baf9ccd65206bc3b263961b0e96 Mon Sep 17 00:00:00 2001 From: night1rider Date: Thu, 1 Aug 2024 10:32:08 -0600 Subject: [PATCH 2/8] Addressing PR comments typos and cleanup and support HAVE_AES_ECB, Sha1, and Sha224 --- wolfcrypt/benchmark/benchmark.c | 1 + wolfcrypt/src/aes.c | 42 ++++ wolfcrypt/src/port/maxim/README.md | 10 +- wolfcrypt/src/port/maxim/max3266x.c | 280 +++++++++++++++++------- wolfcrypt/src/sha.c | 10 + wolfcrypt/src/sha256.c | 6 + wolfcrypt/src/wc_port.c | 2 +- wolfssl/wolfcrypt/port/maxim/max3266x.h | 29 ++- 8 files changed, 291 insertions(+), 89 deletions(-) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 32e7a1283f..042f736469 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -14259,6 +14259,7 @@ void bench_sphincsKeySign(byte level, byte optim) double current_time(int reset) { + (void)reset; return wc_MXC_RTC_Time(); } diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index fd8679b394..e28e8b59ba 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -11508,6 +11508,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, aes->reg, 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, aes->reg, 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/port/maxim/README.md b/wolfcrypt/src/port/maxim/README.md index fa8cd1cddf..17a66b692f 100644 --- a/wolfcrypt/src/port/maxim/README.md +++ b/wolfcrypt/src/port/maxim/README.md @@ -6,7 +6,7 @@ wolfSSL using Analog Devices MAXQ1065, MAX1080, MAX32665 or MAX32666 wolfSSL can be configured to use the MAXQ1065 or MAX1080 cryptographic controllers. wolfSSL can also be configure to utilize the TPU (crypto accelerator), MAA (math accelerator), and TRNG available on select -MAX32665 and MAX32666 microcontrollers. +MAX32665 and MAX32666 microcontroller. Product datasheets, user guides and other resources can be found at Analog Devices website: @@ -41,7 +41,7 @@ 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`. +or you are specifying `#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 @@ -68,7 +68,7 @@ if you want to know more details on the issue. ## Supported Algos -Using these defines will replace software implentations with a call to the +Using these defines will replace software implementations with a call to the hardware. `#define MAX3266X_RNG` @@ -95,7 +95,7 @@ like RSA and ECC key generation): ## 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 +`#define MAX3266X_VERBOSE` to see if errors are occurring during the hardware setup/ To reproduce benchmark numbers you can use `#define MAX3266X_RTC`. @@ -104,7 +104,7 @@ Do note that this will only work with `#define WOLFSSL_MAX3266X` and not 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 +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 diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c index ca2a508fbb..49e3fe2fdc 100644 --- a/wolfcrypt/src/port/maxim/max3266x.c +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -42,13 +42,15 @@ #include #endif -#if defined(USE_FAST_MATH) - #error MXC Not Compatible with Fast Math +#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 #define MXC_MAA_MAX_SIZE (2048 / MXC_WORD_SIZE) @@ -79,37 +81,45 @@ int wc_MXC_TPU_Shutdown(void) } -/* Convert Error Codes Correctly */ -/* TODO: Convert to correct wolfCrypt Codes */ -/* TODO: Add wolfssl Message Statements to report HW issue on bad return */ +/* Convert Error Codes Correctly and Report HW error when */ +/* using #define MAX3266X_VERBOSE */ 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; + 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: - return BAD_FUNC_ARG; + MAX3266X_MSG("HW Reported: E_BAD_PARAM Error"); + *ret = BAD_FUNC_ARG; + break; case E_BAD_STATE: - return 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 */ - return *ret; + break; } + 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) != 0) { @@ -121,7 +131,7 @@ int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) MAX3266X_MSG("TRNG Hardware Used"); return 0; } -#endif /* MAX3266x_RNG */ +#endif /* MAX3266X_RNG */ #if defined(MAX3266X_AES) int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, @@ -132,46 +142,46 @@ int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, 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; + 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"); + MAX3266X_MSG("AES HW Acceleration Error Occurred"); return WC_HW_E; } return 0; } - +#ifdef HAVE_AES_DECRYPT 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, @@ -212,13 +222,13 @@ int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, } wolfSSL_CryptHwMutexUnLock(); if (status != 0) { - MAX3266X_MSG("AES HW Acceleration Error Occured"); + MAX3266X_MSG("AES HW Acceleration Error Occurred"); return WC_HW_E; } return 0; } - -#endif +#endif /* HAVE_AES_DECRYPT */ +#endif /* MAX3266X_AES */ #if defined(MAX3266X_SHA) @@ -296,11 +306,11 @@ int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, MAX3266X_MSG("SHA HW Acceleration Used"); wolfSSL_CryptHwMutexUnLock(); if (wc_MXC_error(&status) != 0) { - MAX3266X_MSG("SHA HW Error Occured"); + MAX3266X_MSG("SHA HW Error Occurred"); return status; } } - /* Error Occured */ + /* Error Occurred */ return status; } @@ -345,11 +355,21 @@ int wc_MXC_TPU_SHA_GetDigest(wc_MXC_Sha *hash, unsigned char* digest, { if (hash->msg == 0 && hash->size == 0 && digest != NULL) { switch(algo) { + #ifndef NO_SHA + case MXC_TPU_HASH_SHA1: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA1, WC_SHA_DIGEST_SIZE); + break; + #endif /* NO_SHA */ #ifndef NO_SHA256 case MXC_TPU_HASH_SHA256: XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA256, WC_SHA256_DIGEST_SIZE); break; - #endif + #endif /* NO_SHA256 */ + #ifdef WOLFSSL_SHA224 + case MXC_TPU_HASH_SHA224: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA224, WC_SHA224_DIGEST_SIZE); + break; + #endif /* WOLFSSL_SHA224 */ default: return BAD_FUNC_ARG; } @@ -358,6 +378,97 @@ int wc_MXC_TPU_SHA_GetDigest(wc_MXC_Sha *hash, unsigned char* digest, return 0; /* False */ } +#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) @@ -404,13 +515,13 @@ WOLFSSL_API void wc_Sha256Free(wc_Sha256* sha256) return; } -#endif +#endif /* NO_SHA256 */ #endif /* MAX3266X_SHA */ #if defined(MAX3266X_MATH) -/* Sets mutex and initializes hardware according to need operation size */ +/* Sets mutex and initializes hardware according to needed operation size */ int wc_MXC_MAA_init(unsigned int len) { int status; @@ -511,17 +622,20 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, /* 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 WC_HW_E; + } XMEMSET(zero_tmp, 0x00, multiplier->size*sizeof(mp_digit)); /* Check for invalid arguments befor padding */ - switch((char)clc){ + 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 */ @@ -545,13 +659,12 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, 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 */ + /* 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 Multipler Buffer"); + MAX3266X_MSG("Zero Padding Multiplier Buffer"); XMEMSET(multiplier->dp + multiplier->used, 0x00, sizeof(int) * (length - multiplier->used)); } @@ -567,6 +680,8 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, } 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 */ @@ -586,7 +701,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, /* General Control Over MAA Hardware to handle all needed Cases */ -int wc_MXC_MAA_math(mp_int* multipler, mp_int* multiplicand, mp_int* exp, +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) { @@ -595,7 +710,7 @@ int wc_MXC_MAA_math(mp_int* multipler, mp_int* multiplicand, mp_int* exp, mp_int* result_tmp_ptr; mp_int result_tmp; /* Check if result shares struct pointer */ - if ((multipler == result) || (multiplicand == result) || (exp == result) || + 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 */ @@ -609,16 +724,16 @@ int wc_MXC_MAA_math(mp_int* multipler, mp_int* multiplicand, mp_int* exp, } if (clc == WC_MXC_TPU_MAA_EXP) { - length = wc_MXC_MAA_Largest(5, multipler->used, multiplicand->used, + length = wc_MXC_MAA_Largest(5, multiplier->used, multiplicand->used, exp->used, mod->used, result->used); } else { - length = wc_MXC_MAA_Largest(4, multipler->used, multiplicand->used, + length = wc_MXC_MAA_Largest(4, multiplier->used, multiplicand->used, mod->used, result->used); } /* Zero Pad everything if needed */ - ret = wc_MXC_MAA_zeroPad(multipler, multiplicand, exp, mod, result_tmp_ptr, + ret = wc_MXC_MAA_zeroPad(multiplier, multiplicand, exp, mod, result_tmp_ptr, clc, length); if (ret != 0) { MAX3266X_MSG("Zero Padding Failed"); @@ -635,7 +750,7 @@ int wc_MXC_MAA_math(mp_int* multipler, mp_int* multiplicand, mp_int* exp, /* Start Math And Cast to expect types for SDK */ MAX3266X_MSG("Starting Computation in MAA"); - ret = MXC_TPU_MAA_Compute(clc, (char *)(multipler->dp), + ret = MXC_TPU_MAA_Compute(clc, (char *)(multiplier->dp), (char *)(multiplicand->dp), (char *)(exp->dp), (char *)(mod->dp), (int *)(result_tmp_ptr->dp), @@ -655,7 +770,7 @@ int wc_MXC_MAA_math(mp_int* multipler, mp_int* multiplicand, mp_int* exp, } /* Copy tmp result if needed */ - if ((multipler == result) || (multiplicand == result) || (exp == result) || + 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 */ @@ -679,51 +794,51 @@ int wc_MXC_MAA_expmod(mp_int* base, mp_int* exp, mp_int* mod, WC_MXC_TPU_MAA_EXP); } -int wc_MXC_MAA_sqrmod(mp_int* multipler, mp_int* mod, mp_int* result) +int wc_MXC_MAA_sqrmod(mp_int* multiplier, mp_int* mod, mp_int* result) { mp_int multiplicand; 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(multipler, &multiplicand, NULL, mod, result, + return wc_MXC_MAA_math(multiplier, &multiplicand, NULL, mod, result, WC_MXC_TPU_MAA_SQ); } -int wc_MXC_MAA_mulmod(mp_int* multipler, mp_int* multiplicand, mp_int* mod, +int wc_MXC_MAA_mulmod(mp_int* multiplier, 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, + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, WC_MXC_TPU_MAA_MUL); } -int wc_MXC_MAA_sqrmulmod(mp_int* multipler, mp_int* multiplicand, +int wc_MXC_MAA_sqrmulmod(mp_int* multiplier, 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, + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, WC_MXC_TPU_MAA_SQMUL); } -int wc_MXC_MAA_addmod(mp_int* multipler, mp_int* multiplicand, mp_int* mod, +int wc_MXC_MAA_addmod(mp_int* multiplier, 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, + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, WC_MXC_TPU_MAA_ADD); } -int wc_MXC_MAA_submod(mp_int* multipler, mp_int* multiplicand, mp_int* mod, +int wc_MXC_MAA_submod(mp_int* multiplier, 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)) { + if ((mod->used < multiplier->used) || (mod->used < multiplicand->used)) { MAX3266X_MSG("HW Limitation: Defaulting back to software"); - return mxc_submod(multipler, multiplicand, mod, result); + return mxc_submod(multiplier, multiplicand, mod, result); } else { - return wc_MXC_MAA_math(multipler, multiplicand, NULL, mod, result, + return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, WC_MXC_TPU_MAA_SUB); } } @@ -807,7 +922,7 @@ int hw_exptmod(mp_int* base, mp_int* exp, mp_int* mod, mp_int* result) } -/* No mod function avaliable with hardware, however preform a submod */ +/* 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) { @@ -829,8 +944,7 @@ int hw_sqrmod(mp_int* base, mp_int* mod, mp_int* result) return wc_MXC_MAA_sqrmod(base, mod, result); } -#endif - +#endif /* MAX3266X_MATH */ #if defined(MAX3266X_RTC) /* Initialize the RTC */ @@ -880,6 +994,7 @@ void wc_MXC_RTC_GetRTCValue(int32_t (*rtcGetFunction)(uint32_t*), } /* Function to provide the current time as a double */ +/* Returns seconds and millisecond */ double wc_MXC_RTC_Time(void) { int32_t err; @@ -897,10 +1012,11 @@ double wc_MXC_RTC_Time(void) 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 */ \ No newline at end of file diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 44db748225..6bbb1c5305 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) @@ -1035,6 +1039,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) @@ -1066,6 +1072,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 +1087,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) { @@ -1150,6 +1159,7 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) 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 b7ee935f46..18adbbd84a 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -1965,6 +1965,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 */ @@ -2355,6 +2358,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) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 3b87dec5ca..5d3e9123b8 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -257,7 +257,7 @@ int wolfCrypt_Init(void) #if defined(MAX3266X_RTC) ret = wc_MXC_RTC_Init(); - if (ret != 0){ + if (ret != 0) { WOLFSSL_MSG("MXC RTC Init Failed"); return WC_HW_E; } diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x.h b/wolfssl/wolfcrypt/port/maxim/max3266x.h index 9c74ddef5d..bf578a229e 100644 --- a/wolfssl/wolfcrypt/port/maxim/max3266x.h +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -224,6 +224,33 @@ unsigned char hash[WOLFSSL_MAX_HASH_SIZE]; } wc_MXC_Sha; + #if !defined(NO_SHA) + typedef wc_MXC_Sha wc_Sha; + #define WC_SHA_TYPE_DEFINED + + /* 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) + typedef wc_MXC_Sha wc_Sha224; + #define WC_SHA224_TYPE_DEFINED + + /* 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) typedef wc_MXC_Sha wc_Sha256; #define WC_SHA256_TYPE_DEFINED @@ -236,7 +263,7 @@ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; - #endif + #endif /* NO_SHA256 */ WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Init(wc_MXC_Sha *hash); From fe7987f2419c7df1f2363badec3c2327c1bd669b Mon Sep 17 00:00:00 2001 From: night1rider Date: Mon, 5 Aug 2024 12:32:42 -0600 Subject: [PATCH 3/8] Adding SHA-384/512 support, Null Checks, RNG Health Test for HW, and MAA call update for MAX3266X Port. --- wolfcrypt/src/aes.c | 35 +++--- wolfcrypt/src/port/maxim/README.md | 38 +++--- wolfcrypt/src/port/maxim/max3266x.c | 146 ++++++++++++++++++++---- wolfcrypt/src/random.c | 10 ++ wolfcrypt/src/sha512.c | 33 ++++++ wolfssl/wolfcrypt/port/maxim/max3266x.h | 75 ++++++++---- wolfssl/wolfcrypt/sha512.h | 3 + 7 files changed, 267 insertions(+), 73 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index e28e8b59ba..7e212685fe 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -5412,16 +5412,23 @@ int wc_AesSetIV(Aes* aes, const byte* iv) int status; byte *iv; -#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + 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) + #endif + if (sz == 0) { return 0; + } iv = (byte*)aes->reg; - status = wc_AesGetKeySize(aes, &keySize); if (status != 0) { return status; @@ -5430,12 +5437,10 @@ int wc_AesSetIV(Aes* aes, const byte* iv) 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; } @@ -5447,16 +5452,23 @@ int wc_AesSetIV(Aes* aes, const byte* iv) byte *iv; byte temp_block[AES_BLOCK_SIZE]; -#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS + 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) + #endif + if (sz == 0) { return 0; + } iv = (byte*)aes->reg; - status = wc_AesGetKeySize(aes, &keySize); if (status != 0) { return status; @@ -5464,17 +5476,14 @@ int wc_AesSetIV(Aes* aes, const byte* iv) /* 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 */ diff --git a/wolfcrypt/src/port/maxim/README.md b/wolfcrypt/src/port/maxim/README.md index 17a66b692f..c3a6d4bb1b 100644 --- a/wolfcrypt/src/port/maxim/README.md +++ b/wolfcrypt/src/port/maxim/README.md @@ -41,30 +41,26 @@ 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`. +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 change this error check: +function you will need to this: ``` -// Check that we're performing a valid operation -if (clc >= 0x6) { - return E_INVALID; -} +MXC_SETFIELD(tpu->maa_ctrl, MXC_F_TPU_REVA_MAA_CTRL_CLC, clc); ``` to ``` -// Check that we're performing a valid operation -if (clc >= 0b1111) { - return E_INVALID; -} +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 -[here](https://github.com/analogdevicesinc/msdk/issues/1089) -if you want to know more details on the issue. +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 @@ -81,17 +77,21 @@ hardware. `#define MAX3266X_SHA`: +- SHA-1 +- SHA-224 - SHA-256 +- SHA-384 +- SHA-512 `#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` +- 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 diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c index 49e3fe2fdc..1e59a16bd8 100644 --- a/wolfcrypt/src/port/maxim/max3266x.c +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -360,16 +360,26 @@ int wc_MXC_TPU_SHA_GetDigest(wc_MXC_Sha *hash, unsigned char* digest, 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_SHA224 - case MXC_TPU_HASH_SHA224: - XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA224, WC_SHA224_DIGEST_SIZE); + #ifdef WOLFSSL_SHA384 + case MXC_TPU_HASH_SHA384: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA384, WC_SHA384_DIGEST_SIZE); break; - #endif /* WOLFSSL_SHA224 */ + #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; } @@ -517,6 +527,102 @@ WOLFSSL_API void wc_Sha256Free(wc_Sha256* sha256) #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 */ #if defined(MAX3266X_MATH) @@ -615,7 +721,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, return BAD_FUNC_ARG; } if ((result == NULL) || (multiplier == NULL) || (multiplicand == NULL) || - ((exp == NULL) && (clc == WC_MXC_TPU_MAA_EXP)) || (mod == NULL)) { + ((exp == NULL) && (clc == MXC_TPU_MAA_EXP)) || (mod == NULL)) { return BAD_FUNC_ARG; } @@ -630,7 +736,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, /* Check for invalid arguments befor padding */ switch ((char)clc) { - case WC_MXC_TPU_MAA_EXP: + 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); @@ -638,9 +744,9 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, return BAD_FUNC_ARG; } - /* Padd out rest of data if used != length to ensure no */ + /* Pad 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 != 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, @@ -649,11 +755,11 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, } /* 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: + 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); @@ -723,7 +829,7 @@ int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, return MP_VAL; } - if (clc == WC_MXC_TPU_MAA_EXP) { + if (clc == MXC_TPU_MAA_EXP) { length = wc_MXC_MAA_Largest(5, multiplier->used, multiplicand->used, exp->used, mod->used, result->used); } @@ -791,7 +897,7 @@ int wc_MXC_MAA_expmod(mp_int* base, mp_int* exp, mp_int* mod, multiplicand.used = mod->used; MAX3266X_MSG("Preparing exptmod MAA HW Call"); return wc_MXC_MAA_math(base, &multiplicand, exp, mod, result, - WC_MXC_TPU_MAA_EXP); + MXC_TPU_MAA_EXP); } int wc_MXC_MAA_sqrmod(mp_int* multiplier, mp_int* mod, mp_int* result) @@ -802,7 +908,7 @@ int wc_MXC_MAA_sqrmod(mp_int* multiplier, mp_int* mod, mp_int* result) multiplicand.used = mod->used; MAX3266X_MSG("Preparing sqrmod MAA HW Call"); return wc_MXC_MAA_math(multiplier, &multiplicand, NULL, mod, result, - WC_MXC_TPU_MAA_SQ); + MXC_TPU_MAA_SQ); } int wc_MXC_MAA_mulmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, @@ -810,7 +916,7 @@ int wc_MXC_MAA_mulmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, { MAX3266X_MSG("Preparing mulmod MAA HW Call"); return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, - WC_MXC_TPU_MAA_MUL); + MXC_TPU_MAA_MUL); } int wc_MXC_MAA_sqrmulmod(mp_int* multiplier, mp_int* multiplicand, @@ -818,7 +924,7 @@ int wc_MXC_MAA_sqrmulmod(mp_int* multiplier, mp_int* multiplicand, { MAX3266X_MSG("Preparing sqrmulmod MAA HW Call"); return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, - WC_MXC_TPU_MAA_SQMUL); + MXC_TPU_MAA_SQMUL); } int wc_MXC_MAA_addmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, @@ -826,7 +932,7 @@ int wc_MXC_MAA_addmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, { MAX3266X_MSG("Preparing addmod MAA HW Call"); return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, - WC_MXC_TPU_MAA_ADD); + MXC_TPU_MAA_ADD); } int wc_MXC_MAA_submod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, @@ -839,7 +945,7 @@ int wc_MXC_MAA_submod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, } else { return wc_MXC_MAA_math(multiplier, multiplicand, NULL, mod, result, - WC_MXC_TPU_MAA_SUB); + MXC_TPU_MAA_SUB); } } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 42e385af77..5f23203158 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3839,7 +3839,17 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) #elif defined(MAX3266X_RNG) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { + static int initDone = 0; (void)os; + if (initDone == 0) { + if(MXC_TRNG_HealthTest() != 0) { + #if defined(DEBUG_WOLFSSL) + WOLFSSL_MSG("TRNG HW Health Test Failed"); + #endif + return WC_HW_E; + } + initDone = 1; + } return wc_MXC_TRNG_Random(output, sz); } diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 77313f7a2a..fd9acc1e20 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) { @@ -1158,6 +1166,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 +1329,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 +1408,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) { @@ -1442,6 +1460,8 @@ void wc_Sha512Free(wc_Sha512* sha512) ForceZero(sha512, sizeof(*sha512)); } +#endif + #if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) \ && !defined(WOLFSSL_KCAPI_HASH) /* Apply SHA512 transformation to the data */ @@ -1560,6 +1580,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) @@ -1755,6 +1778,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; @@ -1813,6 +1840,7 @@ void wc_Sha384Free(wc_Sha384* sha384) ForceZero(sha384, sizeof(*sha384)); } +#endif #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 @@ -1824,6 +1852,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, @@ -2115,6 +2146,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) diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x.h b/wolfssl/wolfcrypt/port/maxim/max3266x.h index bf578a229e..5fa12a1be2 100644 --- a/wolfssl/wolfcrypt/port/maxim/max3266x.h +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -53,7 +53,9 @@ #if defined(MAX3266X_RNG) #include "trng.h" /* Provides TRNG Drivers */ - #define MXC_TPU_TRNG_Read TRNG_Read + #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 */ @@ -95,12 +97,12 @@ /* 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 + #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 @@ -134,22 +136,12 @@ #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 @@ -234,7 +226,6 @@ 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) @@ -248,7 +239,6 @@ 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) @@ -262,9 +252,52 @@ 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) + typedef wc_MXC_Sha wc_Sha384; + #define WC_SHA384_TYPE_DEFINED + + /* 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) + 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 + + /* 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, diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 4b2dd2a194..307c987fce 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 From 8f8b4e666593f4bdcd614c34bb35d1fb4998abec Mon Sep 17 00:00:00 2001 From: night1rider Date: Fri, 9 Aug 2024 14:19:00 -0600 Subject: [PATCH 4/8] Addressing Feedback, Adding Null Checks and Mutex Around TRNG --- wolfcrypt/src/aes.c | 18 +-- wolfcrypt/src/port/maxim/README.md | 4 + wolfcrypt/src/port/maxim/max3266x.c | 212 +++++++++++++++++++--------- 3 files changed, 162 insertions(+), 72 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 7e212685fe..f226156e6d 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2209,7 +2209,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. @@ -3187,7 +3188,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. @@ -5422,8 +5424,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv) return BAD_LENGTH_E; #else return BAD_FUNC_ARG; - } #endif + } if (sz == 0) { return 0; } @@ -5462,8 +5464,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv) return BAD_LENGTH_E; #else return BAD_FUNC_ARG; - } #endif + } if (sz == 0) { return 0; } @@ -11532,8 +11534,8 @@ int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) return status; } - status = wc_MXC_TPU_AesEncrypt(in, aes->reg, aes->key, MXC_TPU_MODE_ECB, - sz, out, keySize); + status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, sz, out, keySize); return status; } @@ -11552,8 +11554,8 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) return status; } - status = wc_MXC_TPU_AesDecrypt(in, aes->reg, aes->key, MXC_TPU_MODE_ECB, - sz, out, keySize); + status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key, + MXC_TPU_MODE_ECB, sz, out, keySize); return status; } diff --git a/wolfcrypt/src/port/maxim/README.md b/wolfcrypt/src/port/maxim/README.md index c3a6d4bb1b..2898c897cf 100644 --- a/wolfcrypt/src/port/maxim/README.md +++ b/wolfcrypt/src/port/maxim/README.md @@ -83,6 +83,10 @@ hardware. - 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): diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c index 1e59a16bd8..de293ea783 100644 --- a/wolfcrypt/src/port/maxim/max3266x.c +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -53,6 +53,7 @@ #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) @@ -85,7 +86,11 @@ int wc_MXC_TPU_Shutdown(void) /* using #define MAX3266X_VERBOSE */ int wc_MXC_error(int *ret) { - switch(*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; @@ -119,27 +124,44 @@ int wc_MXC_error(int *ret) #if defined(MAX3266X_RNG) - +/* Simple call to SDK's TRNG HW */ int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) { - if (MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TRNG) != 0) { + int status; + if (output == NULL) { + return BAD_FUNC_ARG; + } + status = wolfSSL_CryptHwMutexLock(); /* 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"); - return RNG_FAILURE_E; + status = RNG_FAILURE_E; } - /* void return function */ - MXC_TPU_TRNG_Read(MXC_TRNG, output, sz); - MAX3266X_MSG("TRNG Hardware Used"); - return 0; + wolfSSL_CryptHwMutexUnLock(); /* 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_CryptHwMutexLock(); MAX3266X_MSG("AES HW Encryption"); if (status != 0) { @@ -182,12 +204,16 @@ int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, return 0; } #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_CryptHwMutexLock(); if (status != 0) { return status; @@ -243,42 +269,48 @@ int wc_MXC_TPU_SHA_Init(wc_MXC_Sha *hash) 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; - if (size != (0 || NULL)) { - if ((hash == NULL) || (data == NULL)) { - return BAD_FUNC_ARG; + /* 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); } - 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; + 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); } - hash->msg = p; - hash->size = hash->used+size; + #else + p = XREALLOC(hash->msg, hash->used+size, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + #endif } - XMEMCPY(hash->msg+hash->used, data, size); - hash->used += size; - if (hash->msg == NULL) { - return BAD_FUNC_ARG; + 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; } @@ -287,16 +319,20 @@ 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_CryptHwMutexLock(); - if (wc_MXC_error(&status) != 0) { - + status = wolfSSL_CryptHwMutexLock(); /* Set Mutex **/ + if (status != 0) { /* Mutex Call Check */ return status; } MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TPU); @@ -304,7 +340,7 @@ int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, status = MXC_TPU_Hash_SHA((const char *)hash->msg, algo, hash->size, (char *)digest); MAX3266X_MSG("SHA HW Acceleration Used"); - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_CryptHwMutexUnLock(); /* Release Mutex */ if (wc_MXC_error(&status) != 0) { MAX3266X_MSG("SHA HW Error Occurred"); return status; @@ -314,15 +350,21 @@ int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, 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; } - XFREE(hash->msg, NULL, DYNAMIC_TYPE_TMP_BUFFER); status = wc_MXC_TPU_SHA_Init(hash); if (status != 0) { return status; @@ -330,6 +372,7 @@ int wc_MXC_TPU_SHA_Final(wc_MXC_Sha *hash, unsigned char* digest, 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) { @@ -341,8 +384,14 @@ int wc_MXC_TPU_SHA_Copy(wc_MXC_Sha* src, wc_MXC_Sha* dst) 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; @@ -353,8 +402,11 @@ void wc_MXC_TPU_SHA_Free(wc_MXC_Sha* hash) 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) { + 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); @@ -633,10 +685,9 @@ int wc_MXC_MAA_init(unsigned int len) int status; MAX3266X_MSG("Setting Hardware Mutex and Starting MAA"); status = wolfSSL_CryptHwMutexLock(); - if (status != 0) { - return status; + if (status == 0) { + status = MXC_TPU_MAA_Init(len); } - status = MXC_TPU_MAA_Init(len); return wc_MXC_error(&status); /* Return Status of Init */ } @@ -648,13 +699,10 @@ int wc_MXC_MAA_Shutdown(void) 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; + status = WC_HW_E; } - else if(wc_MXC_error(&status) != 0) { - return status; - } - wolfSSL_CryptHwMutexUnLock(); - return status; + wolfSSL_CryptHwMutexUnLock(); /* Always call Unlock in shutdown */ + return wc_MXC_error(&status); } /* Update used number for mp_int struct for results */ @@ -706,8 +754,6 @@ int wc_MXC_MAA_Fallback(unsigned int count, ...) 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, @@ -728,7 +774,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, /* 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){ + if (zero_tmp == NULL) { MAX3266X_MSG("NULL pointer found after XMALLOC call"); return WC_HW_E; } @@ -806,7 +852,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, - /* General Control Over MAA Hardware to handle all needed Cases */ +/* 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) @@ -815,6 +861,11 @@ int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, 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)) { @@ -871,7 +922,8 @@ int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, ret = wc_MXC_MAA_Shutdown(); if (ret != 0) { MAX3266X_MSG("HW Shutdown Failure"); - wolfSSL_CryptHwMutexUnLock(); + /* Shutdown will always call wolfSSL_CryptHwMutexUnLock(); */ + /* before returning */ return ret; } @@ -892,6 +944,9 @@ 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; @@ -903,6 +958,9 @@ int wc_MXC_MAA_expmod(mp_int* base, mp_int* exp, mp_int* mod, 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; @@ -914,6 +972,10 @@ int wc_MXC_MAA_sqrmod(mp_int* multiplier, mp_int* mod, mp_int* result) 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); @@ -922,6 +984,10 @@ int wc_MXC_MAA_mulmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, 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); @@ -930,6 +996,10 @@ int wc_MXC_MAA_sqrmulmod(mp_int* multiplier, mp_int* multiplicand, 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); @@ -938,6 +1008,10 @@ int wc_MXC_MAA_addmod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, 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"); @@ -953,6 +1027,10 @@ int wc_MXC_MAA_submod(mp_int* multiplier, mp_int* multiplicand, mp_int* mod, 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; @@ -1033,7 +1111,10 @@ int hw_exptmod(mp_int* base, mp_int* exp, mp_int* mod, mp_int* result) int hw_mod(mp_int* a, mp_int* mod, mp_int* result) { mp_int b; - if (wc_MXC_MAA_Fallback(2, a->used, mod->used) != 0){ + 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)); @@ -1043,6 +1124,9 @@ int hw_mod(mp_int* a, mp_int* mod, mp_int* 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; @@ -1060,29 +1144,29 @@ int wc_MXC_RTC_Init(void) 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; } - - if (MXC_RTC_Start() != E_NO_ERROR){ + /* 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; } @@ -1109,7 +1193,7 @@ double wc_MXC_RTC_Time(void) /* Retrieve sub-seconds from RTC */ wc_MXC_RTC_GetRTCValue((int32_t (*)(uint32_t*))MXC_RTC_GetSubSeconds, &rtc_subseconds, &err); - if (err != E_NO_ERROR){ + if (err != E_NO_ERROR) { return (double)err; } /* Retrieve seconds from RTC */ From a7ef54034451bda7180ae7b7e2251ac692d0fa1f Mon Sep 17 00:00:00 2001 From: night1rider Date: Fri, 23 Aug 2024 15:21:24 -0600 Subject: [PATCH 5/8] Making so hw mutex define is not needed --- wolfssl/wolfcrypt/wc_port.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 7e4567f961..7f39ce7266 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -422,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 From 1cb324affad7fa43c9bd648d3edab473bd295262 Mon Sep 17 00:00:00 2001 From: night1rider Date: Tue, 3 Sep 2024 14:26:49 -0600 Subject: [PATCH 6/8] Expanding mutexing and Adding in AES Callbacks for HW --- wolfcrypt/benchmark/benchmark.c | 8 +- wolfcrypt/src/aes.c | 52 +++- wolfcrypt/src/cryptocb.c | 4 + wolfcrypt/src/port/maxim/max3266x.c | 261 ++++++++++++++++-- wolfcrypt/src/random.c | 19 +- wolfcrypt/src/wc_port.c | 201 ++++++++++++++ wolfcrypt/test/test.c | 3 + wolfssl/wolfcrypt/aes.h | 5 + wolfssl/wolfcrypt/include.am | 3 +- .../wolfcrypt/port/maxim/max3266x-cryptocb.h | 70 +++++ wolfssl/wolfcrypt/port/maxim/max3266x.h | 27 +- wolfssl/wolfcrypt/wc_port.h | 68 +++++ 12 files changed, 689 insertions(+), 32 deletions(-) create mode 100644 wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 042f736469..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 diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index f226156e6d..1073c4e013 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -84,6 +84,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) #include +#ifdef WOLF_CRYPTO_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) @@ -2794,9 +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) +#if defined(MAX3266X_AES) word32 keySize; - #endif +#endif +#if defined(MAX3266X_CB) + int ret_cb; +#endif word32 r; if (aes == NULL) { @@ -2907,6 +2917,18 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt( 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); @@ -3556,9 +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) +#if defined(MAX3266X_AES) word32 keySize; - #endif +#endif +#if defined(MAX3266X_CB) + int ret_cb; +#endif word32 r; if (aes == NULL) { @@ -3643,6 +3668,19 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( } #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; @@ -4130,6 +4168,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) unsigned int i = 0; XMEMCPY(rk, key, keySz); +#ifdef MAX3266X_CB /* Copies needed values to use later if CB is used */ + XMEMCPY(aes->cb_key, key, keySz); +#endif #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \ !defined(MAX3266X_AES) @@ -4572,6 +4613,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #endif XMEMCPY(aes->key, userKey, keylen); +#ifdef MAX3266X_CB /* Copy Key for CB for use later if needed */ + XMEMCMP(aes->cb_key, userKey, keylen); +#endif #ifndef WC_AES_BITSLICED #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index d510bb4382..47c333cf03 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -56,6 +56,10 @@ #include #endif +#if defined (WOLFSSL_MAX3266X) || defined (WOLFSSL_MAX3266X_OLD) + #include +#endif + /* TODO: Consider linked list with mutex */ #ifndef MAX_CRYPTO_DEVID_CALLBACKS #define MAX_CRYPTO_DEVID_CALLBACKS 8 diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c index de293ea783..615af9fe50 100644 --- a/wolfcrypt/src/port/maxim/max3266x.c +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -42,6 +42,10 @@ #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 @@ -82,6 +86,85 @@ int wc_MXC_TPU_Shutdown(void) } +#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; +} + +/* 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: + /* return this to bypass HW and use SW */ + MAX3266X_MSG("Using MXC HW Callback:"); + ret = wc_MxcAesCryptoCb(info); /* Determine AES HW or SW */ + break; + 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) @@ -131,7 +214,7 @@ int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) if (output == NULL) { return BAD_FUNC_ARG; } - status = wolfSSL_CryptHwMutexLock(); /* Lock Mutex needed since */ + status = wolfSSL_HwRngMutexLock(); /* Lock Mutex needed since */ /* calling TPU init */ if (status != 0) { return status; @@ -146,7 +229,7 @@ int wc_MXC_TRNG_Random(unsigned char* output, unsigned int sz) MAX3266X_MSG("TRNG Device did not initialize"); status = RNG_FAILURE_E; } - wolfSSL_CryptHwMutexUnLock(); /* Unlock Mutex no matter status value */ + wolfSSL_HwRngMutexUnLock(); /* Unlock Mutex no matter status value */ return status; } #endif /* MAX3266X_RNG */ @@ -162,7 +245,7 @@ int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, if (in == NULL || iv == NULL || enc_key == NULL || out == NULL) { return BAD_FUNC_ARG; } - status = wolfSSL_CryptHwMutexLock(); + status = wolfSSL_HwAesMutexLock(); MAX3266X_MSG("AES HW Encryption"); if (status != 0) { MAX3266X_MSG("Hardware Mutex Failure"); @@ -192,17 +275,84 @@ int wc_MXC_TPU_AesEncrypt(const unsigned char* in, const unsigned char* iv, break; default: MAX3266X_MSG("AES HW ERROR: Length Not Supported"); - wolfSSL_CryptHwMutexUnLock(); - return WC_HW_E; - break; + wolfSSL_HwAesMutexUnLock(); + return BAD_FUNC_ARG; } - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwAesMutexUnLock(); if (status != 0) { MAX3266X_MSG("AES HW Acceleration Error Occurred"); return WC_HW_E; } - return 0; + 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->cb_key, + 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->cb_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; } +#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, @@ -214,7 +364,7 @@ int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, if (in == NULL || iv == NULL || dec_key == NULL || out == NULL) { return BAD_FUNC_ARG; } - status = wolfSSL_CryptHwMutexLock(); + status = wolfSSL_HwAesMutexLock(); if (status != 0) { return status; } @@ -242,17 +392,86 @@ int wc_MXC_TPU_AesDecrypt(const unsigned char* in, const unsigned char* iv, break; default: MAX3266X_MSG("AES HW ERROR: Length Not Supported"); - wolfSSL_CryptHwMutexUnLock(); - return WC_HW_E; - break; + wolfSSL_HwAesMutexUnLock(); + return BAD_FUNC_ARG; } - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwAesMutexUnLock(); if (status != 0) { MAX3266X_MSG("AES HW Acceleration Error Occurred"); return WC_HW_E; } - return 0; + 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->cb_key, + 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->cb_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_CBC */ +#endif /* WOLF_CRYPTO_CB */ #endif /* HAVE_AES_DECRYPT */ #endif /* MAX3266X_AES */ @@ -331,7 +550,7 @@ int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, } /* False Case where msg needs to be processed */ else if (status == 0) { - status = wolfSSL_CryptHwMutexLock(); /* Set Mutex **/ + status = wolfSSL_HwHashMutexLock(); /* Set Mutex */ if (status != 0) { /* Mutex Call Check */ return status; } @@ -340,7 +559,7 @@ int wc_MXC_TPU_SHA_GetHash(wc_MXC_Sha *hash, unsigned char* digest, status = MXC_TPU_Hash_SHA((const char *)hash->msg, algo, hash->size, (char *)digest); MAX3266X_MSG("SHA HW Acceleration Used"); - wolfSSL_CryptHwMutexUnLock(); /* Release Mutex */ + wolfSSL_HwHashMutexUnLock(); /* Release Mutex */ if (wc_MXC_error(&status) != 0) { MAX3266X_MSG("SHA HW Error Occurred"); return status; @@ -684,7 +903,7 @@ int wc_MXC_MAA_init(unsigned int len) { int status; MAX3266X_MSG("Setting Hardware Mutex and Starting MAA"); - status = wolfSSL_CryptHwMutexLock(); + status = wolfSSL_HwPkMutexLock(); if (status == 0) { status = MXC_TPU_MAA_Init(len); } @@ -701,7 +920,7 @@ int wc_MXC_MAA_Shutdown(void) /* This is returned when MAA cannot stop */ status = WC_HW_E; } - wolfSSL_CryptHwMutexUnLock(); /* Always call Unlock in shutdown */ + wolfSSL_HwPkMutexUnLock(); /* Always call Unlock in shutdown */ return wc_MXC_error(&status); } @@ -901,7 +1120,7 @@ int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, ret = wc_MXC_MAA_init(length*sizeof(mp_digit)*8); if (ret != 0) { MAX3266X_MSG("HW Init Failed"); - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwPkMutexUnLock(); return ret; } @@ -915,14 +1134,14 @@ int wc_MXC_MAA_math(mp_int* multiplier, mp_int* multiplicand, mp_int* exp, MAX3266X_MSG("MAA Finished Computation"); if (wc_MXC_error(&ret) != 0) { MAX3266X_MSG("HW Computation Error"); - wolfSSL_CryptHwMutexUnLock(); + wolfSSL_HwPkMutexUnLock(); return ret; } ret = wc_MXC_MAA_Shutdown(); if (ret != 0) { MAX3266X_MSG("HW Shutdown Failure"); - /* Shutdown will always call wolfSSL_CryptHwMutexUnLock(); */ + /* Shutdown will always call wolfSSL_HwPkMutexUnLock(); */ /* before returning */ return ret; } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 5f23203158..d6c32f6923 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3839,15 +3839,30 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 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) { - #if defined(DEBUG_WOLFSSL) + #ifdef DEBUG_WOLFSSL WOLFSSL_MSG("TRNG HW Health Test Failed"); - #endif + #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); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 5d3e9123b8..772231ba0d 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -46,6 +46,9 @@ #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) #include +#ifdef WOLF_CRYPTO_CB + #include +#endif #endif #ifdef WOLFSSL_PSOC6_CRYPTO @@ -255,6 +258,14 @@ 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) { @@ -1362,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 */ /* ---------------------------------------------------------------------------*/ 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/aes.h b/wolfssl/wolfcrypt/aes.h index cf08ec3a5c..eab2ea5b52 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -263,6 +263,11 @@ struct Aes { word32 rounds; #ifdef WC_C_DYNAMIC_FALLBACK word32 key_C_fallback[60]; +#endif +#if (defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ + defined(WOLF_CRYPTO_CB) + /* Need backup key for MXC CB */ + word32 cb_key[60]; #endif int keylen; diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 490dadd9a0..d091946c0c 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -117,7 +117,8 @@ noinst_HEADERS+= \ 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/maxim/max3266x.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..371af11ed0 --- /dev/null +++ b/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h @@ -0,0 +1,70 @@ +/* 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 +#ifndef MAX_CRYPTO_DEVID_CALLBACKS + #define MAX_CRYPTO_DEVID_CALLBACKS WOLFSSL_MAX3266X_DEVID +#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 */ + +#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 index 5fa12a1be2..39c79b9c08 100644 --- a/wolfssl/wolfcrypt/port/maxim/max3266x.h +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -41,6 +41,21 @@ #define MAX3266X_MATH #endif +/* Some extra conditions when using callbacks */ +#if defined(WOLF_CRYPTO_CB) + #define MAX3266X_CB +#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 */ @@ -198,14 +213,15 @@ 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 +#endif /* HAVE_AES_DECRYPT */ +#endif /* MAX3266X_AES */ #ifdef MAX3266X_SHA @@ -214,6 +230,13 @@ unsigned int used; unsigned int size; unsigned char hash[WOLFSSL_MAX_HASH_SIZE]; + #ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; /* generic crypto callback context */ + #endif + #ifdef WOLFSSL_HASH_FLAGS + unsigned int flags; /* enum wc_HashFlags in hash.h */ + #endif } wc_MXC_Sha; #if !defined(NO_SHA) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 7f39ce7266..58aba6becc 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -448,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 + int wolfSSL_HwRngMutexInit(void); + int wolfSSL_HwRngMutexLock(void); + 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 + int wolfSSL_HwAesMutexInit(void); + int wolfSSL_HwAesMutexLock(void); + 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 + int wolfSSL_HwHashMutexInit(void); + int wolfSSL_HwHashMutexLock(void); + 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 + int wolfSSL_HwPkMutexInit(void); + int wolfSSL_HwPkMutexLock(void); + 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); From 9881edfabe6d439b85210ce3be058fdcc021f00d Mon Sep 17 00:00:00 2001 From: ZackLabPC Date: Fri, 13 Sep 2024 17:40:18 -0600 Subject: [PATCH 7/8] Crypto Callback Support for ARM ASM: AES-ECB/CBC, SHA-1/256/384/512 + Fix SP SHA CB Bug --- wolfcrypt/src/aes.c | 8 +- wolfcrypt/src/cryptocb.c | 5 - wolfcrypt/src/port/arm/armv8-aes.c | 146 ++++++++++++++++- wolfcrypt/src/port/arm/armv8-sha256.c | 60 ++++++- wolfcrypt/src/port/arm/armv8-sha512.c | 108 ++++++++++++- wolfcrypt/src/port/maxim/README.md | 33 +++- wolfcrypt/src/port/maxim/max3266x.c | 147 ++++++++++++++++-- wolfcrypt/src/sha.c | 17 ++ wolfcrypt/src/sha256.c | 21 ++- wolfcrypt/src/sha512.c | 35 +++++ wolfssl/wolfcrypt/aes.h | 5 - .../wolfcrypt/port/maxim/max3266x-cryptocb.h | 11 +- wolfssl/wolfcrypt/port/maxim/max3266x.h | 52 ++++--- wolfssl/wolfcrypt/sha.h | 3 + wolfssl/wolfcrypt/sha256.h | 3 + wolfssl/wolfcrypt/sha512.h | 3 + 16 files changed, 588 insertions(+), 69 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 1073c4e013..4c9a8d1811 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -84,7 +84,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD) #include -#ifdef WOLF_CRYPTO_CB +#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 @@ -4168,9 +4168,6 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) unsigned int i = 0; XMEMCPY(rk, key, keySz); -#ifdef MAX3266X_CB /* Copies needed values to use later if CB is used */ - XMEMCPY(aes->cb_key, key, keySz); -#endif #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \ !defined(MAX3266X_AES) @@ -4613,9 +4610,6 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #endif XMEMCPY(aes->key, userKey, keylen); -#ifdef MAX3266X_CB /* Copy Key for CB for use later if needed */ - XMEMCMP(aes->cb_key, userKey, keylen); -#endif #ifndef WC_AES_BITSLICED #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 47c333cf03..23355493e9 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -55,11 +55,6 @@ #ifdef WOLFSSL_CAAM #include #endif - -#if defined (WOLFSSL_MAX3266X) || defined (WOLFSSL_MAX3266X_OLD) - #include -#endif - /* TODO: Consider linked list with mutex */ #ifndef MAX_CRYPTO_DEVID_CALLBACKS #define MAX_CRYPTO_DEVID_CALLBACKS 8 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 2898c897cf..3919ffd0f9 100644 --- a/wolfcrypt/src/port/maxim/README.md +++ b/wolfcrypt/src/port/maxim/README.md @@ -34,9 +34,10 @@ this can be done by adding any combination of these defines: #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. +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 @@ -97,6 +98,32 @@ like RSA and ECC key generation): - 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 diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c index 615af9fe50..6dc324df0e 100644 --- a/wolfcrypt/src/port/maxim/max3266x.c +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -134,6 +134,112 @@ int wc_MxcAesCryptoCb(wc_CryptoInfo* info) 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) @@ -151,10 +257,15 @@ int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) switch (info->algo_type) { case WC_ALGO_TYPE_CIPHER: - /* return this to bypass HW and use SW */ - MAX3266X_MSG("Using MXC HW Callback:"); + 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 */ @@ -305,7 +416,7 @@ int wc_MxcCb_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) return status; } - status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->cb_key, + status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->devKey, MXC_TPU_MODE_ECB, sz, out, keySize); return status; @@ -341,7 +452,7 @@ int wc_MxcCb_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) return status; } - status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->cb_key, + status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->devKey, MXC_TPU_MODE_CBC, sz, out, (unsigned int)keySize); /* store iv for next call */ @@ -421,7 +532,7 @@ int wc_MxcCb_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) return status; } - status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->cb_key, + status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->devKey, MXC_TPU_MODE_ECB, sz, out, keySize); return status; @@ -460,7 +571,7 @@ int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) /* 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->cb_key, + status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->devKey, MXC_TPU_MODE_CBC, sz, out, keySize); @@ -475,7 +586,7 @@ int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #endif /* HAVE_AES_DECRYPT */ #endif /* MAX3266X_AES */ -#if defined(MAX3266X_SHA) +#if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) int wc_MXC_TPU_SHA_Init(wc_MXC_Sha *hash) { @@ -521,7 +632,7 @@ int wc_MXC_TPU_SHA_Update(wc_MXC_Sha *hash, const unsigned char* data, #endif } if (p == NULL) { - return -1; + return MEMORY_E; } hash->msg = p; hash->size = hash->used+size; @@ -599,7 +710,16 @@ int wc_MXC_TPU_SHA_Copy(wc_MXC_Sha* src, wc_MXC_Sha* dst) } dst->used = src->used; dst->size = src->size; - XMEMCPY(dst->hash, src->hash, sizeof(dst->hash)); + 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; } @@ -659,6 +779,7 @@ int wc_MXC_TPU_SHA_GetDigest(wc_MXC_Sha *hash, unsigned char* digest, return 0; /* False */ } +#ifndef MAX3266X_SHA_CB #if !defined(NO_SHA) WOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) @@ -893,8 +1014,8 @@ WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha512) } #endif /* WOLFSSL_SHA512 */ - -#endif /* MAX3266X_SHA */ +#endif /* !MAX3266X_SHA_CB*/ +#endif /* MAX3266X_SHA || MAX3266X_SHA_CB */ #if defined(MAX3266X_MATH) @@ -995,7 +1116,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand, DYNAMIC_TYPE_TMP_BUFFER); if (zero_tmp == NULL) { MAX3266X_MSG("NULL pointer found after XMALLOC call"); - return WC_HW_E; + return MEMORY_E; } XMEMSET(zero_tmp, 0x00, multiplier->size*sizeof(mp_digit)); @@ -1428,4 +1549,4 @@ double wc_MXC_RTC_Time(void) #endif /* MAX3266X_RTC */ -#endif /* WOLFSSL_MAX32665 || WOLFSSL_MAX32666 */ \ No newline at end of file +#endif /* WOLFSSL_MAX32665 || WOLFSSL_MAX32666 */ diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 6bbb1c5305..78ce918e26 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -564,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 */ @@ -1057,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 @@ -1153,6 +1163,13 @@ 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 diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 18adbbd84a..c9c3b100bb 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -279,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 @@ -1096,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 @@ -2246,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 */ @@ -2547,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 fd9acc1e20..7f3e745c60 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -773,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); } @@ -1454,6 +1460,10 @@ 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 */ @@ -1759,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; @@ -1837,6 +1854,10 @@ void wc_Sha384Free(wc_Sha384* sha384) } #endif +#ifdef MAX3266X_SHA_CB + wc_MXC_TPU_SHA_Free(&(sha384->mxcCtx)); +#endif + ForceZero(sha384, sizeof(*sha384)); } @@ -1958,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; } @@ -2247,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/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index eab2ea5b52..cf08ec3a5c 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -263,11 +263,6 @@ struct Aes { word32 rounds; #ifdef WC_C_DYNAMIC_FALLBACK word32 key_C_fallback[60]; -#endif -#if (defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ - defined(WOLF_CRYPTO_CB) - /* Need backup key for MXC CB */ - word32 cb_key[60]; #endif int keylen; diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h b/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h index 371af11ed0..e25dba7bb8 100644 --- a/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h +++ b/wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h @@ -24,13 +24,9 @@ #if (defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)) && \ defined(WOLF_CRYPTO_CB) - #ifndef WOLFSSL_MAX3266X_DEVID #define WOLFSSL_MAX3266X_DEVID 9 #endif -#ifndef MAX_CRYPTO_DEVID_CALLBACKS - #define MAX_CRYPTO_DEVID_CALLBACKS WOLFSSL_MAX3266X_DEVID -#endif #define WC_USE_DEVID WOLFSSL_MAX3266X_DEVID #include #include @@ -62,6 +58,13 @@ #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 diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x.h b/wolfssl/wolfcrypt/port/maxim/max3266x.h index 39c79b9c08..10c1188b44 100644 --- a/wolfssl/wolfcrypt/port/maxim/max3266x.h +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -30,20 +30,31 @@ #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 - #define MAX3266X_SHA - #define MAX3266X_ECDSA - #define MAX3266X_MATH -#endif - -/* Some extra conditions when using callbacks */ -#if defined(WOLF_CRYPTO_CB) - #define MAX3266X_CB + #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 */ @@ -92,7 +103,7 @@ #define MXC_TPU_Cipher_AES_Decrypt TPU_AES_Decrypt #endif - #if defined(MAX3266X_SHA) + #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 @@ -141,7 +152,7 @@ #include "trng.h" /* Provides Drivers for TRNG */ #endif #if defined(MAX3266X_AES) || defined(MAX3266X_SHA) || \ - defined(MAX3266X_ECDSA) || defined(MAX3266X_RSA) || \ + defined(MAX3266X_MATH) || defined(MAX3266X_RSA) || \ defined(MAX3266X_RNG) #include "tpu.h" /* SDK Drivers for the TPU unit */ /* Handles AES, SHA, and */ @@ -223,25 +234,22 @@ #endif /* HAVE_AES_DECRYPT */ #endif /* MAX3266X_AES */ -#ifdef MAX3266X_SHA +#if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) typedef struct { unsigned char *msg; unsigned int used; unsigned int size; - unsigned char hash[WOLFSSL_MAX_HASH_SIZE]; - #ifdef WOLF_CRYPTO_CB - int devId; - void* devCtx; /* generic crypto callback context */ - #endif #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 */ @@ -252,8 +260,10 @@ #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 */ @@ -265,8 +275,10 @@ #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 */ @@ -278,8 +290,10 @@ #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 */ @@ -293,10 +307,12 @@ #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 @@ -339,7 +355,7 @@ MXC_TPU_HASH_TYPE algo); -#endif +#endif /* defined(MAX3266X_SHA) && !defined(WOLF_CRYPTO_CB) */ #if defined(MAX3266X_MATH) #define WOLFSSL_USE_HW_MP @@ -369,4 +385,4 @@ #endif #endif /* WOLFSSL_MAX32665 || WOLFSSL_MAX32666 */ -#endif /* _WOLFPORT_MAX3266X_H_ */ \ No newline at end of file +#endif /* _WOLFPORT_MAX3266X_H_ */ diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 0e05823022..dd9d8b90ac 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -163,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 311bb31273..c435cf061c 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -213,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 307c987fce..9bcebdc62a 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -188,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 From 1ffcf4000b19754b04d298439e88da69d2185c48 Mon Sep 17 00:00:00 2001 From: ZackLabPC Date: Fri, 20 Sep 2024 15:21:27 -0600 Subject: [PATCH 8/8] Making HW Mutex Functions Private Api --- wolfssl/wolfcrypt/wc_port.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 58aba6becc..cb8d0f732d 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -438,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 */ @@ -474,9 +474,9 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); /* to using the generic wolfSSL_CryptHwMutex */ #if (!defined(NO_RNG_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ WOLFSSL_CRYPT_HW_MUTEX - int wolfSSL_HwRngMutexInit(void); - int wolfSSL_HwRngMutexLock(void); - int wolfSSL_HwRngMutexUnLock(void); + 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 @@ -485,9 +485,9 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); #if (!defined(NO_AES_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ WOLFSSL_CRYPT_HW_MUTEX - int wolfSSL_HwAesMutexInit(void); - int wolfSSL_HwAesMutexLock(void); - int wolfSSL_HwAesMutexUnLock(void); + 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 @@ -496,9 +496,9 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); #if (!defined(NO_HASH_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ WOLFSSL_CRYPT_HW_MUTEX - int wolfSSL_HwHashMutexInit(void); - int wolfSSL_HwHashMutexLock(void); - int wolfSSL_HwHashMutexUnLock(void); + 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 @@ -507,9 +507,9 @@ WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); #if (!defined(NO_PK_MUTEX) && defined(WOLFSSL_ALGO_HW_MUTEX)) && \ WOLFSSL_CRYPT_HW_MUTEX - int wolfSSL_HwPkMutexInit(void); - int wolfSSL_HwPkMutexLock(void); - int wolfSSL_HwPkMutexUnLock(void); + 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