diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 5dfec3714..dc693883a 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -125,6 +125,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/Renesas/renesas_sce_aes.c \ wolfcrypt/src/port/Renesas/renesas_sce_sha.c \ wolfcrypt/src/port/Renesas/renesas_common.c \ + wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c \ + wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c \ wolfcrypt/src/port/Renesas/README.md \ wolfcrypt/src/port/cypress/psoc6_crypto.c diff --git a/wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c b/wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c new file mode 100644 index 000000000..170ebb5e4 --- /dev/null +++ b/wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c @@ -0,0 +1,443 @@ +/* renesas_rx64_hw_sha.c + * + * Contributed by Johnson Controls Tyco IP Holdings LLP. + * + * Use of this Software is subject to the GPLv2 License + * + * 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 + */ +#include +#include + +#ifdef HAVE_CONFIG_H + #include +#endif +#include + +#if !defined(NO_SHA) || !defined(NO_SHA256) + +#include + +#if defined(WOLFSSL_RENESAS_RX64_HASH) + +#include +#include + +#include + +typedef union +{ + R_sha1 sha1; + R_sha224 sha224; + R_sha256 sha256; +} R_Sha_Data; + +/** +Default SHA Hash Data When Input Msg Buffers are NULL. + +The source of this data can be obtained from a simple python +program that requests the hash of an empty input argument. +Example: +import hashlib +print("SHA default/empty hash values") +print(f"SHA1 {hashlib.sha1(b'').hexdigest()}") +print(f"SHA224 {hashlib.sha224(b'').hexdigest()}") +print(f"SHA256 {hashlib.sha256(b'').hexdigest()}") + +OR + +The following website also provide data for these hashes when +an empty buffer is given as input +https://www.di-mgt.com.au/sha_testvectors.html +**/ + +static byte const DefaultShaHashData[] = +{ + 0xDA, 0x39, 0xA3, 0xEE, 0x5E, 0x6B, 0x4B, 0x0D, + 0x32, 0x55, 0xBF, 0xEF, 0x95, 0x60, 0x18, 0x90, + 0xAF, 0xD8, 0x07, 0x09 +}; + +static byte const DefaultSha224HashData[] = +{ + 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 +}; + +static byte const DefaultSha256HashData[] = +{ + 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 +}; + +/** + * @brief Calculate a SHA hash using the RX64 SHA subsystem. + * + * @param[in] data buffer with data to sha + * @param[in] len length of data + * @param[out] out Output buffer to store sha result in + * @param[in] sha_type Sha type to calculate, from RX64_SHA_TYPE + * @return int R_PROCESS_COMPLETE (0) on success, see r_sha.h for failure codes. + */ +int RX64_ShaCalc(byte* data, word32 len, byte* out, word32 sha_type) +{ + int ret; + uint8_t flag = R_SHA_INIT; + word32 index = 0; + uint16_t chunk_length; + R_Sha_Data work_sha; + + if (data == NULL || len == 0 || + out == NULL || sha_type >= NUM_RX64_SHA_TYPES) + { + return BAD_FUNC_ARG; + } + + XMEMSET(&work_sha, 0, sizeof(work_sha)); + + rx64_hw_lock(); + do { + /* + The hardware functions can only accept UINT16_MAX bytes at a time. + To work around this break the buffer up into chunks and pass the + R_SHA_FINISH flag with the last chunk. + */ + if (len - index <= UINT16_MAX) { + flag = flag | R_SHA_FINISH; + chunk_length = len - index; + } else { + chunk_length = UINT16_MAX; + } + /* Based on the hash type call the correct hardware function. */ + if (sha_type == RX64_SHA1) { + ret = R_Sha1_HashDigest(&data[index], out, chunk_length, flag, + &work_sha.sha1); + } else if (sha_type == RX64_SHA224) { + ret = R_Sha224_HashDigest(&data[index], out, chunk_length, flag, + &work_sha.sha224); + } else if (sha_type == RX64_SHA256) { + ret = R_Sha256_HashDigest(&data[index], out, chunk_length, flag, + &work_sha.sha256); + } + if (ret != R_PROCESS_COMPLETE) { + /* On failure break, unlock hardware, return error. */ + break; + } + index += chunk_length; + flag = R_SHA_ADD; + } while (index < len); + + rx64_hw_unlock(); + return ret; +} + +/** + * @brief Free a hash for use with the RX64 SHA subsystem. + * + * @param[in] hash The hash to free + */ +static void RX64_HashFree(wolfssl_RX64_HW_Hash* hash) +{ + if (hash == NULL) + return; + + if (hash->msg != NULL) { + XFREE(hash->msg, hash->heap, DYNAMIC_TYPE_TMP_BUFFER); + hash->msg = NULL; + } +} + +/** + * @brief Initialize a hash for use with the RX64 SHA subsystem. + * + * @param[in] hash The hash to initialize + * @param[in] heap Optional pointer to memory to use. + * @param devId Unused + * @param[in] sha_type The SHA type for this hash + * @return int 0 on success, BAD_FUNC_ARG on failure + */ +static int RX64_HashInit(wolfssl_RX64_HW_Hash* hash, void* heap, int devId, + word32 sha_type) +{ + if (hash == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + XMEMSET(hash, 0, sizeof(wolfssl_RX64_HW_Hash)); + + hash->heap = heap; + hash->len = 0; + hash->used = 0; + hash->msg = NULL; + hash->sha_type = sha_type; + + return 0; +} + +/** + * @brief Add data to the hash with the RX64 SHA subsystem. + * + * Note that do to the limitations in the RX64 hardware + * and it's inability to save the current state, + * this function actually just adds the data to a buffer + * that will then be processed when calling HashFinal or HashGet + * + * @param[in] hash Hash structure + * @param[in] data data to hash + * @param[in] sz size of the data + * @return int 0 on success, BAD_FUNC_ARG or MEMORY_E on failure + */ +static int RX64_HashUpdate(wolfssl_RX64_HW_Hash* hash, + const byte* data, word32 sz) +{ + if (hash == NULL || (sz > 0 && data == NULL)) { + return BAD_FUNC_ARG; + } + + if (hash->len < hash->used + sz) { + if (hash->msg == NULL) { + hash->msg = (byte*)XMALLOC(hash->used + sz, hash->heap, + DYNAMIC_TYPE_TMP_BUFFER); + } else { + byte* pt = (byte*)XREALLOC(hash->msg, hash->used + sz, hash->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pt == NULL) { + return MEMORY_E; + } + hash->msg = pt; + } + if (hash->msg == NULL) { + return MEMORY_E; + } + hash->len = hash->used + sz; + } + XMEMCPY(hash->msg + hash->used, data , sz); + hash->used += sz; + + return 0; +} + +/** + * @brief Calculate hash value with the RX64 SHA subsystem and reset the hash. + * + * @param[in] hash Structure containing the information on what to hash + * @param[out] out Sha hash + * @retval int R_PROCESS_COMPLETE (0) on success. + * @retval int BAD_FUNC_ARG or see r_sha.h on failure. + */ +static int RX64_HashFinal(wolfssl_RX64_HW_Hash* hash, byte* out) +{ + int ret = R_PROCESS_COMPLETE; + void* heap; + + if (hash == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + if (hash->sha_type != RX64_SHA1 && + hash->sha_type != RX64_SHA224 && + hash->sha_type != RX64_SHA256) + { + return BAD_FUNC_ARG; + } + + heap = hash->heap; + + /* + RX64 HW SHA operations considers empty msgs to be an error, + though some wolfSSL operations expects to have successful SHA operations on + empty incoming buffers (e.g DeriveHandshakeSecret()). + Thus we must support the expected default SHA hash data for this operation + since TLS decrypt operations expect a specific SW Hash to be used when the + input buffer was empty/NULL. + */ + if ((hash->msg == NULL) && (hash->len == 0) && (hash->used == 0)) + { + if (hash->sha_type == RX64_SHA1) + { + XMEMCPY(out, DefaultShaHashData, sizeof(DefaultShaHashData)); + } + else if (hash->sha_type == RX64_SHA224) + { + XMEMCPY(out, DefaultSha224HashData, sizeof(DefaultSha224HashData)); + } + else if (hash->sha_type == RX64_SHA256) + { + XMEMCPY(out, DefaultSha256HashData, sizeof(DefaultSha256HashData)); + } + } + else + { + /* Utilize RX64 SHA HW Acceleration for normal SHA operations. */ + ret = RX64_ShaCalc(hash->msg, hash->len, out, hash->sha_type); + if (ret != R_PROCESS_COMPLETE) + { + return ret; + } + } + + RX64_HashFree(hash); + return RX64_HashInit(hash, heap, 0, hash->sha_type); +} + +/** + * @brief Calculate hash value with the RX64 SHA subsystem. + * + * @param[in] hash Structure containing the information on what to hash + * @param[out] out Sha hash + * @retval int R_PROCESS_COMPLETE (0) on success. + * @retval int BAD_FUNC_ARG or see r_sha.h on failure. + */ +static int RX64_HashGet(wolfssl_RX64_HW_Hash* hash, byte* out) +{ + int ret; + + if (hash == NULL || out == NULL) { + return BAD_FUNC_ARG; + } + if (hash->sha_type != RX64_SHA1 && + hash->sha_type != RX64_SHA224 && + hash->sha_type != RX64_SHA256) + { + return BAD_FUNC_ARG; + } + + ret = RX64_ShaCalc(hash->msg, hash->len, out, hash->sha_type); + if (ret != R_PROCESS_COMPLETE) { + return ret; + } + + return 0; +} + +/** + * @brief Copy a hash for use with the RX64 SHA subsystem. + * + * @param[in] src Source hash structure + * @param[out] dst Destination hash structure + * @return int 0 on success, BAD_FUNC_ARG on failure + */ +static int RX64_HashCopy(wolfssl_RX64_HW_Hash* src, wolfssl_RX64_HW_Hash* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + + XMEMCPY(dst, src, sizeof(wolfssl_RX64_HW_Hash)); + + if (src->len > 0 && src->msg != NULL) { + dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) { + return MEMORY_E; + } + XMEMCPY(dst->msg, src->msg, src->len); + } + + return 0; +} + +/* WolfCrypt wrapper function for RX64 SHA1 Init */ +int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) +{ + return RX64_HashInit((wolfssl_RX64_HW_Hash*)sha, heap, devId, RX64_SHA1); +} +/* WolfCrypt wrapper function for RX64 SHA1 Update */ +int wc_ShaUpdate(wc_Sha* sha, const byte* in, word32 sz) +{ + return RX64_HashUpdate((wolfssl_RX64_HW_Hash*)sha, in, sz); +} +/* WolfCrypt wrapper function for RX64 SHA1 Final */ +int wc_ShaFinal(wc_Sha* sha, byte* hash) +{ + return RX64_HashFinal((wolfssl_RX64_HW_Hash*)sha, hash); +} +/* WolfCrypt wrapper function for RX64 SHA1 Get */ +int wc_ShaGetHash(wc_Sha* sha, byte* hash) +{ + return RX64_HashGet((wolfssl_RX64_HW_Hash*)sha, hash); +} +/* WolfCrypt wrapper function for RX64 SHA1 Copy */ +int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) +{ + return RX64_HashCopy((wolfssl_RX64_HW_Hash*)src, (wolfssl_RX64_HW_Hash*)dst); +} + +#if defined(WOLFSSL_SHA224) +#include + +/* WolfCrypt wrapper function for RX64 SHA224 Init */ +int wc_InitSha224_ex(wc_Sha224* sha, void* heap, int devId) +{ + return RX64_HashInit((wolfssl_RX64_HW_Hash*)sha, heap, devId, RX64_SHA224); +} +/* WolfCrypt wrapper function for RX64 SHA224 Update */ +int wc_Sha224Update(wc_Sha224* sha, const byte* in, word32 sz) +{ + return RX64_HashUpdate((wolfssl_RX64_HW_Hash*)sha, in, sz); +} +/* WolfCrypt wrapper function for RX64 SHA224 Final */ +int wc_Sha224Final(wc_Sha224* sha, byte* hash) +{ + return RX64_HashFinal((wolfssl_RX64_HW_Hash*)sha, hash); +} +/* WolfCrypt wrapper function for RX64 SHA224 Get */ +int wc_Sha224GetHash(wc_Sha224* sha, byte* hash) +{ + return RX64_HashGet((wolfssl_RX64_HW_Hash*)sha, hash); +} +/* WolfCrypt wrapper function for RX64 SHA224 Copy */ +int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst) +{ + return RX64_HashCopy((wolfssl_RX64_HW_Hash*)src, (wolfssl_RX64_HW_Hash*)dst); +} +#endif /* WOLFSSL_SHA224 */ + +#if !defined(NO_SHA256) +#include + +/* WolfCrypt wrapper function for RX64 SHA256 Init */ +int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId) +{ + return RX64_HashInit((wolfssl_RX64_HW_Hash*)sha, heap, devId, RX64_SHA256); +} +/* WolfCrypt wrapper function for RX64 SHA256 Update */ +int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) +{ + return RX64_HashUpdate((wolfssl_RX64_HW_Hash*)sha, in, sz); +} +/* WolfCrypt wrapper function for RX64 SHA256 Final */ +int wc_Sha256Final(wc_Sha256* sha, byte* hash) +{ + return RX64_HashFinal((wolfssl_RX64_HW_Hash*)sha, hash); +} +/* WolfCrypt wrapper function for RX64 SHA256 Get */ +int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) +{ + return RX64_HashGet((wolfssl_RX64_HW_Hash*)sha, hash); +} +/* WolfCrypt wrapper function for RX64 SHA256 Copy */ +int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) +{ + return RX64_HashCopy((wolfssl_RX64_HW_Hash*)src, (wolfssl_RX64_HW_Hash*)dst); +} +#endif /* !NO_SHA256 */ +#endif /* WOLFSSL_RENESAS_RX64_HASH */ +#endif /* #if !defined(NO_SHA) || !defined(NO_SHA256) */ diff --git a/wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c b/wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c new file mode 100644 index 000000000..2d995d99f --- /dev/null +++ b/wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c @@ -0,0 +1,106 @@ +/* renesas_rx64_hw_util.c + * + * Contributed by Johnson Controls Tyco IP Holdings LLP. + * + * Use of this Software is subject to the GPLv2 License + * + * 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_RENESAS_RX64_HASH) + +#include + +#include +/* mutex */ +static wolfSSL_Mutex rx64_hw_mutex; +static int rx64_hw_CryptHwMutexInit_ = 0; + +/* +* lock hw engine. +* this should be called before using engine. +*/ +int rx64_hw_lock(void) +{ + int ret = 0; + + WOLFSSL_MSG("enter rx64_hw_lock"); + + if (rx64_hw_CryptHwMutexInit_ == 0){ + ret = wc_InitMutex(&rx64_hw_mutex); + if (ret == 0) { + rx64_hw_CryptHwMutexInit_ = 1; + } else { + WOLFSSL_MSG(" mutex initialization failed."); + return -1; + } + } + if (wc_LockMutex(&rx64_hw_mutex) != 0) { + /* this should not happen */ + return -1; + } + + WOLFSSL_MSG("leave rx64_hw_lock"); + return ret; +} + +/* +* release hw engine +*/ +void rx64_hw_unlock(void) +{ + WOLFSSL_MSG("enter rx64_hw_unlock"); + /* unlock hw engine for next use */ + wc_UnLockMutex(&rx64_hw_mutex); + WOLFSSL_MSG("leave rx64_hw_unlock"); +} + +/* open RX64 HW drivers for use */ +void rx64_hw_Open(void) +{ + int ret = -1; + if (rx64_hw_lock() == 0) { + /* Enable the SHA coprocessor function. */ + R_Sha_Init(); + /* unlock hw */ + rx64_hw_unlock(); + ret = 0; + } else { + WOLFSSL_MSG("Failed to lock rx64 hw \n"); + } + return ret; +} + +/* close RX64 HW driver */ +void rx64_hw_Close(void) +{ + if (rx64_hw_lock() == 0) { + /* Disable the SHA coprocessor function. */ + R_Sha_Close(); + /* unlock hw */ + rx64_hw_unlock(); + } else { + WOLFSSL_MSG("Failed to unlock rx64 hw \n"); + } +} + + +#endif /* WOLFSSL_RENESAS_RX64_HASH */ diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 11cf844ae..c7d02e10a 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -339,6 +339,11 @@ #elif defined(WOLFSSL_SILABS_SE_ACCEL) /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ + +#elif defined(WOLFSSL_RENESAS_RX64_HASH) + +/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */ + #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include @@ -863,7 +868,8 @@ void wc_ShaFree(wc_Sha* sha) se050_hash_free(&sha->se050Ctx); #endif #if (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \ - !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) + !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) || \ + defined(WOLFSSL_RENESAS_RX64_HASH) if (sha->msg != NULL) { XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); sha->msg = NULL; @@ -882,6 +888,7 @@ void wc_ShaFree(wc_Sha* sha) #if !defined(WOLFSSL_RENESAS_TSIP_CRYPT) || \ defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) +#if !defined(WOLFSSL_RENESAS_RX64_HASH) #if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) int wc_ShaGetHash(wc_Sha* sha, byte* hash) @@ -951,6 +958,7 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) #endif return ret; } +#endif /* WOLFSSL_RENESAS_RX64_HASH */ #endif /* defined(WOLFSSL_RENESAS_TSIP_CRYPT) ... */ #endif /* !WOLFSSL_TI_HASH && !WOLFSSL_IMXRT_DCP */ #endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 9a56f4f9d..b6805a980 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -215,8 +215,8 @@ on the specific device platform. !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050_HASH) && \ (!defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(NO_WOLFSSL_RENESAS_SCEPROTECT_HASH)) && \ - (!defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)) - + (!defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)) && \ + !defined(WOLFSSL_RENESAS_RX64_HASH) static int InitSha256(wc_Sha256* sha256) @@ -818,6 +818,10 @@ 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(WOLFSSL_RENESAS_RX64_HASH) + + /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */ + #else #define NEED_SOFT_SHA256 @@ -1524,6 +1528,10 @@ 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(WOLFSSL_RENESAS_RX64_HASH) + +/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */ + #else #define NEED_SOFT_SHA224 @@ -1685,6 +1693,12 @@ static int InitSha256(wc_Sha256* sha256) #if defined(WOLFSSL_KCAPI_HASH) KcapiHashFree(&sha224->kcapi); #endif + #if defined(WOLFSSL_RENESAS_RX64_HASH) + if (sha224->msg != NULL) { + XFREE(sha224->msg, sha224->heap, DYNAMIC_TYPE_TMP_BUFFER); + sha224->msg = NULL; + } + #endif } #endif /* WOLFSSL_SHA224 */ #endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ @@ -1740,6 +1754,7 @@ void wc_Sha256Free(wc_Sha256* sha256) !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) || \ (defined(WOLFSSL_RENESAS_SCEPROTECT) && \ !defined(NO_WOLFSSL_RENESAS_SCEPROTECT_HASH)) || \ + defined(WOLFSSL_RENESAS_RX64_HASH) || \ defined(WOLFSSL_HASH_KEEP) if (sha256->msg != NULL) { @@ -1805,6 +1820,7 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) #ifndef WOLFSSL_TI_HASH +#if !defined(WOLFSSL_RENESAS_RX64_HASH) #ifdef WOLFSSL_SHA224 #if defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224) @@ -1903,6 +1919,7 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) #endif #endif /* WOLFSSL_SHA224 */ +#endif /* WOLFSSL_RENESAS_RX64_HASH */ #ifdef WOLFSSL_AFALG_HASH /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */ @@ -1929,6 +1946,8 @@ 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(WOLFSSL_RENESAS_RX64_HASH) + /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */ #else diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index b082706fc..78da614af 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -64,6 +64,9 @@ #if defined(WOLFSSL_RENESAS_SCE) #include #endif +#if defined(WOLFSSL_RENESAS_RX64_HASH) + #include +#endif #if defined(WOLFSSL_STSAFEA100) #include #endif @@ -176,6 +179,16 @@ int wolfCrypt_Init(void) } #endif + #if defined(WOLFSSL_RENESAS_RX64_HASH) + ret = rx64_hw_Open(); + if( ret != 0 ) { + WOLFSSL_MSG("Renesas RX64 HW Open failed"); + /* not return 1 since WOLFSSL_SUCCESS=1*/ + ret = -1;/* FATAL ERROR */ + return ret; + } + #endif + #if defined(WOLFSSL_RENESAS_SCEPROTECT) ret = wc_sce_Open( ); if( ret != FSP_SUCCESS ) { @@ -423,6 +436,10 @@ int wolfCrypt_Cleanup(void) tsip_Close(); #endif + #if defined(WOLFSSL_RENESAS_RX64_HASH) + rx64_hw_Close(); + #endif + #ifdef WOLFSSL_RENESAS_SCEPROTECT wc_sce_Close(); #endif diff --git a/wolfssl/wolfcrypt/port/Renesas/renesas-rx64-hw-crypt.h b/wolfssl/wolfcrypt/port/Renesas/renesas-rx64-hw-crypt.h new file mode 100644 index 000000000..07d59ac9a --- /dev/null +++ b/wolfssl/wolfcrypt/port/Renesas/renesas-rx64-hw-crypt.h @@ -0,0 +1,78 @@ +/* renesas-rx64-hw-crypt.h + * + * Contributed by Johnson Controls Tyco IP Holdings LLP. + * + * Use of this Software is subject to the GPLv2 License + * + * 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 __RENESAS_RX64_HW_CRYPT_H__ +#define __RENESAS_RX64_HW_CRYPT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int rx64_hw_Open(void); +void rx64_hw_Close(void); +int rx64_hw_lock(void); +void rx64_hw_unlock(void); + +#if (!defined(NO_SHA) || defined(WOLFSSL_SHA224) || !defined(NO_SHA256)) + +typedef enum +{ + RX64_SHA1 = 0, + RX64_SHA224 = 1, + RX64_SHA256 = 2, + NUM_RX64_SHA_TYPES = 3, +} RX64_SHA_TYPE; + +typedef struct +{ + byte* msg; + void* heap; + word32 used; + word32 len; + word32 sha_type; +} wolfssl_RX64_HW_Hash; + +#if !defined(NO_SHA) + typedef wolfssl_RX64_HW_Hash wc_Sha; +#endif + +#if !defined(NO_SHA256) + typedef wolfssl_RX64_HW_Hash wc_Sha256; +#endif + +#if defined(WOLFSSL_SHA224) + typedef wolfssl_RX64_HW_Hash wc_Sha224; + #define WC_SHA224_TYPE_DEFINED +#endif + +WOLFSSL_LOCAL int RX64_ShaCalc(byte* data, word32 len, byte* out, word32 sha_type); + +#endif /* !NO_SHA || WOLFSSL_SHA224 || !NO_SHA256 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RENESAS_RX64_HW_CRYPT_H__ */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index f4ce5acd3..95ddcd513 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -244,6 +244,9 @@ /* Uncomment next line if using RENESAS RA6M4 */ /* #define WOLFSSL_RENESAS_RA6M4 */ +/* Uncomment next line if using RENESAS RX64 hardware acceleration */ +/* #define WOLFSSL_RENESAS_RX64_HASH */ + /* Uncomment next line if using Solaris OS*/ /* #define WOLFSSL_SOLARIS */ @@ -368,6 +371,11 @@ #endif #endif /* WOLFSSL_RENESAS_TSIP */ +#if !defined(WOLFSSL_NO_HASH_RAW) && defined(WOLFSSL_RENESAS_RX64_HASH) + /* RAW hash function APIs are not implemented with RX64 hardware acceleration */ + #define WOLFSSL_NO_HASH_RAW +#endif + #if defined(WOLFSSL_RENESAS_SCEPROTECT) #define SCE_TLS_MASTERSECRET_SIZE 80 /* 20 words */ #define TSIP_TLS_HMAC_KEY_INDEX_WORDSIZE 64 diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 4f0d1cc47..a6362660f 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -113,6 +113,8 @@ enum { #elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \ !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) #include "wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h" +#elif defined(WOLFSSL_RENESAS_RX64_HASH) + #include "wolfssl/wolfcrypt/port/Renesas/renesas-rx64-hw-crypt.h" #else #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 93e1acf81..ccdee8540 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -156,6 +156,8 @@ enum { #elif defined(WOLFSSL_RENESAS_SCEPROTECT) && \ !defined(NO_WOLFSSL_RENESAS_SCEPROTECT_HASH) #include "wolfssl/wolfcrypt/port/Renesas/renesas-sce-crypt.h" +#elif defined(WOLFSSL_RENESAS_RX64_HASH) + #include "wolfssl/wolfcrypt/port/Renesas/renesas-rx64-hw-crypt.h" #else #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)