Various Espressif HW crypto, SHA2, AES, MP updates. (#6287)

* various Espressif HW crypto, SHA2, AES, MP updates.

* code review updates & cleanup

* clean trailing whitespace

* cleanup per code review

* removed additional unused WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW

* Code review updates; pack & order WC_ESP32SHA

* clean up TAG text for Espressif ESP_LOG()
This commit is contained in:
gojimmypi
2023-04-19 15:10:22 +02:00
committed by GitHub
parent 70322f620d
commit 510038022f
12 changed files with 2101 additions and 653 deletions

View File

@ -190,6 +190,8 @@ set(COMPONENT_SRCEXCLUDE
"${WOLFSSL_ROOT}/src/conf.c"
"${WOLFSSL_ROOT}/src/misc.c"
"${WOLFSSL_ROOT}/src/pk.c"
"${WOLFSSL_ROOT}/src/ssl_asn1.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/ssl_bn.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/ssl_misc.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/x509.c"
"${WOLFSSL_ROOT}/src/x509_str.c"
@ -197,6 +199,7 @@ set(COMPONENT_SRCEXCLUDE
"${WOLFSSL_ROOT}/wolfcrypt/src/misc.c"
"${EXCLUDE_ASM}"
)
set(COMPONENT_PRIV_INCLUDEDIRS ${IDF_PATH}/components/driver/include)
register_component()

View File

@ -190,6 +190,8 @@ set(COMPONENT_SRCEXCLUDE
"${WOLFSSL_ROOT}/src/conf.c"
"${WOLFSSL_ROOT}/src/misc.c"
"${WOLFSSL_ROOT}/src/pk.c"
"${WOLFSSL_ROOT}/src/ssl_asn1.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/ssl_bn.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/ssl_misc.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/x509.c"
"${WOLFSSL_ROOT}/src/x509_str.c"

View File

@ -178,7 +178,8 @@ void app_main(void)
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
#error "ESP32WROOM32_CRYPT not yet supported on ESP32-S2"
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#error "ESP32WROOM32_CRYPT not yet supported on ESP32-S3"
/* #error "ESP32WROOM32_CRYPT not yet supported on ESP32-S3" */
ESP_LOGI(TAG, "ESP32WROOM32_CRYPT is enabled for ESP32-S3.");
#else
ESP_LOGI(TAG, "ESP32WROOM32_CRYPT is enabled.");
#endif

View File

@ -66,7 +66,21 @@
#include <wolfssl/wolfcrypt/wolfmath.h>
#ifdef WOLFSSL_ESPIDF
#include <xtensa/hal.h> /* reminder Espressif RISC-V not yet implemented */
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
#include "driver/gptimer.h"
static gptimer_handle_t esp_gptimer = NULL;
static gptimer_config_t esp_timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = CONFIG_XTAL_FREQ * 1000000,
};
#elif defined(CONFIG_IDF_TARGET_ESP32) || \
defined(CONFIG_IDF_TARGET_ESP32S2) || \
defined(CONFIG_IDF_TARGET_ESP32S3)
#include <xtensa/hal.h>
#else
#error "CONFIG_IDF_TARGET not implemented"
#endif
#include <esp_log.h>
#endif
@ -1001,13 +1015,18 @@ static const char* bench_desc_words[][15] = {
** the Espressif `unsigned xthal_get_ccount()` which is known to overflow
** at least once during full benchmark tests.
*/
word64 xthal_get_ccount_ex()
uint64_t xthal_get_ccount_ex()
{
/* reminder: unsigned long long max = 18,446,744,073,709,551,615 */
/* the currently observed clock counter value */
word64 thisVal = xthal_get_ccount();
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
uint64_t thisVal = 0;
ESP_ERROR_CHECK(gptimer_get_raw_count(esp_gptimer, &thisVal));
#else
/* reminder unsupported CONFIG_IDF_TARGET captured above */
uint64_t thisVal = xthal_get_ccount();
#endif
/* if the current value is less than the previous value,
** we likely overflowed at least once.
*/
@ -1034,8 +1053,12 @@ static const char* bench_desc_words[][15] = {
_xthal_get_ccount_ex += (thisVal - _xthal_get_ccount_last);
/* all of this took some time, so reset the "last seen" value */
_xthal_get_ccount_last = xthal_get_ccount();
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
ESP_ERROR_CHECK(gptimer_get_raw_count(esp_gptimer,
&_xthal_get_ccount_last));
#else
_xthal_get_ccount_last = xthal_get_ccount();
#endif
return _xthal_get_ccount_ex;
}
@ -4992,7 +5015,7 @@ exit:
WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
}
#endif
#endif /* WOLFSSL_NOSHA512_224 && !FIPS ... */
#if !defined(WOLFSSL_NOSHA512_256) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
@ -5086,10 +5109,9 @@ exit:
WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
}
#endif /* WOLFSSL_NOSHA512_256 && !FIPS ... */
#endif
#endif
#endif /* WOLFSSL_SHA512 */
#ifdef WOLFSSL_SHA3
@ -7494,8 +7516,9 @@ void bench_eccEncrypt(int curveId)
if (ret != 0)
goto exit;
for (i = 0; i < (int)sizeof(msg); i++)
for (i = 0; i < (int)sizeof(msg); i++) {
msg[i] = (byte)i;
}
bench_stats_start(&count, &start);
do {
@ -9095,6 +9118,14 @@ static int string_matches(const char* arg, const char* str)
#ifdef WOLFSSL_ESPIDF
int argc = construct_argv();
char** argv = (char**)__argv;
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
ESP_ERROR_CHECK(gptimer_new_timer(&esp_timer_config, &esp_gptimer));
ESP_LOGI(TAG, "Enable ESP32-C3 timer ");
ESP_ERROR_CHECK(gptimer_enable(esp_gptimer));
ESP_ERROR_CHECK(gptimer_start(esp_gptimer));
#endif
#endif
return wolfcrypt_benchmark_main(argc, argv);

View File

@ -35,10 +35,12 @@
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
#include "sdkconfig.h" /* programmatically generated from sdkconfig */
#include <wolfssl/wolfcrypt/aes.h>
#include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
#include <wolfssl/wolfcrypt/error-crypt.h>
/* breadcrumb tag text for ESP_LOG() */
static const char* TAG = "wolf_hw_aes";
/* mutex */
@ -67,27 +69,36 @@ static int esp_aes_hw_InUse()
}
else {
ESP_LOGE(TAG, "aes mutex initialization failed.");
return -1;
}
}
else {
/* esp aes has already been initialized */
}
/* lock hardware */
ret = esp_CryptHwMutexLock(&aes_mutex, portMAX_DELAY);
if(ret != 0) {
if (ret == 0) {
/* lock hardware */
ret = esp_CryptHwMutexLock(&aes_mutex, portMAX_DELAY);
}
else {
ESP_LOGE(TAG, "aes engine lock failed.");
return -1;
}
/* Enable AES hardware */
periph_module_enable(PERIPH_AES_MODULE);
if (ret == 0) {
/* Enable AES hardware */
periph_module_enable(PERIPH_AES_MODULE);
#if CONFIG_IDF_TARGET_ESP32S3
/* Select working mode. Can be typical or DMA.
* 0 => typical
* 1 => DMA */
DPORT_REG_WRITE(AES_DMA_ENABLE_REG, 0);
#endif
}
ESP_LOGV(TAG, "leave esp_aes_hw_InUse");
return ret;
}
} /* esp_aes_hw_InUse */
/*
* release hw engine
@ -102,20 +113,22 @@ static void esp_aes_hw_Leave( void )
esp_CryptHwMutexUnLock(&aes_mutex);
ESP_LOGV(TAG, "leave esp_aes_hw_Leave");
}
} /* esp_aes_hw_Leave */
/*
* set key to hardware key registers.
* return 0 on success; -1 if mode isn't supported.
*/
static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
static int esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
{
int ret = 0;
word32 i;
word32 mode_ = 0;
ESP_LOGV(TAG, " enter esp_aes_hw_Set_KeyMode");
/* check mode */
if(mode == ESP32_AES_UPDATEKEY_ENCRYPT) {
if (mode == ESP32_AES_UPDATEKEY_ENCRYPT) {
mode_ = 0;
}
else {
@ -124,47 +137,89 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
}
else {
ESP_LOGE(TAG, " >> unexpected error.");
return;
ret = BAD_FUNC_ARG;
}
} /* if mode */
if (ret == 0) {
/* update key */
for (i = 0; i < (ctx->keylen) / sizeof(word32); i++) {
DPORT_REG_WRITE(AES_KEY_BASE + (i * 4), *(((word32*)ctx->key) + i));
}
/*
** ESP32: see table 22-1 in ESP32 Technical Reference
** ESP32S3: see table 19-2 in ESP32S3 Technical Reference
** mode Algorithm ESP32 ESP32S3
** 0 AES-128 Encryption y y
** 1 AES-192 Encryption y n
** 2 AES-256 Encryption y y
** 4 AES-128 Decryption y y
** 5 AES-192 Decryption y n
** 6 AES-256 Decryption y y
*/
switch(ctx->keylen){
case 24: mode_ += 1; break;
case 32: mode_ += 2; break;
default: break;
}
#if CONFIG_IDF_TARGET_ESP32S3
if (mode_ == 1 || mode_ == 5 || mode_ == 7) {
ESP_LOGE(TAG, "esp_aes_hw_Set_KeyMode unsupported mode: %i", mode_);
ret = BAD_FUNC_ARG;
}
#endif
if (ret == 0) {
DPORT_REG_WRITE(AES_MODE_REG, mode_);
}
ESP_LOGV(TAG, " leave esp_aes_hw_Setkey");
}
/* update key */
for(i=0; i<(ctx->keylen)/sizeof(word32); i++){
DPORT_REG_WRITE(AES_KEY_BASE + (i*4), *(((word32*)ctx->key) + i));
}
/* mode
* 0 AES-128 Encryption
* 1 AES-192 Encryption
* 2 AES-256 Encryption
* 4 AES-128 Decryption
* 5 AES-192 Decryption
* 6 AES-256 Decryption
*/
switch(ctx->keylen){
case 24: mode_ += 1; break;
case 32: mode_ += 2; break;
default: break;
}
DPORT_REG_WRITE(AES_MODE_REG, mode_);
ESP_LOGV(TAG, " leave esp_aes_hw_Setkey");
}
return ret;
} /* esp_aes_hw_Set_KeyMode */
/*
* esp_aes_bk
* Process a one block of AES
* in: block of 16 bytes (4 x words32) to process
* out: result of processing input bytes.
*/
static void esp_aes_bk(const byte* in, byte* out)
{
const word32 *inwords = (const word32 *)in;
#if ESP_IDF_VERSION_MAJOR >= 4
uint32_t *outwords = (uint32_t *)out;
uint32_t *outwords = (uint32_t *)out;
#else
word32 *outwords = (word32 *)out;
#endif
ESP_LOGV(TAG, "enter esp_aes_bk");
#if CONFIG_IDF_TARGET_ESP32S3
/* See esp32 - s3 technical reference manual:
** 19.4.3 Operation process using CPU working mode.
** The ESP32-S3 also supports a DMA mode.
**
** Copy text for encrypting/decrypting blocks: */
DPORT_REG_WRITE(AES_TEXT_IN_BASE, inwords[0]);
DPORT_REG_WRITE(AES_TEXT_IN_BASE + 4, inwords[1]);
DPORT_REG_WRITE(AES_TEXT_IN_BASE + 8, inwords[2]);
DPORT_REG_WRITE(AES_TEXT_IN_BASE + 12, inwords[3]);
/* start engine */
DPORT_REG_WRITE(AES_TRIGGER_REG, 1);
/* wait until finishing the process */
while (DPORT_REG_READ(AES_STATE_REG) != 0) {
/* wating for the hardware accelerator to complete operation. */
}
/* read-out blocks */
esp_dport_access_read_buffer(outwords, AES_TEXT_OUT_BASE, 4);
#else
/* copy text for encrypting/decrypting blocks */
DPORT_REG_WRITE(AES_TEXT_BASE, inwords[0]);
DPORT_REG_WRITE(AES_TEXT_BASE + 4, inwords[1]);
@ -175,15 +230,18 @@ static void esp_aes_bk(const byte* in, byte* out)
DPORT_REG_WRITE(AES_START_REG, 1);
/* wait until finishing the process */
while(1) {
if(DPORT_REG_READ(AES_IDLE_REG) == 1)
while (1) {
if (DPORT_REG_READ(AES_IDLE_REG) == 1) {
break;
}
}
/* read-out blocks */
esp_dport_access_read_buffer(outwords, AES_TEXT_BASE, 4);
#endif
ESP_LOGV(TAG, "leave esp_aes_bk");
}
} /* esp_aes_bk */
/*
* wc_esp32AesEncrypt
@ -192,20 +250,33 @@ static void esp_aes_bk(const byte* in, byte* out)
* @param in : a pointer of the input buffer containing plain text to be encrypted
* @param out: a pointer of the output buffer in which to store the cipher text of
* the encrypted message
* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
*/
int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)
{
int ret = 0;
ESP_LOGV(TAG, "enter wc_esp32AesEncrypt");
/* lock the hw engine */
esp_aes_hw_InUse();
ret = esp_aes_hw_InUse();
if (ret == 0) {
ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);
if (ret != 0) {
ESP_LOGE(TAG, "wc_esp32AesEncrypt failed during esp_aes_hw_Set_KeyMode");
}
}
/* load the key into the register */
esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);
/* process a one block of AES */
esp_aes_bk(in, out);
if (ret == 0) {
/* process a one block of AES */
esp_aes_bk(in, out);
}
/* release hw */
esp_aes_hw_Leave();
return 0;
}
return ret;
} /* wc_esp32AesEncrypt */
/*
* wc_esp32AesDecrypt
@ -214,20 +285,33 @@ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)
* @param in : a pointer of the input buffer containing plain text to be decrypted
* @param out: a pointer of the output buffer in which to store the cipher text of
* the decrypted message
* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
*/
int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
{
int ret;
ESP_LOGV(TAG, "enter wc_esp32AesDecrypt");
/* lock the hw engine */
esp_aes_hw_InUse();
/* load the key into the register */
esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
/* process a one block of AES */
esp_aes_bk(in, out);
/* release hw engine */
esp_aes_hw_Leave();
return 0;
}
ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
if (ret != 0) {
ESP_LOGE(TAG, "wc_esp32AesDecrypt failed during esp_aes_hw_Set_KeyMode");
/* release hw */
esp_aes_hw_Leave();
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
/* process a one block of AES */
esp_aes_bk(in, out);
/* release hw engine */
esp_aes_hw_Leave();
}
return ret;
} /* wc_esp32AesDecrypt */
/*
* wc_esp32AesCbcEncrypt
@ -239,9 +323,11 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
* the encrypted message
* @param in : a pointer of the input buffer containing plain text to be encrypted
* @param sz : size of input message
* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
*/
int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret;
int i;
int offset = 0;
word32 blocks = (sz / AES_BLOCK_SIZE);
@ -250,31 +336,40 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
ESP_LOGV(TAG, "enter wc_esp32AesCbcEncrypt");
iv = (byte*)aes->reg;
iv = (byte*)aes->reg;
esp_aes_hw_InUse();
ret = esp_aes_hw_InUse();
esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);
if (ret == 0) {
ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);
if (ret != 0) {
ESP_LOGE(TAG, "wc_esp32AesCbcEncrypt failed HW Set KeyMode");
}
} /* if set esp_aes_hw_InUse successful */
while (blocks--) {
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
if (ret == 0) {
while (blocks--) {
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
/* XOR block with IV for CBC */
for (i = 0; i < AES_BLOCK_SIZE; i++)
temp_block[i] ^= iv[i];
/* XOR block with IV for CBC */
for (i = 0; i < AES_BLOCK_SIZE; i++) {
temp_block[i] ^= iv[i];
}
esp_aes_bk(temp_block, (out + offset));
esp_aes_bk(temp_block, (out + offset));
offset += AES_BLOCK_SIZE;
offset += AES_BLOCK_SIZE;
/* store IV for next block */
XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
}
/* store IV for next block */
XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
} /* while (blocks--) */
} /* if Set Mode successful (ret == 0) */
esp_aes_hw_Leave();
ESP_LOGV(TAG, "leave wc_esp32AesCbcEncrypt");
return 0;
}
} /* wc_esp32AesCbcEncrypt */
/*
* wc_esp32AesCbcDecrypt
* @brief: Encrypts a plain text message from the input buffer, and places the
@ -285,9 +380,12 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
* the decrypted message
* @param in : a pointer of the input buffer containing plain text to be decrypted
* @param sz : size of input message
* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
*/
int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret;
int i;
int offset = 0;
word32 blocks = (sz / AES_BLOCK_SIZE);
@ -296,32 +394,39 @@ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
ESP_LOGV(TAG, "enter wc_esp32AesCbcDecrypt");
iv = (byte*)aes->reg;
iv = (byte*)aes->reg;
esp_aes_hw_InUse();
ret = esp_aes_hw_InUse();
esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
while (blocks--) {
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
esp_aes_bk((in + offset), (out + offset));
/* XOR block with IV for CBC */
for (i = 0; i < AES_BLOCK_SIZE; i++) {
(out + offset)[i] ^= iv[i];
if (ret == 0) {
ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
if (ret != 0) {
ESP_LOGE(TAG, "wc_esp32AesCbcDecrypt failed HW Set KeyMode");
}
/* store IV for next block */
XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
offset += AES_BLOCK_SIZE;
}
if (ret == 0) {
while (blocks--) {
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
esp_aes_bk((in + offset), (out + offset));
/* XOR block with IV for CBC */
for (i = 0; i < AES_BLOCK_SIZE; i++) {
(out + offset)[i] ^= iv[i];
}
/* store IV for next block */
XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
offset += AES_BLOCK_SIZE;
} /* while (blocks--) */
} /* if Set Mode was successful (ret == 0) */
esp_aes_hw_Leave();
ESP_LOGV(TAG, "leave wc_esp32AesCbcDecrypt");
return 0;
}
} /* wc_esp32AesCbcDecrypt */
#endif /* WOLFSSL_ESP32WROOM32_CRYPT */
#endif /* NO_AES */

View File

@ -48,6 +48,7 @@ static const char* const TAG = "wolfssl_mp";
#define ESP_HW_RSAMIN_BIT 512
#define BYTE_TO_WORDS(s) (((s+3)>>2)) /* (s+(4-1))/ 4 */
#define BITS_TO_WORDS(s) (((s+31)>>3)>>2) /* (s+(32-1))/ 8/ 4*/
#define BITS_IN_ONE_WORD 32
#define MP_NG -1
@ -57,7 +58,7 @@ static const char* const TAG = "wolfssl_mp";
static wolfSSL_Mutex mp_mutex;
static int espmp_CryptHwMutexInit = 0;
/*
* check if the hw is ready before accessing it
* check if the HW is ready before accessing it
*
* When the RSA Accelerator is released from reset, the register RSA_CLEAN_REG
* reads 0 and an initialization process begins. Hardware initializes the four
@ -66,27 +67,39 @@ static int espmp_CryptHwMutexInit = 0;
* after being released from reset, and before writing to any RSA Accelerator
* memory blocks or registers for the first time.
*/
static int esp_mp_hw_wait_clean()
static int esp_mp_hw_wait_clean(void)
{
int ret = MP_OKAY;
word32 timeout = 0;
while(!ESP_TIMEOUT(++timeout) &&
DPORT_REG_READ(RSA_CLEAN_REG) != 1) {
#if CONFIG_IDF_TARGET_ESP32S3
while (!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1)
{
/* wait. expected delay 1 to 2 uS */
}
#else
/* RSA_CLEAN_REG is now called RSA_QUERY_CLEAN_REG. hwcrypto_reg.h maintains
* RSA_CLEAN_REG for backwards compatibility so this block _might_ be not needed. */
while(!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(RSA_CLEAN_REG) != 1) {
/* wait. expected delay 1 to 2 uS */
}
#endif
if (ESP_TIMEOUT(timeout)) {
ESP_LOGE(TAG, "waiting hw ready is timed out.");
return MP_NG;
ESP_LOGE(TAG, "esp_mp_hw_wait_clean waiting HW ready timed out.");
ret = MP_NG;
}
return MP_OKAY;
return ret;
}
/*
* lock hw engine.
* this should be called before using engine.
* esp_mp_hw_lock()
*
* returns 0 if the hw lock was initialized and mutex lock
* Lock HW engine.
* This should be called before using engine.
*
* Returns 0 if the HW lock was initialized and mutex lock.
*
* See Chapter 24:
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
@ -116,27 +129,40 @@ static int esp_mp_hw_lock()
}
else {
ESP_LOGE(TAG, "mp mutex initialization failed.");
return MP_NG;
}
}
else {
/* esp aes has already been initialized */
/* ESP AES has already been initialized */
}
/* lock hardware */
ret = esp_CryptHwMutexLock(&mp_mutex, portMAX_DELAY);
if (ret == 0) {
/* lock hardware */
ret = esp_CryptHwMutexLock(&mp_mutex, portMAX_DELAY);
if (ret != 0) {
ESP_LOGE(TAG, "mp engine lock failed.");
ret = MP_NG;
}
}
if (ret != 0) {
ESP_LOGE(TAG, "mp engine lock failed.");
return MP_NG;
#if CONFIG_IDF_TARGET_ESP32S3
/* Activate the RSA accelerator. See 20.3 of ESP32-S3 technical manual.
* periph_module_enable doesn't seem to be documented and in private folder
* with v5 release. Maybe it will be deprecated? */
if (ret == 0) {
periph_module_enable(PERIPH_RSA_MODULE);
/* clear bit to enable hardware operation; (set to disable) */
DPORT_REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
}
#else
/* Enable RSA hardware */
periph_module_enable(PERIPH_RSA_MODULE);
if (ret == 0) {
periph_module_enable(PERIPH_RSA_MODULE);
/* clear bit to enable hardware operation; (set to disable)
*/
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
/* clear bit to enable hardware operation; (set to disable) */
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
}
#endif
/* reminder: wait until RSA_CLEAN_REG reads 1
* see esp_mp_hw_wait_clean()
@ -145,17 +171,27 @@ static int esp_mp_hw_lock()
ESP_LOGV(TAG, "leave esp_mp_hw_lock");
return ret;
}
/*
* Release hw engine
* Release HW engine
*/
static void esp_mp_hw_unlock( void )
{
#if CONFIG_IDF_TARGET_ESP32S3
/* Deactivate the RSA accelerator. See 20.3 of ESP32-S3 technical manual.
* periph_module_enable doesn't seem to be documented and in private folder
* with v5 release. Maybe it will be deprecated? */
DPORT_REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
periph_module_disable(PERIPH_RSA_MODULE);
#else
/* set bit to disabled hardware operation; (clear to enable)
*/
DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
/* Disable RSA hardware */
periph_module_disable(PERIPH_RSA_MODULE);
#endif
/* unlock */
esp_CryptHwMutexUnLock(&mp_mutex);
@ -189,7 +225,7 @@ static int esp_calc_Mdash(MATH_INT_T *M, word32 k, mp_digit* md)
return MP_OKAY;
}
/* start hw process */
/* start HW process */
static void process_start(word32 reg)
{
/* clear interrupt */
@ -249,7 +285,8 @@ static void esp_mpint_to_memblock(word32 mem_address, const MATH_INT_T* mp,
}
}
}
/* return needed hw words.
/* return needed HW words.
* supported words length
* words : {16 , 32, 48, 64, 80, 96, 112, 128}
* bits : {512,1024, 1536, 2048, 2560, 3072, 3584, 4096}
@ -294,7 +331,91 @@ static int esp_get_rinv(MATH_INT_T *rinv, MATH_INT_T *M, word32 exp)
int esp_mp_mul(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* Z)
{
int ret = 0;
#if CONFIG_IDF_TARGET_ESP32S3
int BitsInX = mp_count_bits(X);
int BitsInY = mp_count_bits(Y);
/* X & Y must be represented by the same number of bits. Must be
* enough to represent the larger one. */
int MinXYBits = max(BitsInX, BitsInY);
/* Figure out how many words we need to represent each operand & the result. */
int WordsForOperand = bits2words(MinXYBits);
int WordsForResult = bits2words(BitsInX + BitsInY);
#ifdef WOLFSSL_SP_INT_NEGATIVE
int neg;
neg = (X->sign == Y->sign) ? MP_ZPOS : MP_NEG;
#endif
/* Make sure we are within capabilities of hardware. */
if ( (WordsForOperand * BITS_IN_ONE_WORD) > ESP_HW_MULTI_RSAMAX_BITS ) {
ESP_LOGW(TAG, "exceeds max bit length(2048)");
return MP_VAL; /* Error: value is not able to be used. */
}
/* Steps to perform large number multiplication. Calculates Z = X x Y. The number of
* bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the
* maximum number of bits in the X and Y is 2048.
* See 20.3.3 of ESP32-S3 technical manual
* 1. Lock the hardware so no-one else uses it and wait until it is ready.
* 2. Enable/disable interrupt that signals completion -- we don't use the interrupt.
* 3. Write number of words required for result to the RSA_MODE_REG (now called RSA_LENGTH_REG).
* Number of words required for the result is 2 * words for operand - 1
* 4. Load X, Y operands to memory blocks. Note the Y value must be written to
* right aligned.
* 5. Start the operation by writing 1 to RSA_MULT_START_REG, then wait for it
* to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG).
* 6. Read the result out.
* 7. Release the hardware lock so others can use it.
* x. Clear the interrupt flag, if you used it (we don't). */
/* 1. lock HW for use & wait until it is ready. */
if ( ((ret = esp_mp_hw_lock()) != MP_OKAY) ||
((ret = esp_mp_hw_wait_clean()) != MP_OKAY) ) {
return ret;
}
/* 2. Disable completion interrupt signal; we don't use. */
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion.
/* 3. Write number of words required for result. */
if ( (WordsForOperand * BITS_IN_ONE_WORD * 2) > ESP_HW_RSAMAX_BIT) {
ESP_LOGW(TAG, "result exceeds max bit length");
return MP_VAL; /* Error: value is not able to be used. */
}
DPORT_REG_WRITE(RSA_LENGTH_REG, (WordsForOperand * 2 - 1) );
/* 4. Load X, Y operands. Maximum is 64 words (64*8*4 = 2048 bits) */
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
X, BitsInX, WordsForOperand);
esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + WordsForOperand * 4,
Y, BitsInY, WordsForOperand);
/* 5. Start operation and wait until it completes. */
process_start(RSA_MULT_START_REG);
ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
if (MP_OKAY != ret) {
return ret;
}
/* 6. read the result form MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, WordsForResult);
/* 7. clear and release HW */
esp_mp_hw_unlock();
#ifdef WOLFSSL_SP_INT_NEGATIVE
Z->sign = (Z->used > 0) ? neg : MP_ZPOS;
#endif
return ret;
/* end if CONFIG_IDF_TARGET_ESP32S3 */
#else /* not CONFIG_IDF_TARGET_ESP32S3 */
/* assumed to be regular Xtensa here */
word32 Xs;
word32 Ys;
word32 Zs;
@ -302,25 +423,27 @@ int esp_mp_mul(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* Z)
word32 hwWords_sz;
/* neg check - X*Y becomes negative */
#ifdef WOLFSSL_SP_INT_NEGATIVE
neg = mp_isneg(X) != mp_isneg(Y) ? 1 : 0;
#endif
/* ask bits number */
Xs = mp_count_bits(X);
Ys = mp_count_bits(Y);
Zs = Xs + Ys;
/* maximum bits and words for writing to hw */
/* maximum bits and words for writing to HW */
maxWords_sz = bits2words(max(Xs, Ys));
hwWords_sz = words2hwords(maxWords_sz);
/* sanity check */
if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) {
ESP_LOGW(TAG, "exceeds max bit length(2048)");
return -2;
return MP_VAL; /* Error: value is not able to be used. */
}
/*Steps to use hw in the following order:
* 1. wait until clean hw engine
/*Steps to use HW in the following order:
* 1. wait until clean HW engine
* 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG
* 3. Write X and Y to memory blocks
* need to write data to each memory block only according to the length
@ -331,9 +454,9 @@ int esp_mp_mul(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* Z)
* 6. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.
* 7. Read the Z from RSA_Z_MEM
* 8. Write 1 to RSA_INTERUPT_REG to clear the interrupt.
* 9. Release the hw engine
* 9. Release the HW engine
*/
/* lock hw for use */
/* lock HW for use */
if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
return ret;
}
@ -366,14 +489,18 @@ int esp_mp_mul(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* Z)
/* step.6 read the result form MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs));
/* step.7 clear and release hw */
/* step.7 clear and release HW */
esp_mp_hw_unlock();
#ifdef WOLFSSL_SP_INT_NEGATIVE
if (!mp_iszero(Z) && neg) {
mp_setneg(Z);
}
#endif
return ret;
#endif /* CONFIG_IDF_TARGET_ESP32S3 or not */
}
/* Z = X * Y (mod M) */
@ -392,6 +519,12 @@ int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
MATH_INT_T tmpZ;
mp_digit mp;
uint32_t Exponent;
#if CONFIG_IDF_TARGET_ESP32S3
uint32_t OperandBits;
int WordsForOperand;
# endif
/* neg check - X*Y becomes negative */
negcheck = mp_isneg(X) != mp_isneg(Y) ? 1 : 0;
@ -400,27 +533,33 @@ int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
Ys = mp_count_bits(Y);
Ms = mp_count_bits(M);
/* maximum bits and words for writing to hw */
/* maximum bits and words for writing to HW */
maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));
zwords = bits2words(min(Ms, Xs + Ys));
hwWords_sz = words2hwords(maxWords_sz);
if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) {
ESP_LOGE(TAG, "exceeds hw maximum bits");
return -2;
ESP_LOGE(TAG, "exceeds HW maximum bits");
return MP_VAL; /* Error: value is not able to be used. */
}
/* calculate r_inv = R^2 mode M
* where: R = b^n, and b = 2^32
* accordingly R^2 = 2^(n*32*2)
*/
#if CONFIG_IDF_TARGET_ESP32S3
Exponent = maxWords_sz * BITS_IN_ONE_WORD * 2;
#else
Exponent = hwWords_sz << 6;
#endif
ret = mp_init_multi(&tmpZ, &r_inv, NULL, NULL, NULL, NULL);
if (ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz << 6))) != MP_OKAY) {
if (ret == 0 && (ret = esp_get_rinv(&r_inv, M, Exponent)) != MP_OKAY) {
ESP_LOGE(TAG, "calculate r_inv failed.");
mp_clear(&tmpZ);
mp_clear(&r_inv);
return ret;
}
/* lock hw for use */
/* lock HW for use */
if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
mp_clear(&tmpZ);
mp_clear(&r_inv);
@ -431,10 +570,85 @@ int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
ESP_LOGE(TAG, "failed to calculate M dash");
mp_clear(&tmpZ);
mp_clear(&r_inv);
return -1;
return ret;
}
/*Steps to use hw in the following order:
* 1. wait until clean hw engine
#if CONFIG_IDF_TARGET_ESP32S3
/* Steps to perform large number modular multiplication. Calculates Z = (X x Y) modulo M.
* The number of bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the
* maximum number of bits in the X and Y is 2048. We must use the same number of words to represent
* the bits in X, Y and M.
* See 20.3.3 of ESP32-S3 technical manual
* 1. Wait until the hardware is ready.
* 2. Enable/disable interrupt that signals completion -- we don't use the interrupt.
* 3. Write the number of words required to represent the operands to the
* RSA_MODE_REG (now called RSA_LENGTH_REG).
* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
* 5. Load X, Y, M, r' operands to memory blocks.
* 6. Start the operation by writing 1 to RSA_MOD_MULT_START_REG, then wait for it
* to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG).
* 7. Read the result out.
* 8. Release the hardware lock so others can use it.
* x. Clear the interrupt flag, if you used it (we don't). */
/* 1. Wait until hardware is ready. */
if ((ret = esp_mp_hw_wait_clean()) != MP_OKAY) {
return ret;
}
/* 2. Disable completion interrupt signal; we don't use. */
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion.
/* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
OperandBits = max(max(Xs, Ys), Ms);
if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
ESP_LOGW(TAG, "result exceeds max bit length");
return MP_VAL; /* Error: value is not able to be used. */
}
WordsForOperand = bits2words(OperandBits);
DPORT_REG_WRITE(RSA_LENGTH_REG, WordsForOperand - 1);
/* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */
DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
/* Select acceleration options. */
DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0);
/* 5. Load X, Y, M, r' operands.
* Note RSA_MEM_RB_BLOCK_BASE == RSA_MEM_Z_BLOC_BASE on ESP32s3*/
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_RB_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv), hwWords_sz);
/* 6. Start operation and wait until it completes. */
process_start(RSA_MOD_MULT_START_REG);
ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
if (MP_OKAY != ret) {
return ret;
}
/* 7. read the result form MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, &tmpZ, zwords);
/* 8. clear and release HW */
esp_mp_hw_unlock();
if (negcheck) {
mp_sub(M, &tmpZ, &tmpZ);
}
mp_copy(&tmpZ, Z);
mp_clear(&tmpZ);
mp_clear(&r_inv);
return ret;
/* end if CONFIG_IDF_TARGET_ESP32S3 */
#else
/* non-S3 Xtensa */
/*Steps to use HW in the following order:
* 1. wait until clean HW engine
* 2. Write(N/512bits - 1) to MULT_MODE_REG
* 3. Write X,M(=G, X, P) to memory blocks
* need to write data to each memory block only according to the length
@ -449,10 +663,10 @@ int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
* 10. Wait for the second operation to be completed. Poll INTERRUPT_REG until it reads 1.
* 11. Read the Z from RSA_Z_MEM
* 12. Write 1 to RSA_INTERUPT_REG to clear the interrupt.
* 13. Release the hw engine
* 13. Release the HW engine
*/
if ((ret = esp_mp_hw_wait_clean()) != MP_OKAY) {
if ( (ret = esp_mp_hw_wait_clean()) != MP_OKAY ) {
return ret;
}
/* step.1 512 bits => 16 words */
@ -468,6 +682,7 @@ int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
/* step.3 write M' into memory */
DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
/* step.4 start process */
process_start(RSA_MULT_START_REG);
@ -485,7 +700,7 @@ int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
/* step.12 read the result from MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, &tmpZ, zwords);
/* step.13 clear and release hw */
/* step.13 clear and release HW */
esp_mp_hw_unlock();
/* additional steps */
@ -504,23 +719,25 @@ int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
mp_clear(&r_inv);
return ret;
#endif
}
/* Large Number Modular Exponentiation
*
* Z = X^Y mod M
*
* See Chapter 24:
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
*
* See:
* ESP32, Chapter 24, https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
* ESP32s3, section 20.3.1, https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf
* The operation is based on Montgomery multiplication. Aside from the
* arguments X, Y , and M, two additional ones are needed —r and M
.* These arguments are calculated in advance by software.
.*
.* The RSA Accelerator supports operand lengths of N ∈ {512, 1024, 1536, 2048,
.* 2560, 3072, 3584, 4096} bits. The bit length of arguments Z, X, Y , M,
.* and r can be any one from the N set, but all numbers in a calculation must
.* be of the same length. The bit length of M is always 32.
.* 2560, 3072, 3584, 4096} bits on the ESP32 and N ∈ [32, 4096] bits on the ESP32s3.
.* The bit length of arguments Z, X, Y , M, and r can be any one from the N set,
.* but all numbers in a calculation must be of the same length.
.* The bit length of M is always 32.
.*
.* Note some DH references may use: Y = (G ^ X) mod P
*/
@ -536,41 +753,111 @@ int esp_mp_exptmod(MATH_INT_T* X, MATH_INT_T* Y, word32 Ys, MATH_INT_T* M, MATH_
MATH_INT_T r_inv;
mp_digit mp;
#if CONFIG_IDF_TARGET_ESP32S3
uint32_t OperandBits;
uint32_t WordsForOperand;
#endif
/* ask bits number */
Xs = mp_count_bits(X);
Ms = mp_count_bits(M);
/* maximum bits and words for writing to hw */
/* maximum bits and words for writing to HW */
maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));
hwWords_sz = words2hwords(maxWords_sz);
if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) {
ESP_LOGE(TAG, "exceeds hw maximum bits");
return -2;
ESP_LOGE(TAG, "exceeds HW maximum bits");
return MP_VAL; /* Error: value is not able to be used. */
}
/* calculate r_inv = R^2 mode M
* where: R = b^n, and b = 2^32
* accordingly R^2 = 2^(n*32*2)
*/
ret = mp_init(&r_inv);
if (ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz << 6))) != MP_OKAY) {
if ( (ret == 0) &&
((ret = esp_get_rinv(&r_inv, M, (hwWords_sz << 6))) != MP_OKAY) ) {
ESP_LOGE(TAG, "calculate r_inv failed.");
mp_clear(&r_inv);
return ret;
}
/* lock and init the hw */
if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
/* lock and init the HW */
if ( (ret = esp_mp_hw_lock()) != MP_OKAY ) {
mp_clear(&r_inv);
return ret;
}
/* calc M' */
/* if Pm is odd, uses mp_montgomery_setup() */
if ((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {
if ( (ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY ) {
ESP_LOGE(TAG, "failed to calculate M dash");
mp_clear(&r_inv);
return -1;
return ret;
}
/*Steps to use hw in the following order:
#if CONFIG_IDF_TARGET_ESP32S3
/* Steps to perform large number modular exponentiation. Calculates Z = (X ^ Y) modulo M.
* The number of bits in the operands (X, Y) is N. N can be 32x, where x = {1,2,3,...64}, so the
* maximum number of bits in the X and Y is 2048.
* See 20.3.3 of ESP32-S3 technical manual
* 1. Wait until the hardware is ready.
* 2. Enable/disable interrupt that signals completion -- we don't use the interrupt.
* 3. Write (N_bits/32 - 1) to the RSA_MODE_REG (now called RSA_LENGTH_REG).
* Here N_bits is the maximum number of bits in X, Y and M.
* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
* 5. Load X, Y, M, r' operands to memory blocks.
* 6. Start the operation by writing 1 to RSA_MODEXP_START_REG, then wait for it
* to complete by monitoring RSA_IDLE_REG (which is now called RSA_QUERY_INTERRUPT_REG).
* 7. Read the result out.
* 8. Release the hardware lock so others can use it.
* x. Clear the interrupt flag, if you used it (we don't). */
/* 1. Wait until hardware is ready. */
if ((ret = esp_mp_hw_wait_clean()) != MP_OKAY) {
return ret;
}
/* 2. Disable completion interrupt signal; we don't use. */
DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion.
/* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
OperandBits = max(max(Xs, Ys), Ms);
if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
ESP_LOGW(TAG, "result exceeds max bit length");
return MP_VAL; /* Error: value is not able to be used. */
}
WordsForOperand = bits2words(OperandBits);
DPORT_REG_WRITE(RSA_LENGTH_REG, WordsForOperand - 1);
/* 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG) */
DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
/* 5. Load X, Y, M, r' operands. */
esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz);
esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv,
mp_count_bits(&r_inv), hwWords_sz);
/* 6. Start operation and wait until it completes. */
process_start(RSA_MODEXP_START_REG);
ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
if (MP_OKAY != ret) {
return ret;
}
/* 7. read the result form MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Ms));
/* 8. clear and release HW */
esp_mp_hw_unlock();
mp_clear(&r_inv);
return ret;
/* end if CONFIG_IDF_TARGET_ESP32S3 */
#else
/* non-ESP32S3 Xtensa (regular ESP32) */
/* Steps to use HW in the following order:
* 1. Write(N/512bits - 1) to MODEXP_MODE_REG
* 2. Write X, Y, M and r_inv to memory blocks
* need to write data to each memory block only according to the length
@ -605,12 +892,13 @@ int esp_mp_exptmod(MATH_INT_T* X, MATH_INT_T* Y, word32 Ys, MATH_INT_T* M, MATH_
wait_until_done(RSA_INTERRUPT_REG);
/* step.6 read a result form memory */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Ms));
/* step.7 clear and release hw */
/* step.7 clear and release HW */
esp_mp_hw_unlock();
mp_clear(&r_inv);
return ret;
#endif
}
#endif /* WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) &&

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/version.h>
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
(!defined(NO_AES) || !defined(NO_SHA) || !defined(NO_SHA256) ||\
@ -27,6 +28,8 @@
#include <wolfssl/wolfcrypt/wc_port.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
/*
* initialize our mutex used to lock hardware access
*
@ -79,25 +82,254 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) {
#endif
}
/*
** Version / Platform info.
**
** This could evolve into a wolfSSL-wide feature. For now, here only. See:
** https://github.com/wolfSSL/wolfssl/pull/6149
*/
#if defined(WOLFSSL_ESPIDF)
#include <esp_log.h>
#include "sdkconfig.h"
const char* TAG = "Version Info";
#define WOLFSSL_VERSION_PRINTF(...) ESP_LOGI(TAG, __VA_ARGS__)
#else
#include <stdio.h>
#define WOLFSSL_VERSION_PRINTF(...) { printf(__VA_ARGS__); printf("\n"); }
#endif
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
/*
*******************************************************************************
** Specific Platforms
*******************************************************************************
*/
#include "esp_timer.h"
#include "esp_log.h"
static uint64_t startTime = 0;
void wc_esp32TimerStart()
/*
** Specific platforms: Espressif
*/
#if defined(WOLFSSL_ESPIDF)
static int ShowExtendedSystemInfo_platform_espressif()
{
startTime = esp_timer_get_time();
#if defined(CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ)
WOLFSSL_VERSION_PRINTF("CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ: %u MHz",
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ);
#endif
#if CONFIG_IDF_TARGET_ESP32
WOLFSSL_VERSION_PRINTF("Xthal_have_ccount: %u",
Xthal_have_ccount);
/* this is the legacy stack size */
#if defined(CONFIG_MAIN_TASK_STACK_SIZE)
WOLFSSL_VERSION_PRINTF("CONFIG_MAIN_TASK_STACK_SIZE: %d",
CONFIG_MAIN_TASK_STACK_SIZE);
#endif
/* this is the modern stack size */
#if defined(CONFIG_ESP_MAIN_TASK_STACK_SIZE)
WOLFSSL_VERSION_PRINTF("CONFIG_ESP_MAIN_TASK_STACK_SIZE: %d",
CONFIG_ESP_MAIN_TASK_STACK_SIZE);
#endif
#if defined(CONFIG_TIMER_TASK_STACK_SIZE)
WOLFSSL_VERSION_PRINTF("CONFIG_TIMER_TASK_STACK_SIZE: %d",
CONFIG_TIMER_TASK_STACK_SIZE);
#endif
#if defined(CONFIG_TIMER_TASK_STACK_DEPTH)
WOLFSSL_VERSION_PRINTF("CONFIG_TIMER_TASK_STACK_DEPTH: %d",
CONFIG_TIMER_TASK_STACK_DEPTH);
#endif
#if defined(SINGLE_THREADED)
/* see also HAVE_STACK_SIZE_VERBOSE */
char thisHWM = 0;
WOLFSSL_VERSION_PRINTF("Stack HWM: %x", (size_t) &thisHWM);
#else
WOLFSSL_VERSION_PRINTF("Stack HWM: %d",
uxTaskGetStackHighWaterMark(NULL));
#endif
#elif CONFIG_IDF_TARGET_ESP32S2
WOLFSSL_VERSION_PRINTF("Xthal_have_ccount = %u",
Xthal_have_ccount);
#elif CONFIG_IDF_TARGET_ESP32C6
/* not supported at this time */
#elif CONFIG_IDF_TARGET_ESP32C3
/* not supported at this time */
#elif CONFIG_IDF_TARGET_ESP32S3
WOLFSSL_VERSION_PRINTF("Xthal_have_ccount = %u",
Xthal_have_ccount);
#elif CONFIG_IDF_TARGET_ESP32H2
/* not supported at this time */
#elif CONFIG_IDF_TARGET_ESP32C2
/* not supported at this time */
#else
/* not supported at this time */
#endif
/* check to see if we are using hardware encryption */
#if defined(NO_ESP32WROOM32_CRYPT)
WOLFSSL_VERSION_PRINTF("NO_ESP32WROOM32_CRYPT defined! "
"HW acceleration DISABLED.");
#else
/* first show what platform hardware acceleration is enabled
** (some new platforms may not be supported yet) */
#if defined(CONFIG_IDF_TARGET_ESP32)
WOLFSSL_VERSION_PRINTF("ESP32WROOM32_CRYPT is enabled for ESP32.");
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
WOLFSSL_VERSION_PRINTF("ESP32WROOM32_CRYPT is enabled for ESP32-S2.");
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
WOLFSSL_VERSION_PRINTF("ESP32WROOM32_CRYPT is enabled for ESP32-S3.");
#else
#error "ESP32WROOM32_CRYPT not yet supported on this IDF TARGET"
#endif
/* Even though enabled, some specifics may be disabled */
#if defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
WOLFSSL_VERSION_PRINTF("NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH is defined!"
"(disabled HW SHA).");
#endif
#if defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
WOLFSSL_VERSION_PRINTF("NO_WOLFSSL_ESP32WROOM32_CRYPT_AES is defined!"
"(disabled HW AES).");
#endif
#if defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)
WOLFSSL_VERSION_PRINTF("NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI defined!"
"(disabled HW RSA)");
#endif
#endif
return 0;
}
#endif
/*
*******************************************************************************
** All Platforms
*******************************************************************************
*/
/*
** All platforms: git details
*/
static int ShowExtendedSystemInfo_git()
{
#if defined(HAVE_WC_INTROSPECTION) && !defined(ALLOW_BINARY_MISMATCH_INTROSPECTION)
#pragma message("WARNING: both HAVE_VERSION_EXTENDED_INFO and " \
"HAVE_WC_INTROSPECTION are enabled. Some extended " \
"information details will not be available.")
WOLFSSL_VERSION_PRINTF("HAVE_WC_INTROSPECTION enabled. "
"Some extended system details not available.");
#else
/* Display some interesting git values that may change,
** but not desired for introspection which requires object code to be
** maximally bitwise-invariant.
*/
#if defined(LIBWOLFSSL_VERSION_GIT_ORIGIN)
/* git config --get remote.origin.url */
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_ORIGIN = %s",
LIBWOLFSSL_VERSION_GIT_ORIGIN);
#endif
#if defined(LIBWOLFSSL_VERSION_GIT_BRANCH)
/* git rev-parse --abbrev-ref HEAD */
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_BRANCH = %s",
LIBWOLFSSL_VERSION_GIT_BRANCH);
#endif
#if defined(LIBWOLFSSL_VERSION_GIT_HASH)
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_HASH = %s",
LIBWOLFSSL_VERSION_GIT_HASH);
#endif
#if defined(LIBWOLFSSL_VERSION_GIT_SHORT_HASH )
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_SHORT_HASH = %s",
LIBWOLFSSL_VERSION_GIT_SHORT_HASH);
#endif
#if defined(LIBWOLFSSL_VERSION_GIT_HASH_DATE)
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_HASH_DATE = %s",
LIBWOLFSSL_VERSION_GIT_HASH_DATE);
#endif
#endif /* else not HAVE_WC_INTROSPECTION */
return 0;
}
uint64_t wc_esp32elapsedTime()
/*
** All platforms: thread details
*/
static int ShowExtendedSystemInfo_thread()
{
/* return elapsed time since wc_esp32AesTimeStart() is called in us */
return esp_timer_get_time() - startTime;
/* all platforms: stack high water mark check */
#if defined(SINGLE_THREADED)
WOLFSSL_VERSION_PRINTF("SINGLE_THREADED");
#else
WOLFSSL_VERSION_PRINTF("NOT SINGLE_THREADED");
#endif
return 0;
}
#endif /*WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */
/*
** All Platforms: platform details
*/
static int ShowExtendedSystemInfo_platform()
{
#if defined(WOLFSSL_ESPIDF)
#if defined(CONFIG_IDF_TARGET)
WOLFSSL_VERSION_PRINTF("CONFIG_IDF_TARGET = %s",
CONFIG_IDF_TARGET);
ShowExtendedSystemInfo_platform_espressif();
#endif
#endif
return 0;
}
/*
*******************************************************************************
** The public ShowExtendedSystemInfo()
*******************************************************************************
*/
int ShowExtendedSystemInfo(void)
{
WOLFSSL_VERSION_PRINTF("Extended Version and Platform Information.");
#if defined(LIBWOLFSSL_VERSION_STRING)
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_STRING = %s",
LIBWOLFSSL_VERSION_STRING);
#endif
#if defined(LIBWOLFSSL_VERSION_HEX)
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_HEX = %x",
LIBWOLFSSL_VERSION_HEX);
#endif
#if defined(WOLFSSL_MULTI_INSTALL_WARNING)
/* CMake may have detected undesired multiple installs, so give warning. */
WOLFSSL_VERSION_PRINTF("");
WOLFSSL_VERSION_PRINTF("WARNING: Multiple wolfSSL installs found.");
WOLFSSL_VERSION_PRINTF("Check ESP-IDF and local project [components] directory.");
WOLFSSL_VERSION_PRINTF("");
#endif
ShowExtendedSystemInfo_git(); /* may be limited during active introspection */
ShowExtendedSystemInfo_platform();
ShowExtendedSystemInfo_thread();
return 0;
}
int esp_ShowExtendedSystemInfo()
{
return ShowExtendedSystemInfo();
}
#endif

View File

@ -26,6 +26,14 @@
#include <wolfssl/wolfcrypt/settings.h>
#ifdef DEBUG_WOLFSSL_VERBOSE
#if defined(WOLFSSL_ESPIDF)
#include <esp_log.h>
#else
#include <wolfssl/wolfcrypt/logging.h>
#endif
#endif
#if !defined(NO_SHA)
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
@ -50,6 +58,29 @@
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
#endif
#undef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
/* define a single keyword for simplicity & readability
*
* by default the HW acceleration is on for ESP32-WROOM32
* but individual components can be turned off.
*/
#define WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
#include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
/* Although we have hardware acceleration,
** we may need to fall back to software */
#define USE_SHA_SOFTWARE_IMPL
static const char* TAG = "wc_sha";
#elif defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
/* The ESP32C3 is different; HW crypto here. Not yet implemented.
** We'll be using software for RISC-V at this time */
static const char* TAG = "wc_sha-c3";
#else
#undef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
#endif
/* fips wrapper calls, user can call direct */
#if defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
@ -290,13 +321,11 @@
!defined(WOLFSSL_QNX_CAAM)
/* wolfcrypt/src/port/caam/caam_sha.c */
#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
#define USE_SHA_SOFTWARE_IMPL
#elif defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) || \
defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
/* This function initializes SHA.
** This is automatically called by wc_ShaHash */
static int InitSha(wc_Sha* sha)
{
int ret = 0;
@ -311,19 +340,10 @@
sha->loLen = 0;
sha->hiLen = 0;
/* always start firstblock = 1 when using hw engine */
sha->ctx.isfirstblock = 1;
sha->ctx.sha_type = SHA1;
if(sha->ctx.mode == ESP32_SHA_HW){
sha->ctx.lockDepth = 0;
/* release hw engine */
esp_sha_hw_unlock(&(sha->ctx));
}
/* always set mode as INIT
* whether using HW or SW is determined at first call of update()
*/
sha->ctx.mode = ESP32_SHA_INIT;
sha->ctx.lockDepth = 0;
/* HW needs to be carefully initialized, taking into account soft copy.
** If already in use; copy may revert to SW as needed. */
ret = esp_sha_init(&(sha->ctx), WC_HASH_TYPE_SHA);
return ret;
}
@ -526,15 +546,20 @@ static WC_INLINE void AddLength(wc_Sha* sha, word32 len)
return 0;
}
#endif /* !USE_CUSTOM_SHA_TRANSFORM */
#endif /* XTRANSFORM when USE_SHA_SOFTWARE_IMPL is enabled */
/*
** wolfCrypt InitSha256 external wrapper.
**
** we'll assume this is ALWAYS for a new, uninitialized sha256
*/
int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
{
int ret = 0;
if (sha == NULL)
if (sha == NULL) {
return BAD_FUNC_ARG;
}
sha->heap = heap;
#ifdef WOLF_CRYPTO_CB
@ -542,28 +567,32 @@ int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
sha->devCtx = NULL;
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#ifdef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
if (sha->ctx.mode != ESP32_SHA_INIT) {
/* it may be interesting to see old values during debugging */
ESP_LOGV(TAG, "Set ctx mode from prior value: %d", sha->ctx.mode);
}
/* We know this is a fresh, uninitialized item, so set to INIT */
sha->ctx.mode = ESP32_SHA_INIT;
sha->ctx.isfirstblock = 1;
sha->ctx.lockDepth = 0; /* keep track of how many times lock is called */
#endif
ret = InitSha(sha);
if (ret != 0)
if (ret != 0) {
return ret;
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
ret = wolfAsync_DevCtxInit(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA,
sha->heap, devId);
#else
(void)devId;
#endif /* WOLFSSL_ASYNC_CRYPT */
# endif /* WOLFSSL_ASYNC_CRYPT */
#ifdef WOLFSSL_IMXRT1170_CAAM
ret = wc_CAAM_HashInit(&sha->hndl, &sha->ctx, WC_HASH_TYPE_SHA);
#endif
return ret;
}
} /* wc_InitSha_ex */
/* do block size increments/updates */
int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
@ -599,8 +628,9 @@ int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
#endif /* WOLFSSL_ASYNC_CRYPT */
/* check that internal buffLen is valid */
if (sha->buffLen >= WC_SHA_BLOCK_SIZE)
if (sha->buffLen >= WC_SHA_BLOCK_SIZE) {
return BUFFER_E;
}
/* add length for final */
AddLength(sha, len);
@ -621,26 +651,32 @@ int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha->ctx.mode == ESP32_SHA_INIT) {
ESP_LOGV(TAG, "wc_ShaUpdate try hardware");
esp_sha_try_hw_lock(&sha->ctx);
}
if (sha->ctx.mode == ESP32_SHA_SW) {
ESP_LOGI(TAG, "wc_ShaUpdate process software");
ret = XTRANSFORM(sha, (const byte*)local);
}
else {
ESP_LOGV(TAG, "wc_ShaUpdate process hardware");
esp_sha_process(sha, (const byte*)local);
}
#elif defined (WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
ESP_LOGI(TAG, "wc_ShaUpdate not implemented for ESP32C3");
ret = XTRANSFORM(sha, (const byte*)local);
#else
ret = XTRANSFORM(sha, (const byte*)local);
#endif
if (ret != 0)
if (ret != 0) {
return ret;
}
sha->buffLen = 0;
}
}
sha->buffLen = 0; /* Nothing left to do, so set to zero. */
} /* (sha->buffLen == WC_SHA_BLOCK_SIZE) */
} /* (sha->buffLen > 0) Process any remainder from previous operation. */
/* process blocks */
#ifdef XTRANSFORM_LEN
@ -676,8 +712,7 @@ int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
ByteReverseWords(local32, local32, WC_SHA_BLOCK_SIZE);
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha->ctx.mode == ESP32_SHA_INIT){
esp_sha_try_hw_lock(&sha->ctx);
}
@ -722,6 +757,10 @@ int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
return 0;
}
/*
** Finalizes hashing of data. Result is placed into hash.
** Resets state of sha struct.
*/
int wc_ShaFinal(wc_Sha* sha, byte* hash)
{
int ret;
@ -749,6 +788,13 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
}
#endif /* WOLFSSL_ASYNC_CRYPT */
/* we'll add a 0x80 byte at the end,
** so make sure we have appropriate buffer length. */
if (sha->buffLen > WC_SHA_BLOCK_SIZE - 1) {
/* exit with error code if there's a bad buffer size in buffLen */
return BAD_STATE_E;
} /* buffLen check */
local[sha->buffLen++] = 0x80; /* add 1 */
/* pad with zeros */
@ -760,11 +806,13 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
/* For a fresh sha.ctx, try to use hardware acceleration */
if (sha->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha->ctx);
}
/* if HW was busy, we may need to fall back to SW. */
if (sha->ctx.mode == ESP32_SHA_SW) {
ret = XTRANSFORM(sha, (const byte*)local);
}
@ -772,13 +820,19 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
ret = esp_sha_process(sha, (const byte*)local);
}
#else
/*
** The #if defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) also falls
** though here to SW, as it's not yet implemented for HW.
*/
ret = XTRANSFORM(sha, (const byte*)local);
#endif
if (ret != 0)
if (ret != 0) {
return ret;
}
sha->buffLen = 0;
}
} /* (sha->buffLen > WC_SHA_PAD_SIZE) */
XMEMSET(&local[sha->buffLen], 0, WC_SHA_PAD_SIZE - sha->buffLen);
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
@ -801,8 +855,7 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
2 * sizeof(word32));
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha->ctx);
}
@ -812,6 +865,10 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
else {
ret = esp_sha_digest_process(sha, 1);
}
/*
** The #if defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) also falls
** though here to SW, as it's not yet implemented for HW.
*/
#else
ret = XTRANSFORM(sha, (const byte*)local);
#endif
@ -822,7 +879,7 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
XMEMCPY(hash, (byte *)&sha->digest[0], WC_SHA_DIGEST_SIZE);
(void)InitSha(sha); /* reset state */
ret = InitSha(sha); /* reset state */
return ret;
}
@ -844,12 +901,15 @@ int wc_ShaTransform(wc_Sha* sha, const unsigned char* data)
#endif /* USE_SHA_SOFTWARE_IMPL */
/*
** This function initializes SHA. This is automatically called by wc_ShaHash.
*/
int wc_InitSha(wc_Sha* sha)
{
return wc_InitSha_ex(sha, NULL, INVALID_DEVID);
}
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
void wc_ShaFree(wc_Sha* sha)
@ -882,7 +942,7 @@ void wc_ShaFree(wc_Sha* sha)
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */
#endif /* !WOLFSSL_TI_HASH */
#endif /* HAVE_FIPS */
#endif /* !HAVE_FIPS ... */
#if !defined(WOLFSSL_TI_HASH) && !defined(WOLFSSL_IMXRT_DCP)
@ -891,36 +951,38 @@ void wc_ShaFree(wc_Sha* sha)
#if !defined(WOLFSSL_RENESAS_RX64_HASH)
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
/* wc_ShaGetHash get hash value */
int wc_ShaGetHash(wc_Sha* sha, byte* hash)
{
int ret;
wc_Sha tmpSha;
#ifdef WOLFSSL_SMALL_STACK
wc_Sha* tmpSha;
#else
wc_Sha tmpSha[1];
#endif
if (sha == NULL || hash == NULL)
if (sha == NULL || hash == NULL) {
return BAD_FUNC_ARG;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
if(sha->ctx.mode == ESP32_SHA_INIT){
esp_sha_try_hw_lock(&sha->ctx);
}
if (sha->ctx.mode != ESP32_SHA_SW) {
/* TODO check SW/HW logic */
esp_sha_digest_process(sha, 0);
#ifdef WOLFSSL_SMALL_STACK
tmpSha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (tmpSha == NULL) {
return MEMORY_E;
}
#endif
ret = wc_ShaCopy(sha, &tmpSha);
ret = wc_ShaCopy(sha, tmpSha);
if (ret == 0) {
/* if HW failed, use SW */
ret = wc_ShaFinal(&tmpSha, hash);
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
sha->ctx.mode = ESP32_SHA_SW;
ret = wc_ShaFinal(tmpSha, hash);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmpSha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
}
return ret;
}
@ -941,27 +1003,29 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst)
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif
#ifdef WOLFSSL_PIC32MZ_HASH
ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
#endif
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
ret = se050_hash_copy(&src->se050Ctx, &dst->se050Ctx);
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
dst->ctx.mode = src->ctx.mode;
dst->ctx.isfirstblock = src->ctx.isfirstblock;
dst->ctx.sha_type = src->ctx.sha_type;
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
esp_sha_ctx_copy(src, dst);
#endif
#ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY;
dst->flags |= WC_HASH_FLAG_ISCOPY;
#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) */
#endif /* !defined(WOLFSSL_RENESAS_TSIP_CRYPT) ||
defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) */
#endif /* !defined(WOLFSSL_TI_HASH) && !defined(WOLFSSL_IMXRT_DCP) */
#ifdef WOLFSSL_HASH_FLAGS
int wc_ShaSetFlags(wc_Sha* sha, word32 flags)

View File

@ -103,6 +103,14 @@ on the specific device platform.
#undef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
#endif
#ifdef WOLFSSL_ESPIDF
/* Define the ESP_LOGx(TAG, "" value for output messages here.
**
** Beware of possible conflict in test.c (that one now named TEST_TAG)
*/
static const char* TAG = "wc_sha256";
#endif
/* fips wrapper calls, user can call direct */
#if defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
@ -731,16 +739,16 @@ static int InitSha256(wc_Sha256* sha256)
#define NEED_SOFT_SHA256
/*
* soft SHA needs initialization digest, but HW does not.
*/
** soft SHA needs initialization digest, but HW does not.
*/
static int InitSha256(wc_Sha256* sha256)
{
int ret = 0; /* zero = success */
if (sha256 == NULL)
if (sha256 == NULL) {
return BAD_FUNC_ARG;
}
XMEMSET(sha256->digest, 0, sizeof(sha256->digest));
sha256->digest[0] = 0x6A09E667L;
sha256->digest[1] = 0xBB67AE85L;
sha256->digest[2] = 0x3C6EF372L;
@ -754,41 +762,33 @@ static int InitSha256(wc_Sha256* sha256)
sha256->loLen = 0;
sha256->hiLen = 0;
/* always start firstblock = 1 when using hw engine */
sha256->ctx.isfirstblock = 1;
sha256->ctx.sha_type = SHA2_256;
if(sha256->ctx.mode == ESP32_SHA_HW) {
/* release hw */
esp_sha_hw_unlock(&(sha256->ctx));
}
/* always set mode as INIT
* whether using HW or SW is determined at first call of update()
*/
sha256->ctx.mode = ESP32_SHA_INIT;
ret = esp_sha_init(&(sha256->ctx), WC_HASH_TYPE_SHA256);
return ret;
}
/*
* wolfCrypt InitSha256 external wrapper
*/
** wolfCrypt InitSha256 external wrapper.
**
** we'll assume this is ALWAYS for a new, uninitialized sha256
*/
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
{
int ret = 0; /* zero = success */
if (sha256 == NULL)
return BAD_FUNC_ARG;
XMEMSET(sha256, 0, sizeof(wc_Sha256));
sha256->ctx.mode = ESP32_SHA_INIT;
sha256->ctx.isfirstblock = 1;
sha256->ctx.lockDepth = 0; /* we'll keep track of our own lock depth */
(void)devId;
if (sha256 == NULL) {
return BAD_FUNC_ARG;
}
ret = InitSha256(sha256);
#ifdef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
/* We know this is a fresh, uninitialized item, so set to INIT */
if (sha256->ctx.mode != ESP32_SHA_INIT) {
ESP_LOGV(TAG, "Set ctx mode from prior value: "
"%d", sha256->ctx.mode);
}
sha256->ctx.mode = ESP32_SHA_INIT;
#endif
return ret;
return InitSha256(sha256);
}
#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \
@ -1100,15 +1100,17 @@ static int InitSha256(wc_Sha256* sha256)
#endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha256->ctx.mode == ESP32_SHA_INIT ||
sha256->ctx.mode == ESP32_SHA_FAIL_NEED_UNROLL) {
if (sha256->ctx.mode == ESP32_SHA_INIT) {
ESP_LOGV(TAG, "Sha256Update try hardware");
esp_sha_try_hw_lock(&sha256->ctx);
}
if (sha256->ctx.mode == ESP32_SHA_SW) {
ESP_LOGV(TAG, "Sha256Update process software");
ret = XTRANSFORM(sha256, (const byte*)local);
}
else {
ESP_LOGV(TAG, "Sha256Update process hardware");
esp_sha256_process(sha256, (const byte*)local);
}
#else
@ -1183,15 +1185,18 @@ static int InitSha256(wc_Sha256* sha256)
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha256->ctx.mode == ESP32_SHA_INIT){
ESP_LOGV(TAG, "Sha256Update try hardware loop");
esp_sha_try_hw_lock(&sha256->ctx);
}
if (sha256->ctx.mode == ESP32_SHA_SW) {
ESP_LOGV(TAG, "Sha256Update process software loop");
ret = XTRANSFORM(sha256, (const byte*)local32);
}
else {
ESP_LOGV(TAG, "Sha256Update process hardware");
esp_sha256_process(sha256, (const byte*)local32);
}
#else
#else
ret = XTRANSFORM(sha256, (const byte*)local32);
#endif
@ -1255,6 +1260,13 @@ static int InitSha256(wc_Sha256* sha256)
return BAD_FUNC_ARG;
}
/* we'll add a 0x80 byte at the end,
** so make sure we have appropriate buffer length. */
if (sha256->buffLen > WC_SHA256_BLOCK_SIZE - 1) {
/* exit with error code if there's a bad buffer size in buffLen */
return BAD_STATE_E;
} /* buffLen check */
local = (byte*)sha256->buffer;
local[sha256->buffLen++] = 0x80; /* add 1 */
@ -1400,8 +1412,9 @@ static int InitSha256(wc_Sha256* sha256)
#endif /* WOLFSSL_ASYNC_CRYPT */
ret = Sha256Final(sha256);
if (ret != 0)
if (ret != 0) {
return ret;
}
#if defined(LITTLE_ENDIAN_ORDER)
ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE);
@ -1572,6 +1585,10 @@ static int InitSha256(wc_Sha256* sha256)
sha224->used = 0;
#endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
/* not to be confused with HAS512_224 */
sha224->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
#endif
return ret;
}
@ -1591,9 +1608,20 @@ static int InitSha256(wc_Sha256* sha256)
sha224->W = NULL;
#endif
#ifdef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
/* We know this is a fresh, uninitialized item, so set to INIT */
if (sha224->ctx.mode != ESP32_SHA_SW) {
ESP_LOGV(TAG, "Set sha224 ctx mode init to ESP32_SHA_SW. "
"Prior value: %d", sha224->ctx.mode);
}
/* no sha224 HW support is available, set to SW */
sha224->ctx.mode = ESP32_SHA_SW;
#endif
ret = InitSha224(sha224);
if (ret != 0)
if (ret != 0) {
return ret;
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
ret = wolfAsync_DevCtxInit(&sha224->asyncDev,
@ -1604,6 +1632,16 @@ static int InitSha256(wc_Sha256* sha256)
#ifdef WOLFSSL_IMXRT1170_CAAM
ret = wc_CAAM_HashInit(&sha224->hndl, &sha224->ctx, WC_HASH_TYPE_SHA224);
#endif
#ifdef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
if (sha224->ctx.mode != ESP32_SHA_INIT) {
ESP_LOGV("SHA224", "Set ctx mode from prior value: "
"%d", sha224->ctx.mode);
}
/* We know this is a fresh, uninitialized item, so set to INIT */
sha224->ctx.mode = ESP32_SHA_INIT;
#endif
return ret;
}
@ -1623,6 +1661,10 @@ static int InitSha256(wc_Sha256* sha256)
}
#endif /* WOLFSSL_ASYNC_CRYPT */
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
sha224->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
#endif
ret = Sha256Update((wc_Sha256*)sha224, data, len);
return ret;
@ -1645,6 +1687,10 @@ static int InitSha256(wc_Sha256* sha256)
}
#endif /* WOLFSSL_ASYNC_CRYPT */
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
sha224->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
#endif
ret = Sha256Final((wc_Sha256*)sha224);
if (ret != 0)
return ret;
@ -1785,11 +1831,11 @@ void wc_Sha256Free(wc_Sha256* sha256)
* the unexpected. by the time free is called, the hardware
* should have already been released (lockDepth = 0)
*/
InitSha256(sha256); /* unlock mutex, set mode to ESP32_SHA_INIT */
ESP_LOGV("sha256", "Alert: hardware unlock needed in wc_Sha256Free.");
(void)InitSha256(sha256); /* unlock mutex, set mode to ESP32_SHA_INIT */
ESP_LOGV(TAG, "Alert: hardware unlock needed in wc_Sha256Free.");
}
else {
ESP_LOGV("sha256", "Hardware unlock not needed in wc_Sha256Free.");
ESP_LOGV(TAG, "Hardware unlock not needed in wc_Sha256Free.");
}
#endif
}
@ -1865,12 +1911,14 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz)
int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst)
{
int ret = 0;
int ret = 0; /* assume success unless proven otherwise */
if (src == NULL || dst == NULL)
if (src == NULL || dst == NULL) {
return BAD_FUNC_ARG;
}
XMEMCPY(dst, src, sizeof(wc_Sha224));
#ifdef WOLFSSL_SMALL_STACK_CACHE
dst->W = NULL;
#endif
@ -1883,9 +1931,15 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz)
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
ret = esp_sha224_ctx_copy(src, dst);
#endif
#ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif
#if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap,
@ -1972,32 +2026,13 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
}
#endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
/* ESP32 hardware can only handle only 1 active hardware hashing
* at a time. If the mutex lock is acquired the first time then
* that Sha256 instance has exclusive access to hardware. The
* final or free needs to release the mutex. Operations that
* do not get the lock fallback to software based Sha256 */
if (sha256->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha256->ctx);
}
if (sha256->ctx.mode == ESP32_SHA_HW) {
esp_sha256_digest_process(sha256, 0);
}
#endif
ret = wc_Sha256Copy(sha256, tmpSha256);
if (ret == 0) {
ret = wc_Sha256Final(tmpSha256, hash);
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
sha256->ctx.mode = ESP32_SHA_SW;
#endif
wc_Sha256Free(tmpSha256);
wc_Sha256Free(tmpSha256); /* TODO move outside brackets? */
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmpSha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
@ -2008,8 +2043,9 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
{
int ret = 0;
if (src == NULL || dst == NULL)
if (src == NULL || dst == NULL) {
return BAD_FUNC_ARG;
}
XMEMCPY(dst, src, sizeof(wc_Sha256));
@ -2029,20 +2065,19 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif
#ifdef WOLFSSL_PIC32MZ_HASH
ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
#endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
dst->ctx.mode = src->ctx.mode;
dst->ctx.isfirstblock = src->ctx.isfirstblock;
dst->ctx.sha_type = src->ctx.sha_type;
dst->ctx.lockDepth = src->ctx.lockDepth;
esp_sha256_ctx_copy(src, dst);
#endif
#ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif
#if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);

View File

@ -28,6 +28,21 @@
#if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PSOC6_CRYPTO)
/* determine if we are using Espressif SHA hardware acceleration */
#undef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
/* define a single keyword for simplicity & readability
*
* by default the HW acceleration is on for ESP32-WROOM32
* but individual components can be turned off.
*/
#define WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
static const char* TAG = "wc_sha_512";
#else
#undef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
#endif
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
#define FIPS_NO_WRAPPERS
@ -279,21 +294,13 @@ static int InitSha512(wc_Sha512* sha512)
sha512->loLen = 0;
sha512->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
sha512->ctx.sha_type = SHA2_512;
/* always start firstblock = 1 when using hw engine */
sha512->ctx.isfirstblock = 1;
if(sha512->ctx.mode == ESP32_SHA_HW) {
/* release hw */
esp_sha_hw_unlock(&(sha512->ctx));
}
/* always set mode as INIT
* whether using HW or SW is determined at first call of update()
*/
sha512->ctx.mode = ESP32_SHA_INIT;
/* HW needs to be carefully initialized, taking into account soft copy.
** If already in use; copy may revert to SW as needed. */
esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512);
#endif
#ifdef WOLFSSL_HASH_FLAGS
sha512->flags = 0;
#endif
@ -327,21 +334,15 @@ static int InitSha512_224(wc_Sha512* sha512)
sha512->loLen = 0;
sha512->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
sha512->ctx.sha_type = SHA2_512;
/* always start firstblock = 1 when using hw engine */
sha512->ctx.isfirstblock = 1;
if(sha512->ctx.mode == ESP32_SHA_HW) {
/* release hw */
esp_sha_hw_unlock(&(sha512->ctx));
}
/* always set mode as INIT
* whether using HW or SW is determined at first call of update()
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
/* HW needs to be carefully initialized, taking into account soft copy.
** If already in use; copy may revert to SW as needed.
**
** Note for original ESP32, there's no HW for SHA512/224
*/
sha512->ctx.mode = ESP32_SHA_INIT;
esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_224);
#endif
#ifdef WOLFSSL_HASH_FLAGS
sha512->flags = 0;
#endif
@ -375,21 +376,15 @@ static int InitSha512_256(wc_Sha512* sha512)
sha512->loLen = 0;
sha512->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
sha512->ctx.sha_type = SHA2_512;
/* always start firstblock = 1 when using hw engine */
sha512->ctx.isfirstblock = 1;
if(sha512->ctx.mode == ESP32_SHA_HW) {
/* release hw */
esp_sha_hw_unlock(&(sha512->ctx));
}
/* always set mode as INIT
* whether using HW or SW is determined at first call of update()
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
/* HW needs to be carefully initialized, taking into account soft copy.
** If already in use; copy may revert to SW as needed.
**
** Note for original ESP32, there's no HW for SHA512/2256.
*/
sha512->ctx.mode = ESP32_SHA_INIT;
esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_256);
#endif
#ifdef WOLFSSL_HASH_FLAGS
sha512->flags = 0;
#endif
@ -578,8 +573,10 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
{
int ret = 0;
if (sha512 == NULL)
if (sha512 == NULL) {
return BAD_FUNC_ARG;
}
sha512->heap = heap;
#ifdef WOLFSSL_SMALL_STACK_CACHE
@ -590,6 +587,7 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
sha512->devCtx = NULL;
#endif
/* call the initialization function pointed to by initfp */
ret = initfp(sha512);
if (ret != 0)
return ret;
@ -614,10 +612,19 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
ret = wc_CAAM_HashInit(&sha512->hndl, &sha512->ctx, WC_HASH_TYPE_SHA512);
#endif
return ret;
}
} /* InitSha512_Family */
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
{
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha512->ctx.mode != ESP32_SHA_INIT) {
ESP_LOGV(TAG, "Set ctx mode from prior value: "
"%d", sha512->ctx.mode);
}
/* We know this is a fresh, uninitialized item, so set to INIT */
sha512->ctx.mode = ESP32_SHA_INIT;
#endif
return InitSha512_Family(sha512, heap, devId, InitSha512);
}
@ -625,6 +632,10 @@ int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
{
#ifdef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
/* No SHA512/224 HW support is available, set to SW. */
sha512->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
#endif
return InitSha512_Family(sha512, heap, devId, InitSha512_224);
}
#endif /* !WOLFSSL_NOSHA512_224 ... */
@ -633,6 +644,10 @@ int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
{
#ifdef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
/* No SHA512/256 HW support is available on ESP32, set to SW. */
sha512->ctx.mode = ESP32_SHA_SW;
#endif
return InitSha512_Family(sha512, heap, devId, InitSha512_256);
}
#endif /* !WOLFSSL_NOSHA512_256 ... */
@ -836,6 +851,8 @@ static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 le
}
ret = esp_sha512_process(sha512);
if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){
ByteReverseWords64(sha512->buffer, sha512->buffer,
WC_SHA512_BLOCK_SIZE);
ret = Transform_Sha512(sha512);
}
#endif
@ -903,14 +920,18 @@ static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 le
if(sha512->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha512->ctx);
}
ret = esp_sha512_process(sha512);
if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){
if (sha512->ctx.mode == ESP32_SHA_SW) {
ByteReverseWords64(sha512->buffer, sha512->buffer,
WC_SHA512_BLOCK_SIZE);
ret = Transform_Sha512(sha512);
}
else {
ret = esp_sha512_process(sha512);
}
#endif
if (ret != 0)
break;
}
} /* while (len >= WC_SHA512_BLOCK_SIZE) */
}
#endif
@ -962,8 +983,8 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
static WC_INLINE int Sha512Final(wc_Sha512* sha512)
{
byte* local;
int ret;
byte* local;
if (sha512 == NULL) {
return BAD_FUNC_ARG;
@ -971,6 +992,12 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512)
local = (byte*)sha512->buffer;
/* we'll add a 0x80 byte at the end,
** so make sure we have appropriate buffer length. */
if (sha512->buffLen > WC_SHA512_BLOCK_SIZE - 1) {
return BAD_STATE_E;
} /* buffLen check */
local[sha512->buffLen++] = 0x80; /* add 1 */
/* pad with zeros */
@ -990,24 +1017,29 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512)
WC_SHA512_BLOCK_SIZE);
#endif
}
#endif /* LITTLE_ENDIAN_ORDER */
#if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
ret = Transform_Sha512(sha512);
#else
if(sha512->ctx.mode == ESP32_SHA_INIT) {
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha512->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha512->ctx);
}
ret = esp_sha512_process(sha512);
if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){
}
if (sha512->ctx.mode == ESP32_SHA_SW) {
ByteReverseWords64(sha512->buffer,sha512->buffer,
WC_SHA512_BLOCK_SIZE);
ret = Transform_Sha512(sha512);
}
#endif
else {
ret = esp_sha512_process(sha512);
}
#else
ret = Transform_Sha512(sha512);
#endif
if (ret != 0)
return ret;
sha512->buffLen = 0;
}
} /* (sha512->buffLen > WC_SHA512_PAD_SIZE) pad with zeros */
XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);
/* put lengths in bits */
@ -1041,18 +1073,28 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512)
&(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
#endif
#if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
ret = Transform_Sha512(sha512);
#else
if(sha512->ctx.mode == ESP32_SHA_INIT) {
/* typically for tiny block: first = last */
esp_sha_try_hw_lock(&sha512->ctx);
}
ret = esp_sha512_digest_process(sha512, 1);
if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW) {
if (sha512->ctx.mode == ESP32_SHA_SW) {
ByteReverseWords64(sha512->buffer,
sha512->buffer,
WC_SHA512_BLOCK_SIZE);
sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
ret = Transform_Sha512(sha512);
}
else {
ret = esp_sha512_digest_process(sha512, 1);
}
#endif
if (ret != 0)
return ret;
@ -1179,6 +1221,7 @@ void wc_Sha512Free(wc_Sha512* sha512)
wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);
#endif /* WOLFSSL_ASYNC_CRYPT */
}
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_KCAPI_HASH)
/* Apply SHA512 transformation to the data */
/* @param sha a pointer to wc_Sha512 structure */
@ -1302,24 +1345,16 @@ static int InitSha384(wc_Sha384* sha384)
sha384->loLen = 0;
sha384->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
sha384->ctx.sha_type = SHA2_384;
/* always start firstblock = 1 when using hw engine */
sha384->ctx.isfirstblock = 1;
if(sha384->ctx.mode == ESP32_SHA_HW) {
/* release hw */
esp_sha_hw_unlock(&(sha384->ctx));
}
/* always set mode as INIT
* whether using HW or SW is determined at first call of update()
*/
sha384->ctx.mode = ESP32_SHA_INIT;
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
/* HW needs to be carefully initialized, taking into account soft copy.
** If already in use; copy may revert to SW as needed. */
esp_sha_init(&(sha384->ctx), WC_HASH_TYPE_SHA384);
#endif
#ifdef WOLFSSL_HASH_FLAGS
sha384->flags = 0;
#endif
#ifdef WOLFSSL_HASH_KEEP
sha384->msg = NULL;
sha384->len = 0;
@ -1426,10 +1461,19 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
sha384->devId = devId;
sha384->devCtx = NULL;
#endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha384->ctx.mode != ESP32_SHA_INIT) {
ESP_LOGV(TAG, "Set ctx mode from prior value: "
"%d", sha384->ctx.mode);
}
/* We know this is a fresh, uninitialized item, so set to INIT */
sha384->ctx.mode = ESP32_SHA_INIT;
#endif
ret = InitSha384(sha384);
if (ret != 0)
if (ret != 0) {
return ret;
}
#if defined(USE_INTEL_SPEEDUP) && \
(defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
@ -1525,24 +1569,10 @@ static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash,
}
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
if (sha512->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha512->ctx);
}
if (sha512->ctx.mode != ESP32_SHA_SW) {
esp_sha512_digest_process(sha512, 0);
}
#endif
/* copy this sha512 into tmpSha */
ret = wc_Sha512Copy(sha512, tmpSha512);
if (ret == 0) {
ret = finalfp(tmpSha512, hash);
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
sha512->ctx.mode = ESP32_SHA_SW;;
#endif
wc_Sha512Free(tmpSha512);
}
@ -1562,8 +1592,9 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
{
int ret = 0;
if (src == NULL || dst == NULL)
if (src == NULL || dst == NULL) {
return BAD_FUNC_ARG;
}
XMEMCPY(dst, src, sizeof(wc_Sha512));
#ifdef WOLFSSL_SMALL_STACK_CACHE
@ -1578,15 +1609,17 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
dst->ctx.mode = src->ctx.mode;
dst->ctx.isfirstblock = src->ctx.isfirstblock;
dst->ctx.sha_type = src->ctx.sha_type;
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (ret == 0) {
ret = esp_sha512_ctx_copy(src, dst);
}
#endif
#ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif
#if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
@ -1626,6 +1659,7 @@ int wc_InitSha512_224(wc_Sha512* sha)
{
return wc_InitSha512_224_ex(sha, NULL, INVALID_DEVID);
}
int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len)
{
return wc_Sha512Update(sha, data, len);
@ -1640,16 +1674,19 @@ int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash)
{
return Sha512FinalRaw(sha, hash, WC_SHA512_224_DIGEST_SIZE);
}
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
{
return Sha512_Family_Final(sha512, hash, WC_SHA512_224_DIGEST_SIZE,
InitSha512_224);
}
#endif
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
void wc_Sha512_224Free(wc_Sha512* sha)
{
wc_Sha512Free(sha);
}
#if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
@ -1660,11 +1697,12 @@ int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
{
return Sha512_Family_GetHash(sha512, hash, wc_Sha512_224Final);
}
int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst)
{
return wc_Sha512Copy(src, dst);
}
#endif
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
#ifdef WOLFSSL_HASH_FLAGS
int wc_Sha512_224SetFlags(wc_Sha512* sha, word32 flags)
@ -1694,6 +1732,7 @@ int wc_InitSha512_256(wc_Sha512* sha)
{
return wc_InitSha512_256_ex(sha, NULL, INVALID_DEVID);
}
int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len)
{
return wc_Sha512Update(sha, data, len);
@ -1707,16 +1746,19 @@ int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash)
{
return Sha512FinalRaw(sha, hash, WC_SHA512_256_DIGEST_SIZE);
}
int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
{
return Sha512_Family_Final(sha512, hash, WC_SHA512_256_DIGEST_SIZE,
InitSha512_256);
}
#endif
void wc_Sha512_256Free(wc_Sha512* sha)
{
wc_Sha512Free(sha);
}
#if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
@ -1782,23 +1824,10 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
}
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
if (sha384->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha384->ctx);
}
if (sha384->ctx.mode != ESP32_SHA_SW) {
esp_sha512_digest_process(sha384, 0);
}
#endif
/* copy this sha384 into tmpSha */
ret = wc_Sha384Copy(sha384, tmpSha384);
if (ret == 0) {
ret = wc_Sha384Final(tmpSha384, hash);
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
sha384->ctx.mode = ESP32_SHA_SW;
#endif
wc_Sha384Free(tmpSha384);
}
@ -1818,6 +1847,7 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
}
XMEMCPY(dst, src, sizeof(wc_Sha384));
#ifdef WOLFSSL_SMALL_STACK_CACHE
dst->W = NULL;
#endif
@ -1830,15 +1860,15 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
dst->ctx.mode = src->ctx.mode;
dst->ctx.isfirstblock = src->ctx.isfirstblock;
dst->ctx.sha_type = src->ctx.sha_type;
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
esp_sha384_ctx_copy(src, dst);
#endif
#ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif
#if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);

View File

@ -28,7 +28,6 @@
#include "esp_idf_version.h"
#include "esp_types.h"
#include "esp_log.h"
#include "esp_random.h"
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
#undef LOG_LOCAL_LEVEL
@ -39,31 +38,45 @@
#endif
#include <freertos/FreeRTOS.h>
#include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h"
#if ESP_IDF_VERSION_MAJOR < 5
#include "soc/cpu.h"
#endif
#if ESP_IDF_VERSION_MAJOR >= 5
#include "esp_private/periph_ctrl.h"
#else
#include "driver/periph_ctrl.h"
#endif
#if ESP_IDF_VERSION_MAJOR >= 4
#include <esp32/rom/ets_sys.h>
#if defined(CONFIG_IDF_TARGET_ESP32C3)
/* no includes for ESP32C3 at this time (no HW implemented yet) */
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#include <esp32s3/rom/ets_sys.h>
#include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h"
#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR >= 5
#include "esp_private/periph_ctrl.h"
#else
#include "driver/periph_ctrl.h"
#endif
#else
#include <rom/ets_sys.h>
#include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h"
#if ESP_IDF_VERSION_MAJOR < 5
#include "soc/cpu.h"
#endif
#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR >= 5
#include "esp_private/periph_ctrl.h"
#else
#include "driver/periph_ctrl.h"
#endif
#if ESP_IDF_VERSION_MAJOR >= 4
#include <esp32/rom/ets_sys.h>
#else
#include <rom/ets_sys.h>
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
int esp_ShowExtendedSystemInfo(void);
int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex);
int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBloxkTime);
int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
@ -72,8 +85,6 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#if ESP_IDF_VERSION_MAJOR >= 4
#include "esp32/rom/aes.h"
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#include "esp32s3/rom/aes.h"
#else
#include "rom/aes.h"
#endif
@ -95,14 +106,15 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
void wc_esp32TimerStart();
uint64_t wc_esp32elapsedTime();
void wc_esp32TimerStart(void);
uint64_t wc_esp32elapsedTime(void);
#endif /* WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */
#if (!defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \
defined(WOLFSSL_SHA512)) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
#if !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) && \
(!defined(NO_SHA) || !defined(NO_SHA256) || \
defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) \
)
/* RAW hash function APIs are not implemented with esp32 hardware acceleration*/
#define WOLFSSL_NO_HASH_RAW
@ -118,50 +130,67 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#undef SHA_CTX
typedef enum {
ESP32_SHA_INIT = 0,
ESP32_SHA_HW = 1,
ESP32_SHA_SW = 2,
typedef enum
{
ESP32_SHA_INIT = 0,
ESP32_SHA_HW = 1,
ESP32_SHA_SW = 2,
ESP32_SHA_HW_COPY = 3,
ESP32_SHA_FAIL_NEED_UNROLL = -1
} ESP32_MODE;
typedef struct {
byte isfirstblock;
typedef struct
{
/* pointer to object the initialized HW; to track copies */
void* initializer;
ESP32_MODE mode; /* typically 0 init, 1 HW, 2 SW */
/* an ESP32_MODE value; typically:
** 0 init,
** 1 HW,
** 2 SW */
ESP32_MODE mode;
/* see esp_rom/include/esp32/rom/sha.h
**
** the Espressif type: SHA1, SHA256, etc.
*/
enum SHA_TYPE sha_type;
/* we'll keep track of our own locks.
* actual enable/disable only occurs for ref_counts[periph] == 0 */
int lockDepth; /* see ref_counts[periph] in periph_ctrl.c */
** actual enable/disable only occurs for ref_counts[periph] == 0
**
** see ref_counts[periph] in periph_ctrl.c */
byte lockDepth:7; /* 7 bits for a small number, pack with below. */
/* ESP32S3 defines SHA_TYPE to enum, all other ESP32s define it to
typedef enum. */
#if defined(CONFIG_IDF_TARGET_ESP32S3)
SHA_TYPE sha_type;
#else
enum SHA_TYPE sha_type;
#endif
/* 0 (false) this is NOT first block.
** 1 (true ) this is first block. */
byte isfirstblock:1; /* 1 bit only for true / false */
} WC_ESP32SHA;
int esp_sha_init(WC_ESP32SHA* ctx, enum wc_HashType hash_type);
int esp_sha_init_ctx(WC_ESP32SHA* ctx);
int esp_sha_try_hw_lock(WC_ESP32SHA* ctx);
int esp_sha_hw_unlock(WC_ESP32SHA* ctx);
struct wc_Sha;
int esp_sha_ctx_copy(struct wc_Sha* src, struct wc_Sha* dst);
int esp_sha_digest_process(struct wc_Sha* sha, byte blockprocess);
int esp_sha_process(struct wc_Sha* sha, const byte* data);
#ifndef NO_SHA256
struct wc_Sha256;
int esp_sha224_ctx_copy(struct wc_Sha256* src, struct wc_Sha256* dst);
int esp_sha256_ctx_copy(struct wc_Sha256* src, struct wc_Sha256* dst);
int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess);
int esp_sha256_process(struct wc_Sha256* sha, const byte* data);
int esp32_Transform_Sha256_demo(struct wc_Sha256* sha256, const byte* data);
#endif
/* TODO do we really call esp_sha512_process for WOLFSSL_SHA384 ? */
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
struct wc_Sha512;
int esp_sha384_ctx_copy(struct wc_Sha512* src, struct wc_Sha512* dst);
int esp_sha512_ctx_copy(struct wc_Sha512* src, struct wc_Sha512* dst);
int esp_sha512_process(struct wc_Sha512* sha);
int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc);
#endif