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/conf.c"
"${WOLFSSL_ROOT}/src/misc.c" "${WOLFSSL_ROOT}/src/misc.c"
"${WOLFSSL_ROOT}/src/pk.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/ssl_misc.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/x509.c" "${WOLFSSL_ROOT}/src/x509.c"
"${WOLFSSL_ROOT}/src/x509_str.c" "${WOLFSSL_ROOT}/src/x509_str.c"
@ -197,6 +199,7 @@ set(COMPONENT_SRCEXCLUDE
"${WOLFSSL_ROOT}/wolfcrypt/src/misc.c" "${WOLFSSL_ROOT}/wolfcrypt/src/misc.c"
"${EXCLUDE_ASM}" "${EXCLUDE_ASM}"
) )
set(COMPONENT_PRIV_INCLUDEDIRS ${IDF_PATH}/components/driver/include)
register_component() register_component()

View File

@ -190,6 +190,8 @@ set(COMPONENT_SRCEXCLUDE
"${WOLFSSL_ROOT}/src/conf.c" "${WOLFSSL_ROOT}/src/conf.c"
"${WOLFSSL_ROOT}/src/misc.c" "${WOLFSSL_ROOT}/src/misc.c"
"${WOLFSSL_ROOT}/src/pk.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/ssl_misc.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/x509.c" "${WOLFSSL_ROOT}/src/x509.c"
"${WOLFSSL_ROOT}/src/x509_str.c" "${WOLFSSL_ROOT}/src/x509_str.c"

View File

@ -178,7 +178,8 @@ void app_main(void)
#elif defined(CONFIG_IDF_TARGET_ESP32S2) #elif defined(CONFIG_IDF_TARGET_ESP32S2)
#error "ESP32WROOM32_CRYPT not yet supported on ESP32-S2" #error "ESP32WROOM32_CRYPT not yet supported on ESP32-S2"
#elif defined(CONFIG_IDF_TARGET_ESP32S3) #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 #else
ESP_LOGI(TAG, "ESP32WROOM32_CRYPT is enabled."); ESP_LOGI(TAG, "ESP32WROOM32_CRYPT is enabled.");
#endif #endif

View File

@ -66,7 +66,21 @@
#include <wolfssl/wolfcrypt/wolfmath.h> #include <wolfssl/wolfcrypt/wolfmath.h>
#ifdef WOLFSSL_ESPIDF #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> #include <esp_log.h>
#endif #endif
@ -1001,13 +1015,18 @@ static const char* bench_desc_words[][15] = {
** the Espressif `unsigned xthal_get_ccount()` which is known to overflow ** the Espressif `unsigned xthal_get_ccount()` which is known to overflow
** at least once during full benchmark tests. ** 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 */ /* reminder: unsigned long long max = 18,446,744,073,709,551,615 */
/* the currently observed clock counter value */ /* 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, /* if the current value is less than the previous value,
** we likely overflowed at least once. ** 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); _xthal_get_ccount_ex += (thisVal - _xthal_get_ccount_last);
/* all of this took some time, so reset the "last seen" value */ /* 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; return _xthal_get_ccount_ex;
} }
@ -4992,7 +5015,7 @@ exit:
WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT); WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
} }
#endif #endif /* WOLFSSL_NOSHA512_224 && !FIPS ... */
#if !defined(WOLFSSL_NOSHA512_256) && \ #if !defined(WOLFSSL_NOSHA512_256) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) (!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); WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
} }
#endif /* WOLFSSL_NOSHA512_256 && !FIPS ... */
#endif #endif /* WOLFSSL_SHA512 */
#endif
#ifdef WOLFSSL_SHA3 #ifdef WOLFSSL_SHA3
@ -7494,8 +7516,9 @@ void bench_eccEncrypt(int curveId)
if (ret != 0) if (ret != 0)
goto exit; goto exit;
for (i = 0; i < (int)sizeof(msg); i++) for (i = 0; i < (int)sizeof(msg); i++) {
msg[i] = (byte)i; msg[i] = (byte)i;
}
bench_stats_start(&count, &start); bench_stats_start(&count, &start);
do { do {
@ -9095,6 +9118,14 @@ static int string_matches(const char* arg, const char* str)
#ifdef WOLFSSL_ESPIDF #ifdef WOLFSSL_ESPIDF
int argc = construct_argv(); int argc = construct_argv();
char** argv = (char**)__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 #endif
return wolfcrypt_benchmark_main(argc, argv); return wolfcrypt_benchmark_main(argc, argv);

View File

@ -35,10 +35,12 @@
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES) !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
#include "sdkconfig.h" /* programmatically generated from sdkconfig */
#include <wolfssl/wolfcrypt/aes.h> #include <wolfssl/wolfcrypt/aes.h>
#include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.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"; static const char* TAG = "wolf_hw_aes";
/* mutex */ /* mutex */
@ -67,27 +69,36 @@ static int esp_aes_hw_InUse()
} }
else { else {
ESP_LOGE(TAG, "aes mutex initialization failed."); ESP_LOGE(TAG, "aes mutex initialization failed.");
return -1;
} }
} }
else { else {
/* esp aes has already been initialized */ /* esp aes has already been initialized */
} }
/* lock hardware */ if (ret == 0) {
ret = esp_CryptHwMutexLock(&aes_mutex, portMAX_DELAY); /* lock hardware */
ret = esp_CryptHwMutexLock(&aes_mutex, portMAX_DELAY);
if(ret != 0) { }
else {
ESP_LOGE(TAG, "aes engine lock failed."); 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"); ESP_LOGV(TAG, "leave esp_aes_hw_InUse");
return ret; return ret;
} } /* esp_aes_hw_InUse */
/* /*
* release hw engine * release hw engine
@ -102,20 +113,22 @@ static void esp_aes_hw_Leave( void )
esp_CryptHwMutexUnLock(&aes_mutex); esp_CryptHwMutexUnLock(&aes_mutex);
ESP_LOGV(TAG, "leave esp_aes_hw_Leave"); ESP_LOGV(TAG, "leave esp_aes_hw_Leave");
} } /* esp_aes_hw_Leave */
/* /*
* set key to hardware key registers. * 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 i;
word32 mode_ = 0; word32 mode_ = 0;
ESP_LOGV(TAG, " enter esp_aes_hw_Set_KeyMode"); ESP_LOGV(TAG, " enter esp_aes_hw_Set_KeyMode");
/* check mode */ /* check mode */
if(mode == ESP32_AES_UPDATEKEY_ENCRYPT) { if (mode == ESP32_AES_UPDATEKEY_ENCRYPT) {
mode_ = 0; mode_ = 0;
} }
else { else {
@ -124,47 +137,89 @@ static void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
} }
else { else {
ESP_LOGE(TAG, " >> unexpected error."); 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 */ return ret;
for(i=0; i<(ctx->keylen)/sizeof(word32); i++){ } /* esp_aes_hw_Set_KeyMode */
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");
}
/* /*
* esp_aes_bk
* Process a one block of AES * 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) static void esp_aes_bk(const byte* in, byte* out)
{ {
const word32 *inwords = (const word32 *)in; const word32 *inwords = (const word32 *)in;
#if ESP_IDF_VERSION_MAJOR >= 4 #if ESP_IDF_VERSION_MAJOR >= 4
uint32_t *outwords = (uint32_t *)out; uint32_t *outwords = (uint32_t *)out;
#else #else
word32 *outwords = (word32 *)out; word32 *outwords = (word32 *)out;
#endif #endif
ESP_LOGV(TAG, "enter esp_aes_bk"); 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 */ /* copy text for encrypting/decrypting blocks */
DPORT_REG_WRITE(AES_TEXT_BASE, inwords[0]); DPORT_REG_WRITE(AES_TEXT_BASE, inwords[0]);
DPORT_REG_WRITE(AES_TEXT_BASE + 4, inwords[1]); 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); DPORT_REG_WRITE(AES_START_REG, 1);
/* wait until finishing the process */ /* wait until finishing the process */
while(1) { while (1) {
if(DPORT_REG_READ(AES_IDLE_REG) == 1) if (DPORT_REG_READ(AES_IDLE_REG) == 1) {
break; break;
}
} }
/* read-out blocks */ /* read-out blocks */
esp_dport_access_read_buffer(outwords, AES_TEXT_BASE, 4); esp_dport_access_read_buffer(outwords, AES_TEXT_BASE, 4);
#endif
ESP_LOGV(TAG, "leave esp_aes_bk"); ESP_LOGV(TAG, "leave esp_aes_bk");
} } /* esp_aes_bk */
/* /*
* wc_esp32AesEncrypt * 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 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 * @param out: a pointer of the output buffer in which to store the cipher text of
* the encrypted message * 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 wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)
{ {
int ret = 0;
ESP_LOGV(TAG, "enter wc_esp32AesEncrypt"); ESP_LOGV(TAG, "enter wc_esp32AesEncrypt");
/* lock the hw engine */ /* 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 */ /* load the key into the register */
esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT); if (ret == 0) {
/* process a one block of AES */ /* process a one block of AES */
esp_aes_bk(in, out); esp_aes_bk(in, out);
}
/* release hw */ /* release hw */
esp_aes_hw_Leave(); esp_aes_hw_Leave();
return 0; return ret;
} } /* wc_esp32AesEncrypt */
/* /*
* wc_esp32AesDecrypt * 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 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 * @param out: a pointer of the output buffer in which to store the cipher text of
* the decrypted message * 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 wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
{ {
int ret;
ESP_LOGV(TAG, "enter wc_esp32AesDecrypt"); ESP_LOGV(TAG, "enter wc_esp32AesDecrypt");
/* lock the hw engine */ /* lock the hw engine */
esp_aes_hw_InUse(); esp_aes_hw_InUse();
/* load the key into the register */ /* load the key into the register */
esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT); ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
/* process a one block of AES */ if (ret != 0) {
esp_aes_bk(in, out); ESP_LOGE(TAG, "wc_esp32AesDecrypt failed during esp_aes_hw_Set_KeyMode");
/* release hw engine */ /* release hw */
esp_aes_hw_Leave(); esp_aes_hw_Leave();
return 0; 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 * wc_esp32AesCbcEncrypt
@ -239,9 +323,11 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
* the encrypted message * the encrypted message
* @param in : a pointer of the input buffer containing plain text to be encrypted * @param in : a pointer of the input buffer containing plain text to be encrypted
* @param sz : size of input message * @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 wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{ {
int ret;
int i; int i;
int offset = 0; int offset = 0;
word32 blocks = (sz / AES_BLOCK_SIZE); 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"); 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--) { if (ret == 0) {
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); while (blocks--) {
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
/* XOR block with IV for CBC */ /* XOR block with IV for CBC */
for (i = 0; i < AES_BLOCK_SIZE; i++) for (i = 0; i < AES_BLOCK_SIZE; i++) {
temp_block[i] ^= iv[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 */ /* store IV for next block */
XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
} } /* while (blocks--) */
} /* if Set Mode successful (ret == 0) */
esp_aes_hw_Leave(); esp_aes_hw_Leave();
ESP_LOGV(TAG, "leave wc_esp32AesCbcEncrypt"); ESP_LOGV(TAG, "leave wc_esp32AesCbcEncrypt");
return 0; return 0;
} } /* wc_esp32AesCbcEncrypt */
/* /*
* wc_esp32AesCbcDecrypt * wc_esp32AesCbcDecrypt
* @brief: Encrypts a plain text message from the input buffer, and places the * @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 * the decrypted message
* @param in : a pointer of the input buffer containing plain text to be decrypted * @param in : a pointer of the input buffer containing plain text to be decrypted
* @param sz : size of input message * @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 wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{ {
int ret;
int i; int i;
int offset = 0; int offset = 0;
word32 blocks = (sz / AES_BLOCK_SIZE); 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"); 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); if (ret == 0) {
ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
while (blocks--) { if (ret != 0) {
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); ESP_LOGE(TAG, "wc_esp32AesCbcDecrypt failed HW Set KeyMode");
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;
} }
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_aes_hw_Leave();
ESP_LOGV(TAG, "leave wc_esp32AesCbcDecrypt"); ESP_LOGV(TAG, "leave wc_esp32AesCbcDecrypt");
return 0; return 0;
} } /* wc_esp32AesCbcDecrypt */
#endif /* WOLFSSL_ESP32WROOM32_CRYPT */ #endif /* WOLFSSL_ESP32WROOM32_CRYPT */
#endif /* NO_AES */ #endif /* NO_AES */

View File

@ -48,6 +48,7 @@ static const char* const TAG = "wolfssl_mp";
#define ESP_HW_RSAMIN_BIT 512 #define ESP_HW_RSAMIN_BIT 512
#define BYTE_TO_WORDS(s) (((s+3)>>2)) /* (s+(4-1))/ 4 */ #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_TO_WORDS(s) (((s+31)>>3)>>2) /* (s+(32-1))/ 8/ 4*/
#define BITS_IN_ONE_WORD 32
#define MP_NG -1 #define MP_NG -1
@ -57,7 +58,7 @@ static const char* const TAG = "wolfssl_mp";
static wolfSSL_Mutex mp_mutex; static wolfSSL_Mutex mp_mutex;
static int espmp_CryptHwMutexInit = 0; 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 * When the RSA Accelerator is released from reset, the register RSA_CLEAN_REG
* reads 0 and an initialization process begins. Hardware initializes the four * 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 * after being released from reset, and before writing to any RSA Accelerator
* memory blocks or registers for the first time. * 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; word32 timeout = 0;
while(!ESP_TIMEOUT(++timeout) && #if CONFIG_IDF_TARGET_ESP32S3
DPORT_REG_READ(RSA_CLEAN_REG) != 1) {
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 */ /* wait. expected delay 1 to 2 uS */
} }
#endif
if (ESP_TIMEOUT(timeout)) { if (ESP_TIMEOUT(timeout)) {
ESP_LOGE(TAG, "waiting hw ready is timed out."); ESP_LOGE(TAG, "esp_mp_hw_wait_clean waiting HW ready timed out.");
return MP_NG; ret = MP_NG;
} }
return MP_OKAY; return ret;
} }
/* /*
* lock hw engine. * esp_mp_hw_lock()
* this should be called before using engine.
* *
* 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: * See Chapter 24:
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf * 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 { else {
ESP_LOGE(TAG, "mp mutex initialization failed."); ESP_LOGE(TAG, "mp mutex initialization failed.");
return MP_NG;
} }
} }
else { else {
/* esp aes has already been initialized */ /* ESP AES has already been initialized */
} }
/* lock hardware */ if (ret == 0) {
ret = esp_CryptHwMutexLock(&mp_mutex, portMAX_DELAY); /* 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) { #if CONFIG_IDF_TARGET_ESP32S3
ESP_LOGE(TAG, "mp engine lock failed."); /* Activate the RSA accelerator. See 20.3 of ESP32-S3 technical manual.
return MP_NG; * 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 */ /* 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) /* clear bit to enable hardware operation; (set to disable) */
*/ DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); }
#endif
/* reminder: wait until RSA_CLEAN_REG reads 1 /* reminder: wait until RSA_CLEAN_REG reads 1
* see esp_mp_hw_wait_clean() * see esp_mp_hw_wait_clean()
@ -145,17 +171,27 @@ static int esp_mp_hw_lock()
ESP_LOGV(TAG, "leave esp_mp_hw_lock"); ESP_LOGV(TAG, "leave esp_mp_hw_lock");
return ret; return ret;
} }
/* /*
* Release hw engine * Release HW engine
*/ */
static void esp_mp_hw_unlock( void ) 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) /* set bit to disabled hardware operation; (clear to enable)
*/ */
DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
/* Disable RSA hardware */ /* Disable RSA hardware */
periph_module_disable(PERIPH_RSA_MODULE); periph_module_disable(PERIPH_RSA_MODULE);
#endif
/* unlock */ /* unlock */
esp_CryptHwMutexUnLock(&mp_mutex); 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; return MP_OKAY;
} }
/* start hw process */ /* start HW process */
static void process_start(word32 reg) static void process_start(word32 reg)
{ {
/* clear interrupt */ /* 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 * supported words length
* words : {16 , 32, 48, 64, 80, 96, 112, 128} * words : {16 , 32, 48, 64, 80, 96, 112, 128}
* bits : {512,1024, 1536, 2048, 2560, 3072, 3584, 4096} * 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 esp_mp_mul(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* Z)
{ {
int ret = 0; 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; 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 Xs;
word32 Ys; word32 Ys;
word32 Zs; 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; word32 hwWords_sz;
/* neg check - X*Y becomes negative */ /* neg check - X*Y becomes negative */
#ifdef WOLFSSL_SP_INT_NEGATIVE
neg = mp_isneg(X) != mp_isneg(Y) ? 1 : 0; neg = mp_isneg(X) != mp_isneg(Y) ? 1 : 0;
#endif
/* ask bits number */ /* ask bits number */
Xs = mp_count_bits(X); Xs = mp_count_bits(X);
Ys = mp_count_bits(Y); Ys = mp_count_bits(Y);
Zs = Xs + Ys; 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)); maxWords_sz = bits2words(max(Xs, Ys));
hwWords_sz = words2hwords(maxWords_sz); hwWords_sz = words2hwords(maxWords_sz);
/* sanity check */ /* sanity check */
if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) { if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) {
ESP_LOGW(TAG, "exceeds max bit length(2048)"); 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: /*Steps to use HW in the following order:
* 1. wait until clean hw engine * 1. wait until clean HW engine
* 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG * 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG
* 3. Write X and Y to memory blocks * 3. Write X and Y to memory blocks
* need to write data to each memory block only according to the length * 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. * 6. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.
* 7. Read the Z from RSA_Z_MEM * 7. Read the Z from RSA_Z_MEM
* 8. Write 1 to RSA_INTERUPT_REG to clear the interrupt. * 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) { if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
return ret; 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 */ /* step.6 read the result form MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs)); 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(); esp_mp_hw_unlock();
#ifdef WOLFSSL_SP_INT_NEGATIVE
if (!mp_iszero(Z) && neg) { if (!mp_iszero(Z) && neg) {
mp_setneg(Z); mp_setneg(Z);
} }
#endif
return ret; return ret;
#endif /* CONFIG_IDF_TARGET_ESP32S3 or not */
} }
/* Z = X * Y (mod M) */ /* 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; MATH_INT_T tmpZ;
mp_digit mp; mp_digit mp;
uint32_t Exponent;
#if CONFIG_IDF_TARGET_ESP32S3
uint32_t OperandBits;
int WordsForOperand;
# endif
/* neg check - X*Y becomes negative */ /* neg check - X*Y becomes negative */
negcheck = mp_isneg(X) != mp_isneg(Y) ? 1 : 0; 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); Ys = mp_count_bits(Y);
Ms = mp_count_bits(M); 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))); maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));
zwords = bits2words(min(Ms, Xs + Ys)); zwords = bits2words(min(Ms, Xs + Ys));
hwWords_sz = words2hwords(maxWords_sz); hwWords_sz = words2hwords(maxWords_sz);
if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) { if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) {
ESP_LOGE(TAG, "exceeds hw maximum bits"); ESP_LOGE(TAG, "exceeds HW maximum bits");
return -2; return MP_VAL; /* Error: value is not able to be used. */
} }
/* calculate r_inv = R^2 mode M /* calculate r_inv = R^2 mode M
* where: R = b^n, and b = 2^32 * where: R = b^n, and b = 2^32
* accordingly R^2 = 2^(n*32*2) * 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); 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."); ESP_LOGE(TAG, "calculate r_inv failed.");
mp_clear(&tmpZ); mp_clear(&tmpZ);
mp_clear(&r_inv); mp_clear(&r_inv);
return ret; return ret;
} }
/* lock hw for use */
/* lock HW for use */
if ((ret = esp_mp_hw_lock()) != MP_OKAY) { if ((ret = esp_mp_hw_lock()) != MP_OKAY) {
mp_clear(&tmpZ); mp_clear(&tmpZ);
mp_clear(&r_inv); 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"); ESP_LOGE(TAG, "failed to calculate M dash");
mp_clear(&tmpZ); mp_clear(&tmpZ);
mp_clear(&r_inv); 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 * 2. Write(N/512bits - 1) to MULT_MODE_REG
* 3. Write X,M(=G, X, P) to memory blocks * 3. Write X,M(=G, X, P) to memory blocks
* need to write data to each memory block only according to the length * 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. * 10. Wait for the second operation to be completed. Poll INTERRUPT_REG until it reads 1.
* 11. Read the Z from RSA_Z_MEM * 11. Read the Z from RSA_Z_MEM
* 12. Write 1 to RSA_INTERUPT_REG to clear the interrupt. * 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; return ret;
} }
/* step.1 512 bits => 16 words */ /* 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 */ /* step.3 write M' into memory */
DPORT_REG_WRITE(RSA_M_DASH_REG, mp); DPORT_REG_WRITE(RSA_M_DASH_REG, mp);
/* step.4 start process */ /* step.4 start process */
process_start(RSA_MULT_START_REG); 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 */ /* step.12 read the result from MEM_Z */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, &tmpZ, zwords); 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(); esp_mp_hw_unlock();
/* additional steps */ /* 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); mp_clear(&r_inv);
return ret; return ret;
#endif
} }
/* Large Number Modular Exponentiation /* Large Number Modular Exponentiation
* *
* Z = X^Y mod M * Z = X^Y mod M
* *
* See Chapter 24: * See:
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf * 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 * The operation is based on Montgomery multiplication. Aside from the
* arguments X, Y , and M, two additional ones are needed —r and M * arguments X, Y , and M, two additional ones are needed —r and M
.* These arguments are calculated in advance by software. .* These arguments are calculated in advance by software.
.* .*
.* The RSA Accelerator supports operand lengths of N ∈ {512, 1024, 1536, 2048, .* 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, .* 2560, 3072, 3584, 4096} bits on the ESP32 and N ∈ [32, 4096] bits on the ESP32s3.
.* and r can be any one from the N set, but all numbers in a calculation must .* The bit length of arguments Z, X, Y , M, and r can be any one from the N set,
.* be of the same length. The bit length of M is always 32. .* 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 .* 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; MATH_INT_T r_inv;
mp_digit mp; mp_digit mp;
#if CONFIG_IDF_TARGET_ESP32S3
uint32_t OperandBits;
uint32_t WordsForOperand;
#endif
/* ask bits number */ /* ask bits number */
Xs = mp_count_bits(X); Xs = mp_count_bits(X);
Ms = mp_count_bits(M); 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))); maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));
hwWords_sz = words2hwords(maxWords_sz); hwWords_sz = words2hwords(maxWords_sz);
if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) { if ((hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) {
ESP_LOGE(TAG, "exceeds hw maximum bits"); ESP_LOGE(TAG, "exceeds HW maximum bits");
return -2; return MP_VAL; /* Error: value is not able to be used. */
} }
/* calculate r_inv = R^2 mode M /* calculate r_inv = R^2 mode M
* where: R = b^n, and b = 2^32 * where: R = b^n, and b = 2^32
* accordingly R^2 = 2^(n*32*2) * accordingly R^2 = 2^(n*32*2)
*/ */
ret = mp_init(&r_inv); 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."); ESP_LOGE(TAG, "calculate r_inv failed.");
mp_clear(&r_inv); mp_clear(&r_inv);
return ret; return ret;
} }
/* lock and init the hw */ /* lock and init the HW */
if ((ret = esp_mp_hw_lock()) != MP_OKAY) { if ( (ret = esp_mp_hw_lock()) != MP_OKAY ) {
mp_clear(&r_inv); mp_clear(&r_inv);
return ret; return ret;
} }
/* calc M' */ /* calc M' */
/* if Pm is odd, uses mp_montgomery_setup() */ /* 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"); ESP_LOGE(TAG, "failed to calculate M dash");
mp_clear(&r_inv); 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 * 1. Write(N/512bits - 1) to MODEXP_MODE_REG
* 2. Write X, Y, M and r_inv to memory blocks * 2. Write X, Y, M and r_inv to memory blocks
* need to write data to each memory block only according to the length * 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); wait_until_done(RSA_INTERRUPT_REG);
/* step.6 read a result form memory */ /* step.6 read a result form memory */
esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Ms)); 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(); esp_mp_hw_unlock();
mp_clear(&r_inv); mp_clear(&r_inv);
return ret; return ret;
#endif
} }
#endif /* WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && #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 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/ */
#include <wolfssl/wolfcrypt/settings.h> #include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/version.h>
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
(!defined(NO_AES) || !defined(NO_SHA) || !defined(NO_SHA256) ||\ (!defined(NO_AES) || !defined(NO_SHA) || !defined(NO_SHA256) ||\
@ -27,6 +28,8 @@
#include <wolfssl/wolfcrypt/wc_port.h> #include <wolfssl/wolfcrypt/wc_port.h>
#include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h> #include <wolfssl/wolfcrypt/logging.h>
/* /*
* initialize our mutex used to lock hardware access * initialize our mutex used to lock hardware access
* *
@ -79,25 +82,254 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) {
#endif #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 #endif
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG /*
*******************************************************************************
** Specific Platforms
*******************************************************************************
*/
#include "esp_timer.h" /*
#include "esp_log.h" ** Specific platforms: Espressif
*/
static uint64_t startTime = 0; #if defined(WOLFSSL_ESPIDF)
static int ShowExtendedSystemInfo_platform_espressif()
void wc_esp32TimerStart()
{ {
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 */ /* all platforms: stack high water mark check */
return esp_timer_get_time() - startTime; #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> #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(NO_SHA)
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) #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> #include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
#endif #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 */ /* fips wrapper calls, user can call direct */
#if defined(HAVE_FIPS) && \ #if defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
@ -290,13 +321,11 @@
!defined(WOLFSSL_QNX_CAAM) !defined(WOLFSSL_QNX_CAAM)
/* wolfcrypt/src/port/caam/caam_sha.c */ /* wolfcrypt/src/port/caam/caam_sha.c */
#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #elif defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) || \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
#include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
#define USE_SHA_SOFTWARE_IMPL
/* This function initializes SHA.
** This is automatically called by wc_ShaHash */
static int InitSha(wc_Sha* sha) static int InitSha(wc_Sha* sha)
{ {
int ret = 0; int ret = 0;
@ -311,19 +340,10 @@
sha->loLen = 0; sha->loLen = 0;
sha->hiLen = 0; sha->hiLen = 0;
/* always start firstblock = 1 when using hw engine */ /* HW needs to be carefully initialized, taking into account soft copy.
sha->ctx.isfirstblock = 1; ** If already in use; copy may revert to SW as needed. */
sha->ctx.sha_type = SHA1; ret = esp_sha_init(&(sha->ctx), WC_HASH_TYPE_SHA);
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;
return ret; return ret;
} }
@ -526,15 +546,20 @@ static WC_INLINE void AddLength(wc_Sha* sha, word32 len)
return 0; 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 wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
{ {
int ret = 0; int ret = 0;
if (sha == NULL) {
if (sha == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
sha->heap = heap; sha->heap = heap;
#ifdef WOLF_CRYPTO_CB #ifdef WOLF_CRYPTO_CB
@ -542,28 +567,32 @@ int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
sha->devCtx = NULL; sha->devCtx = NULL;
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #ifdef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) 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.mode = ESP32_SHA_INIT;
sha->ctx.isfirstblock = 1;
sha->ctx.lockDepth = 0; /* keep track of how many times lock is called */
#endif #endif
ret = InitSha(sha); ret = InitSha(sha);
if (ret != 0) if (ret != 0) {
return ret; return ret;
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
ret = wolfAsync_DevCtxInit(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA, ret = wolfAsync_DevCtxInit(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA,
sha->heap, devId); sha->heap, devId);
#else #else
(void)devId; (void)devId;
#endif /* WOLFSSL_ASYNC_CRYPT */ # endif /* WOLFSSL_ASYNC_CRYPT */
#ifdef WOLFSSL_IMXRT1170_CAAM #ifdef WOLFSSL_IMXRT1170_CAAM
ret = wc_CAAM_HashInit(&sha->hndl, &sha->ctx, WC_HASH_TYPE_SHA); ret = wc_CAAM_HashInit(&sha->hndl, &sha->ctx, WC_HASH_TYPE_SHA);
#endif #endif
return ret; return ret;
} } /* wc_InitSha_ex */
/* do block size increments/updates */ /* do block size increments/updates */
int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) 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 */ #endif /* WOLFSSL_ASYNC_CRYPT */
/* check that internal buffLen is valid */ /* check that internal buffLen is valid */
if (sha->buffLen >= WC_SHA_BLOCK_SIZE) if (sha->buffLen >= WC_SHA_BLOCK_SIZE) {
return BUFFER_E; return BUFFER_E;
}
/* add length for final */ /* add length for final */
AddLength(sha, len); 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); ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
if (sha->ctx.mode == ESP32_SHA_INIT) { if (sha->ctx.mode == ESP32_SHA_INIT) {
ESP_LOGV(TAG, "wc_ShaUpdate try hardware");
esp_sha_try_hw_lock(&sha->ctx); esp_sha_try_hw_lock(&sha->ctx);
} }
if (sha->ctx.mode == ESP32_SHA_SW) { if (sha->ctx.mode == ESP32_SHA_SW) {
ESP_LOGI(TAG, "wc_ShaUpdate process software");
ret = XTRANSFORM(sha, (const byte*)local); ret = XTRANSFORM(sha, (const byte*)local);
} }
else { else {
ESP_LOGV(TAG, "wc_ShaUpdate process hardware");
esp_sha_process(sha, (const byte*)local); 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 #else
ret = XTRANSFORM(sha, (const byte*)local); ret = XTRANSFORM(sha, (const byte*)local);
#endif #endif
if (ret != 0) if (ret != 0) {
return ret; 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 */ /* process blocks */
#ifdef XTRANSFORM_LEN #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); ByteReverseWords(local32, local32, WC_SHA_BLOCK_SIZE);
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
if (sha->ctx.mode == ESP32_SHA_INIT){ if (sha->ctx.mode == ESP32_SHA_INIT){
esp_sha_try_hw_lock(&sha->ctx); esp_sha_try_hw_lock(&sha->ctx);
} }
@ -722,6 +757,10 @@ int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
return 0; 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 wc_ShaFinal(wc_Sha* sha, byte* hash)
{ {
int ret; int ret;
@ -749,6 +788,13 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
} }
#endif /* WOLFSSL_ASYNC_CRYPT */ #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 */ local[sha->buffLen++] = 0x80; /* add 1 */
/* pad with zeros */ /* pad with zeros */
@ -760,11 +806,13 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE); ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) /* For a fresh sha.ctx, try to use hardware acceleration */
if (sha->ctx.mode == ESP32_SHA_INIT) { if (sha->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha->ctx); 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) { if (sha->ctx.mode == ESP32_SHA_SW) {
ret = XTRANSFORM(sha, (const byte*)local); 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); ret = esp_sha_process(sha, (const byte*)local);
} }
#else #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); ret = XTRANSFORM(sha, (const byte*)local);
#endif #endif
if (ret != 0) if (ret != 0) {
return ret; return ret;
}
sha->buffLen = 0; sha->buffLen = 0;
} } /* (sha->buffLen > WC_SHA_PAD_SIZE) */
XMEMSET(&local[sha->buffLen], 0, WC_SHA_PAD_SIZE - sha->buffLen); XMEMSET(&local[sha->buffLen], 0, WC_SHA_PAD_SIZE - sha->buffLen);
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
@ -801,8 +855,7 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
2 * sizeof(word32)); 2 * sizeof(word32));
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
if (sha->ctx.mode == ESP32_SHA_INIT) { if (sha->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha->ctx); esp_sha_try_hw_lock(&sha->ctx);
} }
@ -812,6 +865,10 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
else { else {
ret = esp_sha_digest_process(sha, 1); 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 #else
ret = XTRANSFORM(sha, (const byte*)local); ret = XTRANSFORM(sha, (const byte*)local);
#endif #endif
@ -822,7 +879,7 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
XMEMCPY(hash, (byte *)&sha->digest[0], WC_SHA_DIGEST_SIZE); XMEMCPY(hash, (byte *)&sha->digest[0], WC_SHA_DIGEST_SIZE);
(void)InitSha(sha); /* reset state */ ret = InitSha(sha); /* reset state */
return ret; return ret;
} }
@ -844,12 +901,15 @@ int wc_ShaTransform(wc_Sha* sha, const unsigned char* data)
#endif /* USE_SHA_SOFTWARE_IMPL */ #endif /* USE_SHA_SOFTWARE_IMPL */
/*
** This function initializes SHA. This is automatically called by wc_ShaHash.
*/
int wc_InitSha(wc_Sha* sha) int wc_InitSha(wc_Sha* sha)
{ {
return wc_InitSha_ex(sha, NULL, INVALID_DEVID); return wc_InitSha_ex(sha, NULL, INVALID_DEVID);
} }
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) #if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
void wc_ShaFree(wc_Sha* sha) 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 /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */
#endif /* !WOLFSSL_TI_HASH */ #endif /* !WOLFSSL_TI_HASH */
#endif /* HAVE_FIPS */ #endif /* !HAVE_FIPS ... */
#if !defined(WOLFSSL_TI_HASH) && !defined(WOLFSSL_IMXRT_DCP) #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_RENESAS_RX64_HASH)
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_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 wc_ShaGetHash(wc_Sha* sha, byte* hash)
{ {
int ret; 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; 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 */ #ifdef WOLFSSL_SMALL_STACK
esp_sha_digest_process(sha, 0); tmpSha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (tmpSha == NULL) {
return MEMORY_E;
} }
#endif #endif
ret = wc_ShaCopy(sha, &tmpSha); ret = wc_ShaCopy(sha, tmpSha);
if (ret == 0) { if (ret == 0) {
/* if HW failed, use SW */ ret = wc_ShaFinal(tmpSha, hash);
ret = wc_ShaFinal(&tmpSha, hash); }
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) #ifdef WOLFSSL_SMALL_STACK
sha->ctx.mode = ESP32_SHA_SW; XFREE(tmpSha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
}
return ret; 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) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif #endif
#ifdef WOLFSSL_PIC32MZ_HASH #ifdef WOLFSSL_PIC32MZ_HASH
ret = wc_Pic32HashCopy(&src->cache, &dst->cache); ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
#endif #endif
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
ret = se050_hash_copy(&src->se050Ctx, &dst->se050Ctx); ret = se050_hash_copy(&src->se050Ctx, &dst->se050Ctx);
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
dst->ctx.mode = src->ctx.mode; esp_sha_ctx_copy(src, dst);
dst->ctx.isfirstblock = src->ctx.isfirstblock;
dst->ctx.sha_type = src->ctx.sha_type;
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY; dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif #endif
return ret; return ret;
} }
#endif /* WOLFSSL_RENESAS_RX64_HASH */ #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_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 #ifdef WOLFSSL_HASH_FLAGS
int wc_ShaSetFlags(wc_Sha* sha, word32 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 #undef WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW
#endif #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 */ /* fips wrapper calls, user can call direct */
#if defined(HAVE_FIPS) && \ #if defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
@ -731,16 +739,16 @@ static int InitSha256(wc_Sha256* sha256)
#define NEED_SOFT_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) static int InitSha256(wc_Sha256* sha256)
{ {
int ret = 0; /* zero = success */ int ret = 0; /* zero = success */
if (sha256 == NULL) if (sha256 == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
XMEMSET(sha256->digest, 0, sizeof(sha256->digest));
sha256->digest[0] = 0x6A09E667L; sha256->digest[0] = 0x6A09E667L;
sha256->digest[1] = 0xBB67AE85L; sha256->digest[1] = 0xBB67AE85L;
sha256->digest[2] = 0x3C6EF372L; sha256->digest[2] = 0x3C6EF372L;
@ -754,41 +762,33 @@ static int InitSha256(wc_Sha256* sha256)
sha256->loLen = 0; sha256->loLen = 0;
sha256->hiLen = 0; sha256->hiLen = 0;
/* always start firstblock = 1 when using hw engine */ ret = esp_sha_init(&(sha256->ctx), WC_HASH_TYPE_SHA256);
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;
return ret; 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 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; (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) && \ #elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \
@ -1100,15 +1100,17 @@ static int InitSha256(wc_Sha256* sha256)
#endif #endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha256->ctx.mode == ESP32_SHA_INIT || if (sha256->ctx.mode == ESP32_SHA_INIT) {
sha256->ctx.mode == ESP32_SHA_FAIL_NEED_UNROLL) { ESP_LOGV(TAG, "Sha256Update try hardware");
esp_sha_try_hw_lock(&sha256->ctx); esp_sha_try_hw_lock(&sha256->ctx);
} }
if (sha256->ctx.mode == ESP32_SHA_SW) { if (sha256->ctx.mode == ESP32_SHA_SW) {
ESP_LOGV(TAG, "Sha256Update process software");
ret = XTRANSFORM(sha256, (const byte*)local); ret = XTRANSFORM(sha256, (const byte*)local);
} }
else { else {
ESP_LOGV(TAG, "Sha256Update process hardware");
esp_sha256_process(sha256, (const byte*)local); esp_sha256_process(sha256, (const byte*)local);
} }
#else #else
@ -1183,15 +1185,18 @@ static int InitSha256(wc_Sha256* sha256)
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
if (sha256->ctx.mode == ESP32_SHA_INIT){ if (sha256->ctx.mode == ESP32_SHA_INIT){
ESP_LOGV(TAG, "Sha256Update try hardware loop");
esp_sha_try_hw_lock(&sha256->ctx); esp_sha_try_hw_lock(&sha256->ctx);
} }
if (sha256->ctx.mode == ESP32_SHA_SW) { if (sha256->ctx.mode == ESP32_SHA_SW) {
ESP_LOGV(TAG, "Sha256Update process software loop");
ret = XTRANSFORM(sha256, (const byte*)local32); ret = XTRANSFORM(sha256, (const byte*)local32);
} }
else { else {
ESP_LOGV(TAG, "Sha256Update process hardware");
esp_sha256_process(sha256, (const byte*)local32); esp_sha256_process(sha256, (const byte*)local32);
} }
#else #else
ret = XTRANSFORM(sha256, (const byte*)local32); ret = XTRANSFORM(sha256, (const byte*)local32);
#endif #endif
@ -1255,6 +1260,13 @@ static int InitSha256(wc_Sha256* sha256)
return BAD_FUNC_ARG; 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 = (byte*)sha256->buffer;
local[sha256->buffLen++] = 0x80; /* add 1 */ local[sha256->buffLen++] = 0x80; /* add 1 */
@ -1400,8 +1412,9 @@ static int InitSha256(wc_Sha256* sha256)
#endif /* WOLFSSL_ASYNC_CRYPT */ #endif /* WOLFSSL_ASYNC_CRYPT */
ret = Sha256Final(sha256); ret = Sha256Final(sha256);
if (ret != 0) if (ret != 0) {
return ret; return ret;
}
#if defined(LITTLE_ENDIAN_ORDER) #if defined(LITTLE_ENDIAN_ORDER)
ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE); ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE);
@ -1572,6 +1585,10 @@ static int InitSha256(wc_Sha256* sha256)
sha224->used = 0; sha224->used = 0;
#endif #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; return ret;
} }
@ -1591,9 +1608,20 @@ static int InitSha256(wc_Sha256* sha256)
sha224->W = NULL; sha224->W = NULL;
#endif #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); ret = InitSha224(sha224);
if (ret != 0) if (ret != 0) {
return ret; return ret;
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
ret = wolfAsync_DevCtxInit(&sha224->asyncDev, ret = wolfAsync_DevCtxInit(&sha224->asyncDev,
@ -1604,6 +1632,16 @@ static int InitSha256(wc_Sha256* sha256)
#ifdef WOLFSSL_IMXRT1170_CAAM #ifdef WOLFSSL_IMXRT1170_CAAM
ret = wc_CAAM_HashInit(&sha224->hndl, &sha224->ctx, WC_HASH_TYPE_SHA224); ret = wc_CAAM_HashInit(&sha224->hndl, &sha224->ctx, WC_HASH_TYPE_SHA224);
#endif #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; return ret;
} }
@ -1623,6 +1661,10 @@ static int InitSha256(wc_Sha256* sha256)
} }
#endif /* WOLFSSL_ASYNC_CRYPT */ #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); ret = Sha256Update((wc_Sha256*)sha224, data, len);
return ret; return ret;
@ -1645,6 +1687,10 @@ static int InitSha256(wc_Sha256* sha256)
} }
#endif /* WOLFSSL_ASYNC_CRYPT */ #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); ret = Sha256Final((wc_Sha256*)sha224);
if (ret != 0) if (ret != 0)
return ret; return ret;
@ -1785,11 +1831,11 @@ void wc_Sha256Free(wc_Sha256* sha256)
* the unexpected. by the time free is called, the hardware * the unexpected. by the time free is called, the hardware
* should have already been released (lockDepth = 0) * should have already been released (lockDepth = 0)
*/ */
InitSha256(sha256); /* unlock mutex, set mode to ESP32_SHA_INIT */ (void)InitSha256(sha256); /* unlock mutex, set mode to ESP32_SHA_INIT */
ESP_LOGV("sha256", "Alert: hardware unlock needed in wc_Sha256Free."); ESP_LOGV(TAG, "Alert: hardware unlock needed in wc_Sha256Free.");
} }
else { else {
ESP_LOGV("sha256", "Hardware unlock not needed in wc_Sha256Free."); ESP_LOGV(TAG, "Hardware unlock not needed in wc_Sha256Free.");
} }
#endif #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 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; return BAD_FUNC_ARG;
}
XMEMCPY(dst, src, sizeof(wc_Sha224)); XMEMCPY(dst, src, sizeof(wc_Sha224));
#ifdef WOLFSSL_SMALL_STACK_CACHE #ifdef WOLFSSL_SMALL_STACK_CACHE
dst->W = NULL; dst->W = NULL;
#endif #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) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif #endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
ret = esp_sha224_ctx_copy(src, dst);
#endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY; dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif #endif
#if defined(WOLFSSL_HASH_KEEP) #if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) { if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap, dst->msg = (byte*)XMALLOC(src->len, dst->heap,
@ -1972,32 +2026,13 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
} }
#endif #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); ret = wc_Sha256Copy(sha256, tmpSha256);
if (ret == 0) { if (ret == 0) {
ret = wc_Sha256Final(tmpSha256, hash); ret = wc_Sha256Final(tmpSha256, hash);
wc_Sha256Free(tmpSha256); /* TODO move outside brackets? */
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
sha256->ctx.mode = ESP32_SHA_SW;
#endif
wc_Sha256Free(tmpSha256);
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(tmpSha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpSha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
@ -2008,8 +2043,9 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
{ {
int ret = 0; int ret = 0;
if (src == NULL || dst == NULL) if (src == NULL || dst == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
XMEMCPY(dst, src, sizeof(wc_Sha256)); 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) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif #endif
#ifdef WOLFSSL_PIC32MZ_HASH #ifdef WOLFSSL_PIC32MZ_HASH
ret = wc_Pic32HashCopy(&src->cache, &dst->cache); ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
#endif #endif
#if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
dst->ctx.mode = src->ctx.mode; esp_sha256_ctx_copy(src, dst);
dst->ctx.isfirstblock = src->ctx.isfirstblock;
dst->ctx.sha_type = src->ctx.sha_type;
dst->ctx.lockDepth = src->ctx.lockDepth;
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY; dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif #endif
#if defined(WOLFSSL_HASH_KEEP) #if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) { if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); 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) #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) #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
#define FIPS_NO_WRAPPERS #define FIPS_NO_WRAPPERS
@ -279,21 +294,13 @@ static int InitSha512(wc_Sha512* sha512)
sha512->loLen = 0; sha512->loLen = 0;
sha512->hiLen = 0; sha512->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
sha512->ctx.sha_type = SHA2_512; /* HW needs to be carefully initialized, taking into account soft copy.
/* always start firstblock = 1 when using hw engine */ ** If already in use; copy may revert to SW as needed. */
sha512->ctx.isfirstblock = 1; esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512);
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;
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
sha512->flags = 0; sha512->flags = 0;
#endif #endif
@ -327,21 +334,15 @@ static int InitSha512_224(wc_Sha512* sha512)
sha512->loLen = 0; sha512->loLen = 0;
sha512->hiLen = 0; sha512->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) /* HW needs to be carefully initialized, taking into account soft copy.
** If already in use; copy may revert to SW as needed.
sha512->ctx.sha_type = SHA2_512; **
/* always start firstblock = 1 when using hw engine */ ** Note for original ESP32, there's no HW for SHA512/224
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; esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_224);
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
sha512->flags = 0; sha512->flags = 0;
#endif #endif
@ -375,21 +376,15 @@ static int InitSha512_256(wc_Sha512* sha512)
sha512->loLen = 0; sha512->loLen = 0;
sha512->hiLen = 0; sha512->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) /* HW needs to be carefully initialized, taking into account soft copy.
** If already in use; copy may revert to SW as needed.
sha512->ctx.sha_type = SHA2_512; **
/* always start firstblock = 1 when using hw engine */ ** Note for original ESP32, there's no HW for SHA512/2256.
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; esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_256);
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
sha512->flags = 0; sha512->flags = 0;
#endif #endif
@ -578,8 +573,10 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
{ {
int ret = 0; int ret = 0;
if (sha512 == NULL) if (sha512 == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
sha512->heap = heap; sha512->heap = heap;
#ifdef WOLFSSL_SMALL_STACK_CACHE #ifdef WOLFSSL_SMALL_STACK_CACHE
@ -590,6 +587,7 @@ static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
sha512->devCtx = NULL; sha512->devCtx = NULL;
#endif #endif
/* call the initialization function pointed to by initfp */
ret = initfp(sha512); ret = initfp(sha512);
if (ret != 0) if (ret != 0)
return ret; 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); ret = wc_CAAM_HashInit(&sha512->hndl, &sha512->ctx, WC_HASH_TYPE_SHA512);
#endif #endif
return ret; return ret;
} } /* InitSha512_Family */
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) 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); 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) (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId) 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); return InitSha512_Family(sha512, heap, devId, InitSha512_224);
} }
#endif /* !WOLFSSL_NOSHA512_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) (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId) 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); return InitSha512_Family(sha512, heap, devId, InitSha512_256);
} }
#endif /* !WOLFSSL_NOSHA512_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); ret = esp_sha512_process(sha512);
if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){ if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){
ByteReverseWords64(sha512->buffer, sha512->buffer,
WC_SHA512_BLOCK_SIZE);
ret = Transform_Sha512(sha512); ret = Transform_Sha512(sha512);
} }
#endif #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) { if(sha512->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha512->ctx); esp_sha_try_hw_lock(&sha512->ctx);
} }
ret = esp_sha512_process(sha512); if (sha512->ctx.mode == ESP32_SHA_SW) {
if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){ ByteReverseWords64(sha512->buffer, sha512->buffer,
WC_SHA512_BLOCK_SIZE);
ret = Transform_Sha512(sha512); ret = Transform_Sha512(sha512);
} }
else {
ret = esp_sha512_process(sha512);
}
#endif #endif
if (ret != 0) if (ret != 0)
break; break;
} } /* while (len >= WC_SHA512_BLOCK_SIZE) */
} }
#endif #endif
@ -962,8 +983,8 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
static WC_INLINE int Sha512Final(wc_Sha512* sha512) static WC_INLINE int Sha512Final(wc_Sha512* sha512)
{ {
byte* local;
int ret; int ret;
byte* local;
if (sha512 == NULL) { if (sha512 == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@ -971,6 +992,12 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512)
local = (byte*)sha512->buffer; 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 */ local[sha512->buffLen++] = 0x80; /* add 1 */
/* pad with zeros */ /* pad with zeros */
@ -990,24 +1017,29 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512)
WC_SHA512_BLOCK_SIZE); WC_SHA512_BLOCK_SIZE);
#endif #endif
} }
#endif /* LITTLE_ENDIAN_ORDER */ #endif /* LITTLE_ENDIAN_ORDER */
#if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) if (sha512->ctx.mode == ESP32_SHA_INIT) {
ret = Transform_Sha512(sha512);
#else
if(sha512->ctx.mode == ESP32_SHA_INIT) {
esp_sha_try_hw_lock(&sha512->ctx); esp_sha_try_hw_lock(&sha512->ctx);
} }
ret = esp_sha512_process(sha512); if (sha512->ctx.mode == ESP32_SHA_SW) {
if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){ ByteReverseWords64(sha512->buffer,sha512->buffer,
WC_SHA512_BLOCK_SIZE);
ret = Transform_Sha512(sha512); ret = Transform_Sha512(sha512);
} }
#endif else {
ret = esp_sha512_process(sha512);
}
#else
ret = Transform_Sha512(sha512);
#endif
if (ret != 0) if (ret != 0)
return ret; return ret;
sha512->buffLen = 0; sha512->buffLen = 0;
} } /* (sha512->buffLen > WC_SHA512_PAD_SIZE) pad with zeros */
XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen); XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);
/* put lengths in bits */ /* 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]), &(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE); WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
#endif #endif
#if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \ #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
ret = Transform_Sha512(sha512); ret = Transform_Sha512(sha512);
#else #else
if(sha512->ctx.mode == ESP32_SHA_INIT) { if(sha512->ctx.mode == ESP32_SHA_INIT) {
/* typically for tiny block: first = last */
esp_sha_try_hw_lock(&sha512->ctx); esp_sha_try_hw_lock(&sha512->ctx);
} }
ret = esp_sha512_digest_process(sha512, 1); if (sha512->ctx.mode == ESP32_SHA_SW) {
if(ret == 0 && 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); ret = Transform_Sha512(sha512);
} }
else {
ret = esp_sha512_digest_process(sha512, 1);
}
#endif #endif
if (ret != 0) if (ret != 0)
return ret; return ret;
@ -1179,6 +1221,7 @@ void wc_Sha512Free(wc_Sha512* sha512)
wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512); wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);
#endif /* WOLFSSL_ASYNC_CRYPT */ #endif /* WOLFSSL_ASYNC_CRYPT */
} }
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_KCAPI_HASH) #if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_KCAPI_HASH)
/* Apply SHA512 transformation to the data */ /* Apply SHA512 transformation to the data */
/* @param sha a pointer to wc_Sha512 structure */ /* @param sha a pointer to wc_Sha512 structure */
@ -1302,24 +1345,16 @@ static int InitSha384(wc_Sha384* sha384)
sha384->loLen = 0; sha384->loLen = 0;
sha384->hiLen = 0; sha384->hiLen = 0;
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) /* HW needs to be carefully initialized, taking into account soft copy.
sha384->ctx.sha_type = SHA2_384; ** If already in use; copy may revert to SW as needed. */
/* always start firstblock = 1 when using hw engine */ esp_sha_init(&(sha384->ctx), WC_HASH_TYPE_SHA384);
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;
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
sha384->flags = 0; sha384->flags = 0;
#endif #endif
#ifdef WOLFSSL_HASH_KEEP #ifdef WOLFSSL_HASH_KEEP
sha384->msg = NULL; sha384->msg = NULL;
sha384->len = 0; sha384->len = 0;
@ -1426,10 +1461,19 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
sha384->devId = devId; sha384->devId = devId;
sha384->devCtx = NULL; sha384->devCtx = NULL;
#endif #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); ret = InitSha384(sha384);
if (ret != 0) if (ret != 0) {
return ret; return ret;
}
#if defined(USE_INTEL_SPEEDUP) && \ #if defined(USE_INTEL_SPEEDUP) && \
(defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
@ -1525,24 +1569,10 @@ static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash,
} }
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ /* copy this sha512 into tmpSha */
!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
ret = wc_Sha512Copy(sha512, tmpSha512); ret = wc_Sha512Copy(sha512, tmpSha512);
if (ret == 0) { if (ret == 0) {
ret = finalfp(tmpSha512, hash); 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); wc_Sha512Free(tmpSha512);
} }
@ -1562,8 +1592,9 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
{ {
int ret = 0; int ret = 0;
if (src == NULL || dst == NULL) if (src == NULL || dst == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
XMEMCPY(dst, src, sizeof(wc_Sha512)); XMEMCPY(dst, src, sizeof(wc_Sha512));
#ifdef WOLFSSL_SMALL_STACK_CACHE #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) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
dst->ctx.mode = src->ctx.mode; if (ret == 0) {
dst->ctx.isfirstblock = src->ctx.isfirstblock; ret = esp_sha512_ctx_copy(src, dst);
dst->ctx.sha_type = src->ctx.sha_type; }
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY; dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif #endif
#if defined(WOLFSSL_HASH_KEEP) #if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) { if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); 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); return wc_InitSha512_224_ex(sha, NULL, INVALID_DEVID);
} }
int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len) int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len)
{ {
return wc_Sha512Update(sha, data, 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); return Sha512FinalRaw(sha, hash, WC_SHA512_224_DIGEST_SIZE);
} }
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash) int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
{ {
return Sha512_Family_Final(sha512, hash, WC_SHA512_224_DIGEST_SIZE, return Sha512_Family_Final(sha512, hash, WC_SHA512_224_DIGEST_SIZE,
InitSha512_224); InitSha512_224);
} }
#endif #endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
void wc_Sha512_224Free(wc_Sha512* sha) void wc_Sha512_224Free(wc_Sha512* sha)
{ {
wc_Sha512Free(sha); wc_Sha512Free(sha);
} }
#if defined(WOLFSSL_KCAPI_HASH) #if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #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); return Sha512_Family_GetHash(sha512, hash, wc_Sha512_224Final);
} }
int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst) int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst)
{ {
return wc_Sha512Copy(src, dst); return wc_Sha512Copy(src, dst);
} }
#endif #endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
int wc_Sha512_224SetFlags(wc_Sha512* sha, word32 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); return wc_InitSha512_256_ex(sha, NULL, INVALID_DEVID);
} }
int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len) int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len)
{ {
return wc_Sha512Update(sha, data, 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); return Sha512FinalRaw(sha, hash, WC_SHA512_256_DIGEST_SIZE);
} }
int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash) int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
{ {
return Sha512_Family_Final(sha512, hash, WC_SHA512_256_DIGEST_SIZE, return Sha512_Family_Final(sha512, hash, WC_SHA512_256_DIGEST_SIZE,
InitSha512_256); InitSha512_256);
} }
#endif #endif
void wc_Sha512_256Free(wc_Sha512* sha) void wc_Sha512_256Free(wc_Sha512* sha)
{ {
wc_Sha512Free(sha); wc_Sha512Free(sha);
} }
#if defined(WOLFSSL_KCAPI_HASH) #if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
@ -1782,23 +1824,10 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
} }
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ /* copy this sha384 into tmpSha */
!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
ret = wc_Sha384Copy(sha384, tmpSha384); ret = wc_Sha384Copy(sha384, tmpSha384);
if (ret == 0) { if (ret == 0) {
ret = wc_Sha384Final(tmpSha384, hash); 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); wc_Sha384Free(tmpSha384);
} }
@ -1818,6 +1847,7 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
} }
XMEMCPY(dst, src, sizeof(wc_Sha384)); XMEMCPY(dst, src, sizeof(wc_Sha384));
#ifdef WOLFSSL_SMALL_STACK_CACHE #ifdef WOLFSSL_SMALL_STACK_CACHE
dst->W = NULL; dst->W = NULL;
#endif #endif
@ -1830,15 +1860,15 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
#endif #endif
#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW)
dst->ctx.mode = src->ctx.mode; esp_sha384_ctx_copy(src, dst);
dst->ctx.isfirstblock = src->ctx.isfirstblock;
dst->ctx.sha_type = src->ctx.sha_type;
#endif #endif
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
dst->flags |= WC_HASH_FLAG_ISCOPY; dst->flags |= WC_HASH_FLAG_ISCOPY;
#endif #endif
#if defined(WOLFSSL_HASH_KEEP) #if defined(WOLFSSL_HASH_KEEP)
if (src->msg != NULL) { if (src->msg != NULL) {
dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); 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_idf_version.h"
#include "esp_types.h" #include "esp_types.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_random.h"
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG #ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
#undef LOG_LOCAL_LEVEL #undef LOG_LOCAL_LEVEL
@ -39,31 +38,45 @@
#endif #endif
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include "soc/dport_reg.h" #if defined(CONFIG_IDF_TARGET_ESP32C3)
#include "soc/hwcrypto_reg.h" /* no includes for ESP32C3 at this time (no HW implemented yet) */
#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>
#elif defined(CONFIG_IDF_TARGET_ESP32S3) #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 #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 #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
int esp_ShowExtendedSystemInfo(void);
int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex); int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex);
int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBloxkTime); int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBloxkTime);
int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex); int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
@ -72,8 +85,6 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#if ESP_IDF_VERSION_MAJOR >= 4 #if ESP_IDF_VERSION_MAJOR >= 4
#include "esp32/rom/aes.h" #include "esp32/rom/aes.h"
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#include "esp32s3/rom/aes.h"
#else #else
#include "rom/aes.h" #include "rom/aes.h"
#endif #endif
@ -95,14 +106,15 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG #ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG
void wc_esp32TimerStart(); void wc_esp32TimerStart(void);
uint64_t wc_esp32elapsedTime(); uint64_t wc_esp32elapsedTime(void);
#endif /* WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */ #endif /* WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */
#if (!defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \ #if !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) && \
defined(WOLFSSL_SHA512)) && \ (!defined(NO_SHA) || !defined(NO_SHA256) || \
!defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) \
)
/* RAW hash function APIs are not implemented with esp32 hardware acceleration*/ /* RAW hash function APIs are not implemented with esp32 hardware acceleration*/
#define WOLFSSL_NO_HASH_RAW #define WOLFSSL_NO_HASH_RAW
@ -118,50 +130,67 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#undef SHA_CTX #undef SHA_CTX
typedef enum { typedef enum
ESP32_SHA_INIT = 0, {
ESP32_SHA_HW = 1, ESP32_SHA_INIT = 0,
ESP32_SHA_SW = 2, ESP32_SHA_HW = 1,
ESP32_SHA_SW = 2,
ESP32_SHA_HW_COPY = 3,
ESP32_SHA_FAIL_NEED_UNROLL = -1 ESP32_SHA_FAIL_NEED_UNROLL = -1
} ESP32_MODE; } ESP32_MODE;
typedef struct { typedef struct
byte isfirstblock; {
/* 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. /* we'll keep track of our own locks.
* actual enable/disable only occurs for ref_counts[periph] == 0 */ ** actual enable/disable only occurs for ref_counts[periph] == 0
int lockDepth; /* see ref_counts[periph] in periph_ctrl.c */ **
** 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 /* 0 (false) this is NOT first block.
typedef enum. */ ** 1 (true ) this is first block. */
#if defined(CONFIG_IDF_TARGET_ESP32S3) byte isfirstblock:1; /* 1 bit only for true / false */
SHA_TYPE sha_type;
#else
enum SHA_TYPE sha_type;
#endif
} WC_ESP32SHA; } 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_try_hw_lock(WC_ESP32SHA* ctx);
int esp_sha_hw_unlock(WC_ESP32SHA* ctx); int esp_sha_hw_unlock(WC_ESP32SHA* ctx);
struct wc_Sha; 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_digest_process(struct wc_Sha* sha, byte blockprocess);
int esp_sha_process(struct wc_Sha* sha, const byte* data); int esp_sha_process(struct wc_Sha* sha, const byte* data);
#ifndef NO_SHA256 #ifndef NO_SHA256
struct wc_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_digest_process(struct wc_Sha256* sha, byte blockprocess);
int esp_sha256_process(struct wc_Sha256* sha, const byte* data); int esp_sha256_process(struct wc_Sha256* sha, const byte* data);
int esp32_Transform_Sha256_demo(struct wc_Sha256* sha256, const byte* data); int esp32_Transform_Sha256_demo(struct wc_Sha256* sha256, const byte* data);
#endif #endif
/* TODO do we really call esp_sha512_process for WOLFSSL_SHA384 ? */ /* TODO do we really call esp_sha512_process for WOLFSSL_SHA384 ? */
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
struct wc_Sha512; 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_process(struct wc_Sha512* sha);
int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc); int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc);
#endif #endif