Espressif HW Improvements (#6624)

* Espressif HW Improvements
* revised AES HW/SW fallback logic for ESP32
This commit is contained in:
gojimmypi
2023-09-19 08:21:13 -07:00
committed by GitHub
parent 1149522357
commit 9398fa0736
17 changed files with 2996 additions and 782 deletions

View File

@@ -6,6 +6,7 @@ and have not yet been upgraded to the master branch V5.
See the latest [migration guides](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/index.html). See the latest [migration guides](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/index.html).
## Overview ## Overview
ESP-IDF development framework with wolfSSL by setting *WOLFSSL_ESPIDF* definition ESP-IDF development framework with wolfSSL by setting *WOLFSSL_ESPIDF* definition
Including the following examples: Including the following examples:
@@ -17,29 +18,57 @@ Including the following examples:
The *user_settings.h* file enables some of the hardened settings. The *user_settings.h* file enables some of the hardened settings.
## Requirements ## Requirements
1. [ESP-IDF development framework](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/) 1. [ESP-IDF development framework](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
## Setup for Linux ## Setup for Linux
1. Run `setup.sh` at _/path/to_`/wolfssl/IDE/Espressif/ESP-IDF/` to deploy files into ESP-IDF tree 1. Run `setup.sh` at _/path/to_`/wolfssl/IDE/Espressif/ESP-IDF/` to deploy files into ESP-IDF tree
2. Find Wolfssl files at _/path/to/esp_`/esp-idf/components/wolfssl/` 2. Find Wolfssl files at _/path/to/esp_`/esp-idf/components/wolfssl/`
3. Find [Example programs](https://github.com/wolfSSL/wolfssl/tree/master/IDE/Espressif/ESP-IDF/examples) under _/path/to/esp_`/esp-idf/examples/protocols/wolfssl_xxx` (where xxx is the project name) 3. Find [Example Programs](https://github.com/wolfSSL/wolfssl/tree/master/IDE/Espressif/ESP-IDF/examples) under _/path/to/esp_`/esp-idf/examples/protocols/wolfssl_xxx` (where xxx is the project name)
## Setup for Windows ## Setup for Windows
1. Run ESP-IDF Command Prompt (cmd.exe) or Run ESP-IDF PowerShell Environment 1. Run ESP-IDF Command Prompt (cmd.exe) or Run ESP-IDF PowerShell Environment
2. Run `setup_win.bat` at `.\IDE\Espressif\ESP-IDF\` 2. Run `setup_win.bat` at `.\IDE\Espressif\ESP-IDF\`
3. Find Wolfssl files at _/path/to/esp_`/esp-idf/components/wolfssl/` 3. Find Wolfssl files at _/path/to/esp_`/esp-idf/components/wolfssl/`
4. Find [Example programs](https://github.com/wolfSSL/wolfssl/tree/master/IDE/Espressif/ESP-IDF/examples) under _/path/to/esp_`/esp-idf/examples/protocols/wolfssl_xxx` (where xxx is the project name) 4. Find [Example programs](https://github.com/wolfSSL/wolfssl/tree/master/IDE/Espressif/ESP-IDF/examples) under _/path/to/esp_`/esp-idf/examples/protocols/wolfssl_xxx` (where xxx is the project name)
## Setup for VisualGDB
### Clone a specific version:
```
C:\SysGCC\esp32\esp-idf>git clone -b v5.0.2 --recursive https://github.com/espressif/esp-idf.git v5.0.2
```
## Configuration ## Configuration
1. The `user_settings.h` can be found in _/path/to/esp_`/esp-idf/components/wolfssl/include/user_settings.h` 1. The `user_settings.h` can be found in _/path/to/esp_`/esp-idf/components/wolfssl/include/user_settings.h`
## Build examples ## Build examples
1. See README in each example folder 1. See README in each example folder
## Support ## Support
For question please email [support@wolfssl.com] For question please email [support@wolfssl.com]
Note: This is tested with : Note: This is tested with :
- OS: Ubuntu 20.04.3 LTS and Microsoft Windows 10 Pro 10.0.19041 and well as WSL Ubuntu - OS: Ubuntu 20.04.3 LTS
- Microsoft Windows 10 Pro 10.0.19041
- WSL Ubuntu
- ESP-IDF: ESP-IDF v4.3.2 - ESP-IDF: ESP-IDF v4.3.2
- Module : ESP32-WROOM-32 - Module : ESP32-WROOM-32
## JTAG Debugging
All of the examples are configured to use either the on-board JTAG (when available) or
the open source [Tigard multi-protocol tool for hardware hacking](https://github.com/tigard-tools/tigard).
VisualGDB users should find the configuration file in the `interface\ftdi` directory:
```
C:\Users\%USERNAME%\AppData\Local\VisualGDB\EmbeddedDebugPackages\com.sysprogs.esp32.core\share\openocd\scripts\interface\ftdi
```

View File

@@ -15,7 +15,7 @@ Including the following examples:
2. Microchip CryptoAuthentication Library: https://github.com/MicrochipTech/cryptoauthlib 2. Microchip CryptoAuthentication Library: https://github.com/MicrochipTech/cryptoauthlib
## Setup ## Setup
1. Comment out `#define WOLFSSL_ESPWROOM32` in `/path/to/wolfssl/IDE/Espressif/ESP-IDF/user_settings.h`\ 1. Comment out `#define WOLFSSL_ESP32` in `/path/to/wolfssl/IDE/Espressif/ESP-IDF/user_settings.h`\
Uncomment out `#define WOLFSSL_ESPWROOM32SE` in `/path/to/wolfssl/IDE/Espressif/ESP-IDF/user_settings.h` Uncomment out `#define WOLFSSL_ESPWROOM32SE` in `/path/to/wolfssl/IDE/Espressif/ESP-IDF/user_settings.h`
* **Note:** crypt test will fail if enabled `WOLFSSL_ESPWROOM32SE` * **Note:** crypt test will fail if enabled `WOLFSSL_ESPWROOM32SE`
3. wolfSSL under ESP-IDF. Please see [README.md](https://github.com/wolfSSL/wolfssl/blob/master/IDE/Espressif/ESP-IDF/README.md) 3. wolfSSL under ESP-IDF. Please see [README.md](https://github.com/wolfSSL/wolfssl/blob/master/IDE/Espressif/ESP-IDF/README.md)

View File

@@ -27,11 +27,19 @@ Example build on WSL, assuming `git clone` from `c:\workspace`:
# switch to test example # switch to test example
cd /mnt/c/workspace/wolfssl/IDE/Espressif/ESP-IDF/examples/wolfssl_test cd /mnt/c/workspace/wolfssl/IDE/Espressif/ESP-IDF/examples/wolfssl_test
# Pick ESP-IDF install directory, this one for v4.4.2 in VisualGDB # Pick ESP-IDF install directory, this one for v5.1 in VisualGDB
. /mnt/c/SysGCC/esp32/esp-idf/v4.4.2/export.sh . /mnt/c/SysGCC/esp32/esp-idf/v5.1/export.sh
# build and flash, in this example to COM20 # set target chipset
idf.py build flash -p /dev/ttyS20 -b 921600 monitor idf.py set-target esp32s3
# erase
idf.py erase-flash -p /dev/ttyS24 -b 115200
# start with a low upload speed, then increase as found operational
idf.py
# build and flash, in this example to COM24
idf.py build flash -p /dev/ttyS24 -b 115200 monitor
``` ```
## Example Output ## Example Output

View File

@@ -50,7 +50,6 @@ set(COMPONENT_SRCDIRS "${WOLFSSL_ROOT}/src/"
"${WOLFSSL_ROOT}/wolfcrypt/src/" "${WOLFSSL_ROOT}/wolfcrypt/src/"
"${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif/" "${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif/"
"${WOLFSSL_ROOT}/wolfcrypt/src/port/atmel/" "${WOLFSSL_ROOT}/wolfcrypt/src/port/atmel/"
"${WOLFSSL_ROOT}/wolfcrypt/benchmark/"
"${WOLFSSL_ROOT}/wolfcrypt/test/" "${WOLFSSL_ROOT}/wolfcrypt/test/"
) )
@@ -192,6 +191,7 @@ set(COMPONENT_SRCEXCLUDE
"${WOLFSSL_ROOT}/src/pk.c" "${WOLFSSL_ROOT}/src/pk.c"
"${WOLFSSL_ROOT}/src/ssl_asn1.c" # included by ssl.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_bn.c" # included by ssl.c
"${WOLFSSL_ROOT}/src/ssl_certman.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

@@ -154,6 +154,8 @@ void app_main(void)
/* some interesting settings are target specific (ESP32, -C3, -S3, etc */ /* some interesting settings are target specific (ESP32, -C3, -S3, etc */
#if defined(CONFIG_IDF_TARGET_ESP32C3) #if defined(CONFIG_IDF_TARGET_ESP32C3)
/* not available for C3 at this time */ /* not available for C3 at this time */
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
/* not available for C6 at this time */
#elif defined(CONFIG_IDF_TARGET_ESP32S3) #elif defined(CONFIG_IDF_TARGET_ESP32S3)
ESP_LOGI(TAG, "CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ = %u MHz", ESP_LOGI(TAG, "CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ = %u MHz",
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ
@@ -185,8 +187,6 @@ void app_main(void)
#endif #endif
#endif #endif
#if defined (WOLFSSL_USE_TIME_HELPER) #if defined (WOLFSSL_USE_TIME_HELPER)
set_time(); set_time();
#endif #endif
@@ -224,9 +224,23 @@ void app_main(void)
/* see wolfssl/wolfcrypt/error-crypt.h */ /* see wolfssl/wolfcrypt/error-crypt.h */
} }
/* after the test, we'll just wait */ #ifdef INCLUDE_uxTaskGetStackHighWaterMark
ESP_LOGI(TAG, "Stack HWM: %d", uxTaskGetStackHighWaterMark(NULL));
ESP_LOGI(TAG, "Stack used: %d", CONFIG_ESP_MAIN_TASK_STACK_SIZE
- (uxTaskGetStackHighWaterMark(NULL) / 4));
#endif
ESP_LOGI(TAG, "\n\nDone!\n\n"
"If running from idf.py monitor, press twice: Ctrl+]");
/* done */
while (1) { while (1) {
/* nothing */ #if defined(SINGLE_THREADED)
} while (1);
#else
vTaskDelay(60000);
#endif
} /* done whle */
#endif #endif
} }

View File

@@ -18,12 +18,24 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/ */
#undef WOLFSSL_ESPIDF #undef WOLFSSL_ESPIDF
#undef WOLFSSL_ESP32 #undef WOLFSSL_ESP32
#undef WOLFSSL_ESPWROOM32SE #undef WOLFSSL_ESPWROOM32SE
#undef WOLFSSL_ESP32 #undef WOLFSSL_ESP32
#undef WOLFSSL_ESP8266 #undef WOLFSSL_ESP8266
/* The Espressif sdkconfig will have chipset info.
**
** Possible values:
**
** CONFIG_IDF_TARGET_ESP32
** CONFIG_IDF_TARGET_ESP32S3
** CONFIG_IDF_TARGET_ESP32C3
** CONFIG_IDF_TARGET_ESP32C6
*/
#include <sdkconfig.h>
#define WOLFSSL_ESPIDF #define WOLFSSL_ESPIDF
/* /*
@@ -85,11 +97,11 @@
/* #define CUSTOM_SLOT_ALLOCATION */ /* #define CUSTOM_SLOT_ALLOCATION */
#endif #endif
/* rsa primitive specific definition */ /* RSA primitive specific definition */
#if defined(WOLFSSL_ESP32) || defined(WOLFSSL_ESPWROOM32SE) #if defined(WOLFSSL_ESP32) || defined(WOLFSSL_ESPWROOM32SE)
/* Define USE_FAST_MATH and SMALL_STACK */ /* Define USE_FAST_MATH and SMALL_STACK */
#define ESP32_USE_RSA_PRIMITIVE #define ESP32_USE_RSA_PRIMITIVE
/* threshold for performance adjustment for hw primitive use */ /* threshold for performance adjustment for HW primitive use */
/* X bits of G^X mod P greater than */ /* X bits of G^X mod P greater than */
#define EPS_RSA_EXPT_XBTIS 36 #define EPS_RSA_EXPT_XBTIS 36
/* X and Y of X * Y mod P greater than */ /* X and Y of X * Y mod P greater than */
@@ -107,11 +119,50 @@
/* #define NO_ASN_TIME */ /* #define NO_ASN_TIME */
/* #define XTIME time */ /* #define XTIME time */
/* when you want not to use HW acceleration */
/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH*/
/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
/* adjust wait-timeout count if you see timeout in rsa hw acceleration */ /* adjust wait-timeout count if you see timeout in RSA HW acceleration */
#define ESP_RSA_TIMEOUT_CNT 0x249F00 #define ESP_RSA_TIMEOUT_CNT 0x249F00
#if defined(CONFIG_IDF_TARGET_ESP32)
/* when you want not to use HW acceleration on ESP32 (below for S3, etc */
/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
/* ESP32-S2 disabled by default; not implemented */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
/* when you want not to use HW acceleration on ESP32-S3 */
/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
/* ESP32-C3 disabled by default, not implemented */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
/* ESP32-C6 disabled by default, not implemented */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
#elif defined(CONFIG_IDF_TARGET_ESP32H2)
/* ESP32-H2 disabled by default, not implemented */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
#else
/* anything else unknown will have HW disabled by default */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
#endif

View File

@@ -469,24 +469,57 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#elif defined(WOLFSSL_ESP32_CRYPT) && \ #elif defined(WOLFSSL_ESP32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32_CRYPT_AES) !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
#include <esp_log.h>
#include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
const char* TAG = "aes";
#include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h" /* We'll use SW for fallback:
* unsupported key lengths. (e.g. ESP32-S3)
* chipsets not ikmplemented.
* hardware busy. */
#define NEED_AES_TABLES
#define NEED_AES_HW_FALLBACK
#define NEED_SOFTWARE_AES_SETKEY
#undef WOLFSSL_AES_DIRECT
#define WOLFSSL_AES_DIRECT
#if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT) /* If we choose to never have a fallback to SW: */
static WARN_UNUSED_RESULT int wc_AesEncrypt( #if !defined(NEED_AES_HW_FALLBACK) && (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
static WARN_UNUSED_RESULT int wc_AesEncrypt( /* calling this one when NO_AES_192 is defined */
Aes* aes, const byte* inBlock, byte* outBlock) Aes* aes, const byte* inBlock, byte* outBlock)
{ {
int ret;
/* Thread mutex protection handled in esp_aes_hw_InUse */ /* Thread mutex protection handled in esp_aes_hw_InUse */
return wc_esp32AesEncrypt(aes, inBlock, outBlock); #ifdef NEED_AES_HW_FALLBACK
if (wc_esp32AesSupportedKeyLen(aes)) {
ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
}
#else
ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
#endif
return ret;
} }
#endif #endif
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT) /* If we choose to never have a fallback to SW */
#if !defined(NEED_AES_HW_FALLBACK) && (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
static WARN_UNUSED_RESULT int wc_AesDecrypt( static WARN_UNUSED_RESULT int wc_AesDecrypt(
Aes* aes, const byte* inBlock, byte* outBlock) Aes* aes, const byte* inBlock, byte* outBlock)
{ {
int ret = 0;
/* Thread mutex protection handled in esp_aes_hw_InUse */ /* Thread mutex protection handled in esp_aes_hw_InUse */
return wc_esp32AesDecrypt(aes, inBlock, outBlock); #ifdef NEED_AES_HW_FALLBACK
if (wc_esp32AesSupportedKeyLen(aes)) {
ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
}
else {
ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
}
#else
/* if we don't need fallback, always use HW */
ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
#endif
return ret;
} }
#endif #endif
@@ -848,7 +881,10 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#ifdef NEED_AES_TABLES #ifdef NEED_AES_TABLES
#if !defined(WOLFSSL_SILABS_SE_ACCEL) #if (!defined(WOLFSSL_SILABS_SE_ACCEL) && \
!defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) \
) || \
(defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && defined(NEED_AES_HW_FALLBACK))
static const FLASH_QUALIFIER word32 rcon[] = { static const FLASH_QUALIFIER word32 rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000,
@@ -1775,14 +1811,21 @@ static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
((word32)(t)[o2] << 8) | ((word32)(t)[o3] << 0)) ((word32)(t)[o2] << 8) | ((word32)(t)[o3] << 0))
#endif #endif
/* Software AES - ECB Encrypt */ /* this section disabled with NO_AES_192 */
static WARN_UNUSED_RESULT int wc_AesEncrypt( static WARN_UNUSED_RESULT int wc_AesEncrypt( /* calling this one when missing NO_AES_192 */
Aes* aes, const byte* inBlock, byte* outBlock) Aes* aes, const byte* inBlock, byte* outBlock)
{ {
word32 s0, s1, s2, s3; word32 s0, s1, s2, s3;
word32 t0, t1, t2, t3; word32 t0, t1, t2, t3;
word32 r = aes->rounds >> 1; word32 r;
const word32* rk = aes->key; const word32* rk;
if (aes == NULL) {
return BAD_FUNC_ARG;
}
r = aes->rounds >> 1;
rk = aes->key;
if (r > 7 || r == 0) { if (r > 7 || r == 0) {
WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E); WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
@@ -1854,6 +1897,21 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt(
} }
#endif #endif
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
if (wc_esp32AesSupportedKeyLen(aes)) {
return wc_esp32AesEncrypt(aes, inBlock, outBlock);
}
else {
/* For example, the ESP32-S3 does not support HW for len = 24,
* so fall back to SW */
#ifdef DEBUG_WOLFSSL
ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
aes->keylen);
#endif
}
#endif
/* /*
* map byte array block to cipher state * map byte array block to cipher state
* and add initial round key: * and add initial round key:
@@ -2114,7 +2172,7 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt(
XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
return 0; return 0;
} } /* wc_AesEncrypt */
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */ #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
#if defined(HAVE_AES_DECRYPT) #if defined(HAVE_AES_DECRYPT)
@@ -2163,8 +2221,15 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
{ {
word32 s0, s1, s2, s3; word32 s0, s1, s2, s3;
word32 t0, t1, t2, t3; word32 t0, t1, t2, t3;
word32 r = aes->rounds >> 1; word32 r;
const word32* rk = aes->key; const word32* rk;
if (aes == NULL) {
return BAD_FUNC_ARG;
}
r = aes->rounds >> 1;
rk = aes->key;
if (r > 7 || r == 0) { if (r > 7 || r == 0) {
WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E); WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
@@ -2210,6 +2275,19 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
AES_DECRYPTION, kAlgorithm_SSS_AES_ECB); AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
} }
#endif #endif
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
if (wc_esp32AesSupportedKeyLen(aes)) {
return wc_esp32AesDecrypt(aes, inBlock, outBlock);
}
else {
/* For example, the ESP32-S3 does not support HW for len = 24,
* so fall back to SW */
#ifdef DEBUG_WOLFSSL
ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
"unsupported keylen = %d", aes->keylen);
#endif
} /* else !wc_esp32AesSupportedKeyLen for ESP32 */
#endif
/* /*
* map byte array block to cipher state * map byte array block to cipher state
@@ -2422,7 +2500,7 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
return 0; return 0;
} } /* wc_AesDecrypt[_SW]() */
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */ #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
#endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AES_DECRYPT */
@@ -2661,15 +2739,16 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
{ {
return wc_AesSetKey(aes, userKey, keylen, iv, dir); return wc_AesSetKey(aes, userKey, keylen, iv, dir);
} }
#elif defined(WOLFSSL_ESP32_CRYPT) && \ #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
!defined(NO_WOLFSSL_ESP32_CRYPT_AES) /* This is the only definition for HW only.
* but needs to be renamed when fallback needed.
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, * See call in wc_AesSetKey() */
int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
const byte* iv, int dir) const byte* iv, int dir)
{ {
(void)dir; (void)dir;
(void)iv; (void)iv;
ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) { if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@@ -2700,13 +2779,9 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
aes->left = 0; aes->left = 0;
#endif #endif
return wc_AesSetIV(aes, iv); return wc_AesSetIV(aes, iv);
} } /* wc_AesSetKey */
int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, /* end #elif ESP32 */
const byte* iv, int dir)
{
return wc_AesSetKey(aes, userKey, keylen, iv, dir);
}
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES) #elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
@@ -2797,7 +2872,13 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */ /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
#else #else
#define NEED_SOFTWARE_AES_SETKEY
#endif
/* Either we fell though with no HW support at all,
* or perhaps there's HW support for *some* keylengths
* and we need both HW and SW. */
#ifdef NEED_SOFTWARE_AES_SETKEY
/* Software AES - SetKey */ /* Software AES - SetKey */
static WARN_UNUSED_RESULT int wc_AesSetKeyLocal( static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir, Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
@@ -2971,10 +3052,26 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
rk = aes->key; rk = aes->key;
XMEMCPY(rk, userKey, keylen); XMEMCPY(rk, userKey, keylen);
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \ #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
(!defined(WOLFSSL_ESP32_CRYPT) || \ (!defined(WOLFSSL_ESP32_CRYPT) || \
defined(NO_WOLFSSL_ESP32_CRYPT_AES)) defined(NO_WOLFSSL_ESP32_CRYPT_AES))
/* software */
ByteReverseWords(rk, rk, keylen); ByteReverseWords(rk, rk, keylen);
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
if (wc_esp32AesSupportedKeyLen(aes)) {
/* supported lengths don't get reversed */
ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
}
else {
/* For example, the ESP32-S3 does not support HW for len = 24,
* so fall back to SW */
#ifdef DEBUG_WOLFSSL
ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
#endif
/* When not ESP32 HW, we need to reverse endianess */
ByteReverseWords(rk, rk, keylen);
}
#endif #endif
#ifdef WOLFSSL_IMXRT_DCP #ifdef WOLFSSL_IMXRT_DCP
@@ -3179,7 +3276,7 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
wc_MemZero_Check(&temp, sizeof(temp)); wc_MemZero_Check(&temp, sizeof(temp));
#endif #endif
return ret; return ret;
} } /* wc_AesSetKeyLocal */
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
const byte* iv, int dir) const byte* iv, int dir)
@@ -3191,8 +3288,22 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1); /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
if (wc_esp32AesSupportedKeyLenValue(keylen)) {
ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
} }
else {
#ifdef DEBUG_WOLFSSL
ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
keylen);
#endif
}
#endif
return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
} /* wc_AesSetKey() */
#if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER) #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
/* AES-CTR and AES-DIRECT need to use this for key setup */ /* AES-CTR and AES-DIRECT need to use this for key setup */
@@ -3951,14 +4062,12 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
#elif defined(WOLFSSL_ESP32_CRYPT) && \ #elif defined(WOLFSSL_ESP32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32_CRYPT_AES) !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) /* We'll use SW for fall back:
{ * unsupported key lengths
return wc_esp32AesCbcEncrypt(aes, out, in, sz); * hardware busy */
} #define NEED_SW_AESCBC
int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #define NEED_AESCBC_HW_FALLBACK
{
return wc_esp32AesCbcDecrypt(aes, out, in, sz);
}
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES) #elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{ {
@@ -3988,9 +4097,15 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */ /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
#else #else
/* Reminder: Some HW implementations may also define this as needed.
* (e.g. for unsupported key length fallback) */
#define NEED_SW_AESCBC
#endif
#ifdef NEED_SW_AESCBC
/* Software AES - CBC Encrypt */ /* Software AES - CBC Encrypt */
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{ {
word32 blocks; word32 blocks;
@@ -4108,6 +4223,21 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
} }
#endif #endif
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
if (wc_esp32AesSupportedKeyLen(aes)) {
ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
return wc_esp32AesCbcEncrypt(aes, out, in, sz);
}
else {
/* For example, the ESP32-S3 does not support HW for len = 24,
* so fall back to SW */
#ifdef DEBUG_WOLFSSL
ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
"unsupported keylen = %d", aes->keylen);
#endif
}
#endif
while (blocks--) { while (blocks--) {
int ret; int ret;
xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE); xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
@@ -4121,14 +4251,13 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
} }
return 0; return 0;
} } /* wc_AesCbcEncrypt */
#ifdef HAVE_AES_DECRYPT #ifdef HAVE_AES_DECRYPT
/* Software AES - CBC Decrypt */ /* Software AES - CBC Decrypt */
int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{ {
word32 blocks; word32 blocks;
if (aes == NULL || out == NULL || in == NULL) { if (aes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@@ -4137,6 +4266,21 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
return 0; return 0;
} }
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
if (wc_esp32AesSupportedKeyLen(aes)) {
ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
return wc_esp32AesCbcDecrypt(aes, out, in, sz);
}
else {
/* For example, the ESP32-S3 does not support HW for len = 24,
* so fall back to SW */
#ifdef DEBUG_WOLFSSL
ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
"unsupported keylen = %d", aes->keylen);
#endif
}
#endif
blocks = sz / AES_BLOCK_SIZE; blocks = sz / AES_BLOCK_SIZE;
if (sz % AES_BLOCK_SIZE) { if (sz % AES_BLOCK_SIZE) {
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
@@ -4242,7 +4386,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
return 0; return 0;
} }
#endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AES_DECRYPT */
#endif /* AES-CBC block */ #endif /* AES-CBC block */
#endif /* HAVE_AES_CBC */ #endif /* HAVE_AES_CBC */

View File

@@ -11,25 +11,30 @@ For detail about ESP32 HW Acceleration, you can find in [Technical Reference Man
To enable hw acceleration : To enable hw acceleration :
* Uncomment out `#define WOLFSSL_ESPIDF` in `/path/to/wolfssl/wolfssl/wolfcrypt/settings.h` * Uncomment out `#define WOLFSSL_ESPIDF` in `/path/to/wolfssl/wolfssl/wolfcrypt/settings.h`
* Uncomment out `#define WOLFSSL_ESPWROOM32` in `/path/to/wolfssl/wolfssl/wolfcrypt/settings.h` * Uncomment out `#define WOLFSSL_ESP32` in `/path/to/wolfssl/wolfssl/wolfcrypt/settings.h`
To disable portions of the hardware acceleration you can optionally define: To disable portions of the hardware acceleration you can optionally define:
```c ```c
/* Disabled SHA, AES and RSA acceleration */ /* Disabled SHA, AES and RSA acceleration */
#define NO_ESP32WROOM32_CRYPT #define NO_ESP32_CRYPT
/* Disabled AES acceleration */ /* Disabled AES acceleration */
#define NO_WOLFSSL_ESP32WROOM32_CRYPT_AES #define NO_WOLFSSL_ESP32_CRYPT_AES
/* Disabled SHA acceleration */ /* Disabled SHA acceleration */
#define NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH #define NO_WOLFSSL_ESP32_CRYPT_HASH
/* Disabled RSA Primitive acceleration */ /* Disabled RSA Primitive acceleration */
#define NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
``` ```
### Coding ### Coding
In your application you must include `<wolfssl/wolfcrypt/settings.h>` before any other wolfSSL headers. If building the sources directly we recommend defining `WOLFSSL_USER_SETTINGS` and adding your own `user_settings.h` file. You can find a good reference for this in `IDE/GCC-ARM/Header/user_settings.h`. In your application you must include `<wolfssl/wolfcrypt/settings.h>` before any other wolfSSL headers. If building the sources directly we recommend defining `WOLFSSL_USER_SETTINGS` and adding your own `user_settings.h` file. You can find a good reference for this in `IDE/GCC-ARM/Header/user_settings.h`.
To view disassembly, add `__attribute__((section(".iram1")))` decorator. Foe example:
```
static int __attribute__((section(".iram1"))) memblock_peek(volatile u_int32_t mem_address)
```
### Benchmarks ### Benchmarks

View File

@@ -125,7 +125,7 @@ static int esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
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 %d", mode);
/* check mode */ /* check mode */
if (mode == ESP32_AES_UPDATEKEY_ENCRYPT) { if (mode == ESP32_AES_UPDATEKEY_ENCRYPT) {
@@ -141,13 +141,6 @@ static int esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
} }
} /* if mode */ } /* 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 ** ESP32: see table 22-1 in ESP32 Technical Reference
** ESP32S3: see table 19-2 in ESP32S3 Technical Reference ** ESP32S3: see table 19-2 in ESP32S3 Technical Reference
@@ -165,12 +158,21 @@ static int esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
default: break; default: break;
} }
#if CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S3
if (mode_ == 1 || mode_ == 5 || mode_ == 7) { if (mode_ == 1 || mode_ == 5 || mode_ == 7) {
/* this should have been detected in aes.c and fall back to SW */
ESP_LOGE(TAG, "esp_aes_hw_Set_KeyMode unsupported mode: %i", mode_); ESP_LOGE(TAG, "esp_aes_hw_Set_KeyMode unsupported mode: %i", mode_);
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
#endif #endif
if (ret == 0) {
/* update key */
for (i = 0; i < (ctx->keylen) / sizeof(word32); i++) {
DPORT_REG_WRITE((volatile uint32_t*)(AES_KEY_BASE + (i * 4)),
*(((word32*)ctx->key) + i)
);
}
if (ret == 0) { if (ret == 0) {
DPORT_REG_WRITE(AES_MODE_REG, mode_); DPORT_REG_WRITE(AES_MODE_REG, mode_);
@@ -243,6 +245,60 @@ static void esp_aes_bk(const byte* in, byte* out)
ESP_LOGV(TAG, "leave esp_aes_bk"); ESP_LOGV(TAG, "leave esp_aes_bk");
} /* esp_aes_bk */ } /* esp_aes_bk */
/*
* wc_esp32AesSupportedKeyLen
* @brief: returns 1 if AES key length supported in HW, 0 if not
* @param aes:a value of a ley length */
WOLFSSL_LOCAL int wc_esp32AesSupportedKeyLenValue(int keylen)
{
int ret = 0;
#if defined(CONFIG_IDF_TARGET_ESP32)
if (keylen == 16 || keylen == 24 || keylen == 32) {
ret = 1;
}
else {
ret = 0; /* keylen 24 (192 bit) not supported */
}
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
ret = 0; /* not supported */
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
if (keylen == 16 || keylen == 32) {
ret = 1;
}
else {
ret = 0; /* keylen 24 (192 bit) not supported */
}
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
ret = 0; /* not supported */
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
ret = 0; /* not supported */
#elif defined(CONFIG_IDF_TARGET_ESP32H2)
ret = 0; /* not supported */
#else
ret = 0; /* if we don't know, then it is not supported */
#endif
return ret;
}
/*
* wc_esp32AesSupportedKeyLen
* @brief: returns 1 if AES key length supported in HW, 0 if not
* @param aes: a pointer of the AES object used to encrypt data */
WOLFSSL_LOCAL int wc_esp32AesSupportedKeyLen(struct Aes* aes)
{
int ret;
if (aes == NULL) {
ret = 0; /* we need a valid aes object to get its keylength */
}
else {
ret = wc_esp32AesSupportedKeyLenValue(aes->keylen);
}
return ret;
}
/* /*
* wc_esp32AesEncrypt * wc_esp32AesEncrypt
* @brief: a one block encrypt of the input block, into the output block * @brief: a one block encrypt of the input block, into the output block
@@ -252,7 +308,7 @@ static void esp_aes_bk(const byte* in, byte* out)
* the encrypted message * the encrypted message
* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. * @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
*/ */
int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out) WOLFSSL_LOCAL int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)
{ {
int ret = 0; int ret = 0;
@@ -287,7 +343,7 @@ int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)
* the decrypted message * the decrypted message
* @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported. * @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
*/ */
int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out) WOLFSSL_LOCAL int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
{ {
int ret; int ret;
@@ -325,7 +381,7 @@ int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
* @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. * @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) WOLFSSL_LOCAL int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{ {
int ret; int ret;
int i; int i;
@@ -343,7 +399,7 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
if (ret == 0) { if (ret == 0) {
ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT); ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);
if (ret != 0) { if (ret != 0) {
ESP_LOGE(TAG, "wc_esp32AesCbcEncrypt failed HW Set KeyMode"); ESP_LOGW(TAG, "wc_esp32AesCbcEncrypt failed HW Set KeyMode");
} }
} /* if set esp_aes_hw_InUse successful */ } /* if set esp_aes_hw_InUse successful */
@@ -367,7 +423,7 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
esp_aes_hw_Leave(); esp_aes_hw_Leave();
ESP_LOGV(TAG, "leave wc_esp32AesCbcEncrypt"); ESP_LOGV(TAG, "leave wc_esp32AesCbcEncrypt");
return 0; return ret;
} /* wc_esp32AesCbcEncrypt */ } /* wc_esp32AesCbcEncrypt */
/* /*
@@ -382,7 +438,7 @@ int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
* @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. * @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) WOLFSSL_LOCAL int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{ {
int ret; int ret;
@@ -401,7 +457,7 @@ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
if (ret == 0) { if (ret == 0) {
ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT); ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
if (ret != 0) { if (ret != 0) {
ESP_LOGE(TAG, "wc_esp32AesCbcDecrypt failed HW Set KeyMode"); ESP_LOGW(TAG, "wc_esp32AesCbcDecrypt failed HW Set KeyMode");
} }
} }
@@ -425,7 +481,7 @@ int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
esp_aes_hw_Leave(); esp_aes_hw_Leave();
ESP_LOGV(TAG, "leave wc_esp32AesCbcDecrypt"); ESP_LOGV(TAG, "leave wc_esp32AesCbcDecrypt");
return 0; return ret;
} /* wc_esp32AesCbcDecrypt */ } /* wc_esp32AesCbcDecrypt */
#endif /* WOLFSSL_ESP32_CRYPT */ #endif /* WOLFSSL_ESP32_CRYPT */

File diff suppressed because it is too large Load Diff

View File

@@ -65,11 +65,11 @@ static const char* TAG = "wolf_hw_sha";
static int InUse = 0; static int InUse = 0;
#else #else
static wolfSSL_Mutex sha_mutex = NULL; static wolfSSL_Mutex sha_mutex = NULL;
#endif
#if defined(DEBUG_WOLFSSL) #if defined(DEBUG_WOLFSSL)
/* Only when debugging, we'll keep tracking of block numbers. */ /* Only when debugging, we'll keep tracking of block numbers. */
static int this_block_num = 0; static int this_block_num = 0;
#endif
#endif #endif
/* esp_sha_init /* esp_sha_init
@@ -502,7 +502,7 @@ int esp_sha512_ctx_copy(struct wc_Sha512* src, struct wc_Sha512* dst)
** Returns zero for bad digest size type request. ** Returns zero for bad digest size type request.
** **
*/ */
static word32 wc_esp_sha_digest_size(enum SHA_TYPE type) static word32 wc_esp_sha_digest_size(WC_ESP_SHA_TYPE type)
{ {
int ret = 0; int ret = 0;
ESP_LOGV(TAG, " esp_sha_digest_size"); ESP_LOGV(TAG, " esp_sha_digest_size");

View File

@@ -18,9 +18,31 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/ */
/*
** Version / Platform info.
**
** This could evolve into a wolfSSL-wide feature. For now, here only. See:
** https://github.com/wolfSSL/wolfssl/pull/6149
*/
#include <wolfssl/wolfcrypt/settings.h> #include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/version.h> #include <wolfssl/version.h>
#include <wolfssl/wolfcrypt/wolfmath.h> /* needed to print MATH_INT_T value */
#if defined(WOLFSSL_ESPIDF)
#include <esp_log.h>
#include "sdkconfig.h"
#define WOLFSSL_VERSION_PRINTF(...) ESP_LOGI(TAG, __VA_ARGS__)
#else
#include <stdio.h>
#define WOLFSSL_VERSION_PRINTF(...) { printf(__VA_ARGS__); printf("\n"); }
#endif
static const char* TAG = "esp32_util";
/* some functions are only applicable when hardware encryption is enabled */
#if defined(WOLFSSL_ESP32_CRYPT) && \ #if defined(WOLFSSL_ESP32_CRYPT) && \
(!defined(NO_AES) || !defined(NO_SHA) || !defined(NO_SHA256) ||\ (!defined(NO_AES) || !defined(NO_SHA) || !defined(NO_SHA256) ||\
defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)) defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512))
@@ -29,6 +51,7 @@
#include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h> #include <wolfssl/wolfcrypt/logging.h>
#define MAX_WORDS_ESP_SHOW_MP 32
/* /*
* initialize our mutex used to lock hardware access * initialize our mutex used to lock hardware access
@@ -39,7 +62,7 @@
* other value from wc_InitMutex() * other value from wc_InitMutex()
* *
*/ */
int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex) { WOLFSSL_LOCAL int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex) {
if (mutex == NULL) { if (mutex == NULL) {
return BAD_MUTEX_E; return BAD_MUTEX_E;
} }
@@ -51,7 +74,7 @@ int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex) {
* call the ESP-IDF mutex lock; xSemaphoreTake * call the ESP-IDF mutex lock; xSemaphoreTake
* *
*/ */
int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBlockTime) { WOLFSSL_LOCAL int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t block_time) {
if (mutex == NULL) { if (mutex == NULL) {
WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex"); WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex");
return BAD_MUTEX_E; return BAD_MUTEX_E;
@@ -60,7 +83,7 @@ int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBlockTime) {
#ifdef SINGLE_THREADED #ifdef SINGLE_THREADED
return wc_LockMutex(mutex); /* xSemaphoreTake take with portMAX_DELAY */ return wc_LockMutex(mutex); /* xSemaphoreTake take with portMAX_DELAY */
#else #else
return ((xSemaphoreTake( *mutex, xBlockTime ) == pdTRUE) ? 0 : BAD_MUTEX_E); return ((xSemaphoreTake( *mutex, block_time ) == pdTRUE) ? 0 : BAD_MUTEX_E);
#endif #endif
} }
@@ -68,7 +91,7 @@ int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBlockTime) {
* call the ESP-IDF mutex UNlock; xSemaphoreGive * call the ESP-IDF mutex UNlock; xSemaphoreGive
* *
*/ */
int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) { WOLFSSL_LOCAL int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) {
if (mutex == NULL) { if (mutex == NULL) {
WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex"); WOLFSSL_ERROR_MSG("esp_CryptHwMutexLock called with null mutex");
return BAD_MUTEX_E; return BAD_MUTEX_E;
@@ -81,22 +104,13 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) {
return 0; return 0;
#endif #endif
} }
#endif /* WOLFSSL_ESP32_CRYPT, etc. */
/*
** Version / Platform info. /* esp_ShowExtendedSystemInfo and supporting info.
** **
** This could evolve into a wolfSSL-wide feature. For now, here only. See: ** available regardless if HW acceleration is turned on or not.
** 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
/* /*
******************************************************************************* *******************************************************************************
@@ -182,8 +196,15 @@ static int ShowExtendedSystemInfo_platform_espressif()
WOLFSSL_VERSION_PRINTF("ESP32_CRYPT is enabled for ESP32-S2."); WOLFSSL_VERSION_PRINTF("ESP32_CRYPT is enabled for ESP32-S2.");
#elif defined(CONFIG_IDF_TARGET_ESP32S3) #elif defined(CONFIG_IDF_TARGET_ESP32S3)
WOLFSSL_VERSION_PRINTF("ESP32_CRYPT is enabled for ESP32-S3."); WOLFSSL_VERSION_PRINTF("ESP32_CRYPT is enabled for ESP32-S3.");
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
WOLFSSL_VERSION_PRINTF("ESP32_CRYPT is enabled for ESP32-C3.");
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
WOLFSSL_VERSION_PRINTF("ESP32_CRYPT is enabled for ESP32-C6.");
#elif defined(CONFIG_IDF_TARGET_ESP32H2)
WOLFSSL_VERSION_PRINTF("ESP32_CRYPT is enabled for ESP32-H2.");
#else #else
#error "ESP32_CRYPT not yet supported on this IDF TARGET" /* this should have been detected & disabled in user_settins.h */
#error "ESP32_CRYPT not yet supported on this IDF TARGET"
#endif #endif
/* Even though enabled, some specifics may be disabled */ /* Even though enabled, some specifics may be disabled */
@@ -201,7 +222,8 @@ static int ShowExtendedSystemInfo_platform_espressif()
WOLFSSL_VERSION_PRINTF("NO_WOLFSSL_ESP32_CRYPT_RSA_PRI defined!" WOLFSSL_VERSION_PRINTF("NO_WOLFSSL_ESP32_CRYPT_RSA_PRI defined!"
"(disabled HW RSA)"); "(disabled HW RSA)");
#endif #endif
#endif
#endif /* ! NO_ESP32_CRYPT */
return 0; return 0;
} }
@@ -230,6 +252,14 @@ static int ShowExtendedSystemInfo_git()
** but not desired for introspection which requires object code to be ** but not desired for introspection which requires object code to be
** maximally bitwise-invariant. ** maximally bitwise-invariant.
*/ */
#if defined(LIBWOLFSSL_VERSION_GIT_TAG)
/* git config describe --tags --abbrev=0 */
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_TAG = %s",
LIBWOLFSSL_VERSION_GIT_TAG);
#endif
#if defined(LIBWOLFSSL_VERSION_GIT_ORIGIN) #if defined(LIBWOLFSSL_VERSION_GIT_ORIGIN)
/* git config --get remote.origin.url */ /* git config --get remote.origin.url */
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_ORIGIN = %s", WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_ORIGIN = %s",
@@ -243,16 +273,19 @@ static int ShowExtendedSystemInfo_git()
#endif #endif
#if defined(LIBWOLFSSL_VERSION_GIT_HASH) #if defined(LIBWOLFSSL_VERSION_GIT_HASH)
/* git rev-parse HEAD */
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_HASH = %s", WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_HASH = %s",
LIBWOLFSSL_VERSION_GIT_HASH); LIBWOLFSSL_VERSION_GIT_HASH);
#endif #endif
#if defined(LIBWOLFSSL_VERSION_GIT_SHORT_HASH ) #if defined(LIBWOLFSSL_VERSION_GIT_SHORT_HASH )
/* git rev-parse --short HEAD */
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_SHORT_HASH = %s", WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_SHORT_HASH = %s",
LIBWOLFSSL_VERSION_GIT_SHORT_HASH); LIBWOLFSSL_VERSION_GIT_SHORT_HASH);
#endif #endif
#if defined(LIBWOLFSSL_VERSION_GIT_HASH_DATE) #if defined(LIBWOLFSSL_VERSION_GIT_HASH_DATE)
/* git show --no-patch --no-notes --pretty=\'\%cd\' */
WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_HASH_DATE = %s", WOLFSSL_VERSION_PRINTF("LIBWOLFSSL_VERSION_GIT_HASH_DATE = %s",
LIBWOLFSSL_VERSION_GIT_HASH_DATE); LIBWOLFSSL_VERSION_GIT_HASH_DATE);
#endif #endif
@@ -292,10 +325,9 @@ static int ShowExtendedSystemInfo_platform()
/* /*
******************************************************************************* *******************************************************************************
** The public ShowExtendedSystemInfo() ** The internal, portable, but currently private ShowExtendedSystemInfo()
******************************************************************************* *******************************************************************************
*/ */
int ShowExtendedSystemInfo(void) int ShowExtendedSystemInfo(void)
{ {
WOLFSSL_VERSION_PRINTF("Extended Version and Platform Information."); WOLFSSL_VERSION_PRINTF("Extended Version and Platform Information.");
@@ -324,12 +356,140 @@ int ShowExtendedSystemInfo(void)
return 0; return 0;
} }
WOLFSSL_LOCAL int esp_ShowExtendedSystemInfo()
int esp_ShowExtendedSystemInfo()
{ {
return ShowExtendedSystemInfo(); return ShowExtendedSystemInfo();
} }
/* Print a MATH_INT_T attribute list.
*
* Note with the right string parameters, the result can be pasted as
* initialization code.
*/
WOLFSSL_LOCAL int esp_show_mp_attributes(char* c, MATH_INT_T* X)
{
static const char* MP_TAG = "MATH_INT_T";
int ret = 0;
if (X == NULL) {
ret = -1;
ESP_LOGV(MP_TAG, "esp_show_mp_attributes called with X == NULL");
}
else {
ESP_LOGI(MP_TAG, "");
ESP_LOGI(MP_TAG, "%s.used = %d;", c, X->used);
#if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
ESP_LOGI(MP_TAG, "%s.sign = %d;", c, X->sign);
#endif #endif
}
return ret;
}
/* Print a MATH_INT_T value.
*
* Note with the right string parameters, the result can be pasted as
* initialization code.
*/
WOLFSSL_LOCAL int esp_show_mp(char* c, MATH_INT_T* X)
{
static const char* MP_TAG = "MATH_INT_T";
int ret = MP_OKAY;
int words_to_show = 0;
size_t i;
if (X == NULL) {
ret = -1;
ESP_LOGV(MP_TAG, "esp_show_mp called with X == NULL");
}
else {
words_to_show = X->used;
/* if too small, we'll show just 1 word */
if (words_to_show < 1) {
ESP_LOGI(MP_TAG, "Bad word count. Adjusting from %d to %d",
words_to_show,
1);
words_to_show = 1;
}
#ifdef MAX_WORDS_ESP_SHOW_MP
/* if too big, we'll show MAX_WORDS_ESP_SHOW_MP words */
if (words_to_show > MAX_WORDS_ESP_SHOW_MP) {
ESP_LOGI(MP_TAG, "Limiting word count from %d to %d",
words_to_show,
MAX_WORDS_ESP_SHOW_MP);
words_to_show = MAX_WORDS_ESP_SHOW_MP;
}
#endif
ESP_LOGI(MP_TAG, "%s:",c);
esp_show_mp_attributes(c, X);
for (i = 0; i < words_to_show; i++) {
ESP_LOGI(MP_TAG, "%s.dp[%2d] = 0x%08x; /* %2d */ ",
c, /* the supplied variable name */
i, /* the index, i for dp[%d] */
(unsigned int)X->dp[i], /* the value */
i /* the index, again, for comment */
);
}
ESP_LOGI(MP_TAG, "");
}
return ret;
}
/* Perform a full mp_cmp and binary compare.
* (typically only used during debugging) */
WOLFSSL_LOCAL int esp_mp_cmp(char* name_A, MATH_INT_T* A, char* name_B, MATH_INT_T* B)
{
int ret = MP_OKAY;
int e;
e = memcmp(A, B, sizeof(mp_int));
if (mp_cmp(A, B) == MP_EQ) {
if (e == 0) {
/* we always want to be here: both esp_show_mp and binary equal! */
ESP_LOGV(TAG, "fp_cmp and memcmp match for %s and %s!",
name_A, name_B);
}
else {
ret = MP_VAL;
ESP_LOGE(TAG, "fp_cmp match, memcmp mismatch for %s and %s!",
name_A, name_B);
if (A->dp[0] == 1) {
ESP_LOGE(TAG, "Both memcmp and fp_cmp fail for %s and %s!",
name_A, name_B);
}
}
}
else {
ret = MP_VAL;
if (e == 0) {
/* if mp_cmp says different,
* but memcmp says equal, that's a problem */
ESP_LOGE(TAG, "memcmp error for %s and %s!",
name_A, name_B);
}
else {
/* in the normal case where mp_cmp and memcmp say the
* values are different, we'll optionally show details. */
ESP_LOGI(TAG, "e = %d", e);
ESP_LOGE(TAG, "fp_cmp mismatch! memcmp "
"offset 0x%02x for %s vs %s!",
e, name_A, name_B);
if (A->dp[0] == 1) {
ESP_LOGE(TAG, "Both memcmp and fp_cmp fail for %s and %s!",
name_A, name_B);
}
}
ESP_LOGV(TAG, "Mismatch for %s and %s!",
name_A, name_B);
}
if (ret == MP_OKAY) {
ESP_LOGV(TAG, "esp_mp_cmp equal for %s and %s!",
name_A, name_B);
}
else {
#ifdef DEBUG_WOLFSSL
esp_show_mp(name_A, A);
esp_show_mp(name_B, B);
#endif
}
return ret;
}

View File

@@ -58,6 +58,28 @@
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h> #include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
#endif #endif
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
#if defined(WOLFSSL_ESP32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32_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_ESP32_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
#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 */
#else
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
#endif
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
#if defined(WOLFSSL_ESP32_CRYPT) && \ #if defined(WOLFSSL_ESP32_CRYPT) && \
!defined(NO_WOLFSSL_ESP32_CRYPT_HASH) !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
@@ -775,6 +797,9 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash)
else { else {
ret = esp_sha_process(sha, (const byte*)local); ret = esp_sha_process(sha, (const byte*)local);
} }
#elif defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
/* The ESP32C3 is different; SW crypto here. Not yet implemented */
ret = XTRANSFORM(sha, (const byte*)local);
#else #else
/* /*
** The #if defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) also falls ** The #if defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) also falls
@@ -835,6 +860,9 @@ 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);
/* we'll always reset state upon exit and return the error code from above,
* which may cause fall back to SW if HW is busy. we do not return result
* of initSha here */
(void)InitSha(sha); /* reset state */ (void)InitSha(sha); /* reset state */
return ret; return ret;

View File

@@ -109,7 +109,9 @@ on the specific device platform.
** **
** Beware of possible conflict in test.c (that one now named TEST_TAG) ** Beware of possible conflict in test.c (that one now named TEST_TAG)
*/ */
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
static const char* TAG = "wc_sha256"; static const char* TAG = "wc_sha256";
#endif
#endif #endif
#if defined(WOLFSSL_TI_HASH) #if defined(WOLFSSL_TI_HASH)

View File

@@ -1021,6 +1021,7 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512)
ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE); ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE);
#endif #endif
return 0; return 0;
} }

View File

@@ -52,6 +52,39 @@
#include <wolfcrypt/src/asm.c> /* will define asm MACROS or C ones */ #include <wolfcrypt/src/asm.c> /* will define asm MACROS or C ones */
#include <wolfssl/wolfcrypt/wolfmath.h> /* common functions */ #include <wolfssl/wolfcrypt/wolfmath.h> /* common functions */
#ifdef WOLFSSL_ESPIDF
#include <esp_log.h>
#include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
#endif
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI)
static const char* TAG = "TFM"; /* esp log breadcrumb */
#if !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI)
/* Each individual math HW can be turned on or off.
* Listed in order of complexity and historical difficulty. */
#define WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
#define WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
#define WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
#endif
#if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL)
#undef WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
#endif
#if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
#undef WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
#endif
#if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD)
#undef WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
#endif
/* Note with HW there's a EPS_RSA_EXPT_XBTIS setting
* as for some small numbers, SW may be faster.
* See ESP_LOGV messages for EPS_RSA_EXPT_XBTIS values. */
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI */
#if defined(FREESCALE_LTC_TFM) #if defined(FREESCALE_LTC_TFM)
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h> #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
#endif #endif
@@ -139,11 +172,44 @@ int s_fp_add(fp_int *a, fp_int *b, fp_int *c)
c->used = y; c->used = y;
t = 0; t = 0;
#ifdef HONOR_MATH_USED_LENGTH
for (x = 0; x < y; x++) {
if ( (x < a->used) && (x < b->used) ) {
/* x is less than both [a].used and [b].used, so we add both */
t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]);
}
else {
/* Here we honor the actual [a].used and [b].used values
* and NOT assume that values beyond [used] are zero. */
if ((x >= a->used) && (x < b->used)) {
/* x more than [a].used, [b] ok, so just add [b] */
t += /* ((fp_word)(0)) + */ ((fp_word)b->dp[x]);
}
else {
if ((x < a->used) && (x >= b->used)) {
/* x more than [b].used, [a] ok, so just add [a] */
t += ((fp_word)a->dp[x]) /* + (fp_word)(0) */;
}
else {
/* we should never get here, as a.used cannot be greater
* than b.used, while b.used is greater than a.used! */
/* t += 0 + 0 */
}
}
}
c->dp[x] = (fp_digit)t;
t >>= DIGIT_BIT;
}
#else
/* the original code */
for (x = 0; x < y; x++) { for (x = 0; x < y; x++) {
t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]); t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]);
c->dp[x] = (fp_digit)t; c->dp[x] = (fp_digit)t;
t >>= DIGIT_BIT; t >>= DIGIT_BIT;
} }
#endif /* HONOR_MATH_USED_LENGTH */
if (t != 0) { if (t != 0) {
if (x == FP_SIZE) if (x == FP_SIZE)
return FP_VAL; return FP_VAL;
@@ -229,15 +295,9 @@ void s_fp_sub(fp_int *a, fp_int *b, fp_int *c)
/* c = a * b */ /* c = a * b */
int fp_mul(fp_int *A, fp_int *B, fp_int *C) int fp_mul(fp_int *A, fp_int *B, fp_int *C)
{ {
int ret = 0; int ret = FP_OKAY;
int y, yy, oldused; int y, yy, oldused;
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI)
ret = esp_mp_mul(A, B, C);
if(ret != -2) return ret;
#endif
oldused = C->used; oldused = C->used;
y = MAX(A->used, B->used); y = MAX(A->used, B->used);
@@ -249,6 +309,36 @@ int fp_mul(fp_int *A, fp_int *B, fp_int *C)
goto clean; goto clean;
} }
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL)
if (esp_hw_validation_active()) {
ESP_LOGV(TAG, "Skipping call to esp_mp_mul "
"during active validation.");
}
else {
ret = esp_mp_mul(A, B, C); /* HW accelerated multiply */
switch (ret) {
case MP_OKAY:
goto clean; /* success */
break;
case WC_HW_WAIT_E: /* MP_HW_BUSY math HW busy, fall back */
case MP_HW_FALLBACK: /* forced fallback from HW to SW */
case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
/* fall back to software, below */
break;
default:
/* Once we've failed, exit without trying to continue.
* We may have mangled operands: (e.g. Z = X * Z)
* Future implementation may consider saving operands,
* but errors should never occur. */
goto clean; /* error */
break;
}
}
/* fall through to software calcs */
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
/* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size /* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size
of the largest input. We also want to avoid doing excess mults if the of the largest input. We also want to avoid doing excess mults if the
inputs are not close to the next power of two. That is, for example, inputs are not close to the next power of two. That is, for example,
@@ -536,6 +626,7 @@ WC_INLINE static int fp_mul_comba_mulx(fp_int *A, fp_int *B, fp_int *C)
} }
#endif #endif
/* C = (A * B) */
int fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) int fp_mul_comba(fp_int *A, fp_int *B, fp_int *C)
{ {
int ret = 0; int ret = 0;
@@ -602,6 +693,8 @@ int fp_mul_comba(fp_int *A, fp_int *B, fp_int *C)
COMBA_FINI; COMBA_FINI;
dst->used = pa; dst->used = pa;
/* warning: WOLFSSL_SP_INT_NEGATIVE may disable negative numbers */
dst->sign = A->sign ^ B->sign; dst->sign = A->sign ^ B->sign;
fp_clamp(dst); fp_clamp(dst);
fp_copy(dst, C); fp_copy(dst, C);
@@ -2158,6 +2251,7 @@ static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P,
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(R, NULL, DYNAMIC_TYPE_BIGINT); XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
#endif #endif
return err; return err;
} }
@@ -2993,13 +3087,11 @@ static int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P,
#undef WINSIZE #undef WINSIZE
#endif #endif
/* Y = (G * X) mod P */
int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
{ {
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \ int retHW = FP_OKAY;
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI)
int x = fp_count_bits (X);
#endif #endif
/* handle modulus of zero and prevent overflows */ /* handle modulus of zero and prevent overflows */
@@ -3019,12 +3111,37 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
return FP_OKAY; return FP_OKAY;
} }
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \ #if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI) if (esp_hw_validation_active()) {
if(x > EPS_RSA_EXPT_XBTIS) { ESP_LOGV(TAG, "Skipping call to esp_mp_exptmod "
return esp_mp_exptmod(G, X, x, P, Y); "during active validation.");
} }
#endif else {
/* HW accelerated exptmod */
retHW = esp_mp_exptmod(G, X, P, Y);
switch (retHW) {
case MP_OKAY:
/* successfully computed in HW */
return retHW;
break;
case WC_HW_WAIT_E: /* MP_HW_BUSY math HW busy, fall back */
case MP_HW_FALLBACK: /* forced fallback from HW to SW */
case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
/* use software calc */
break;
default:
/* Once we've failed, exit without trying to continue.
* We may have mangled operands: (e.g. Z = X * Z)
* Future implementation may consider saving operands,
* but hard errors should never actually occur. */
return retHW; /* error */
break;
} /* switch */
} /* if validation check */
/* fall through to software calcs */
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
if (X->sign == FP_NEG) { if (X->sign == FP_NEG) {
#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ #ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */
@@ -3049,11 +3166,11 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
if (err == FP_OKAY) { if (err == FP_OKAY) {
fp_copy(X, &tmp[1]); fp_copy(X, &tmp[1]);
tmp[1].sign = FP_ZPOS; tmp[1].sign = FP_ZPOS;
#ifdef TFM_TIMING_RESISTANT #ifdef TFM_TIMING_RESISTANT
err = _fp_exptmod_ct(&tmp[0], &tmp[1], tmp[1].used, P, Y); err = _fp_exptmod_ct(&tmp[0], &tmp[1], tmp[1].used, P, Y);
#else #else
err = _fp_exptmod_nct(&tmp[0], &tmp[1], P, Y); err = _fp_exptmod_nct(&tmp[0], &tmp[1], P, Y);
#endif #endif
if ((err == 0) && (P->sign == FP_NEG)) { if ((err == 0) && (P->sign == FP_NEG)) {
err = fp_add(Y, P, Y); err = fp_add(Y, P, Y);
} }
@@ -3064,7 +3181,7 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
return err; return err;
#else #else
return FP_VAL; return FP_VAL;
#endif #endif /* POSITIVE_EXP_ONLY check */
} }
else if (G->used == 1 && G->dp[0] == 2) { else if (G->used == 1 && G->dp[0] == 2) {
return _fp_exptmod_base_2(X, X->used, P, Y); return _fp_exptmod_base_2(X, X->used, P, Y);
@@ -3081,10 +3198,8 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y)
{ {
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \ int retHW = FP_OKAY;
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI)
int x = fp_count_bits (X);
#endif #endif
/* handle modulus of zero and prevent overflows */ /* handle modulus of zero and prevent overflows */
@@ -3104,12 +3219,30 @@ int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y)
return FP_OKAY; return FP_OKAY;
} }
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \ #if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI) retHW = esp_mp_exptmod(G, X, P, Y);
if(x > EPS_RSA_EXPT_XBTIS) { switch (retHW) {
return esp_mp_exptmod(G, X, x, P, Y); case MP_OKAY:
} /* successfully computed in HW */
#endif return retHW;
break;
case WC_HW_WAIT_E: /* MP_HW_BUSY math HW busy, fall back */
case MP_HW_FALLBACK: /* forced fallback from HW to SW */
case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
/* use software calc */
break;
default:
/* Once we've failed, exit without trying to continue.
* We may have mangled operands: (e.g. Z = X * Z)
* Future implementation may consider saving operands,
* but hard errors should never actually occur. */
return retHW;
break;
} /* HW result switch */
/* falling through to SW: */
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
if (X->sign == FP_NEG) { if (X->sign == FP_NEG) {
#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ #ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */
@@ -3166,9 +3299,8 @@ int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y)
int fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) int fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
{ {
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \ #if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI) int retHW = FP_OKAY;
int x = fp_count_bits (X);
#endif #endif
/* handle modulus of zero and prevent overflows */ /* handle modulus of zero and prevent overflows */
@@ -3188,11 +3320,29 @@ int fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
return FP_OKAY; return FP_OKAY;
} }
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \ #if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI) retHW = esp_mp_exptmod(G, X, P, Y);
if(x > EPS_RSA_EXPT_XBTIS) { switch (retHW) {
return esp_mp_exptmod(G, X, x, P, Y); case MP_OKAY:
/* successfully computed in HW */
return retHW;
break;
case WC_HW_WAIT_E: /* MP_HW_BUSY math HW busy, fall back */
case MP_HW_FALLBACK: /* forced fallback from HW to SW */
case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
/* use software calc */
break;
default:
/* Once we've failed, exit without trying to continue.
* We may have mangled operands: (e.g. Z = X * Z)
* Future implementation may consider saving operands,
* but hard errors should never actually occur. */
return retHW;
break;
} }
/* falling through to SW: */
#endif #endif
if (X->sign == FP_NEG) { if (X->sign == FP_NEG) {
@@ -4505,16 +4655,32 @@ int wolfcrypt_mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
#endif #endif
{ {
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \ int ret = MP_OKAY;
!defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI) #ifdef WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
int A = fp_count_bits (a); ret = esp_mp_mulmod(a, b, c, d);
int B = fp_count_bits (b); switch (ret) {
case MP_OKAY:
/* successfully computed in HW */
break;
if( A >= ESP_RSA_MULM_BITS && B >= ESP_RSA_MULM_BITS) case WC_HW_WAIT_E: /* MP_HW_BUSY math HW busy, fall back */
return esp_mp_mulmod(a, b, c, d); case MP_HW_FALLBACK: /* forced fallback from HW to SW */
else case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
#endif /* use software calc */
return fp_mulmod(a, b, c, d); ret = fp_mulmod(a, b, c, d);
break;
default:
/* Once we've failed, exit without trying to continue.
* We may have mangled operands: (e.g. Z = X * Z)
* Future implementation may consider saving operands,
* but hard errors should never actually occur. */
break;
}
#else /* no HW */
ret = fp_mulmod(a, b, c, d);
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
return ret;
} }
/* d = a - b (mod c) */ /* d = a - b (mod c) */

View File

@@ -22,13 +22,160 @@
#define __ESP32_CRYPT_H__ #define __ESP32_CRYPT_H__
#include "wolfssl/wolfcrypt/settings.h" #include "sdkconfig.h" /* ensure ESP-IDF settings are available everywhere */
/* wolfSSL */
#include <wolfssl/wolfcrypt/settings.h> /* references user_settings.h */
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/types.h> /* for MATH_INT_T */ #include <wolfssl/wolfcrypt/types.h> /* for MATH_INT_T */
#include "esp_idf_version.h" /* Espressif */
#include "esp_types.h" #include <esp_idf_version.h>
#include "esp_log.h" #include <esp_types.h>
#include <esp_log.h>
/* exit codes to be used in tfm.c, sp_int.c, integer.c, etc.
*
* see wolfssl/wolfcrypt/error-crypt.h
*
* WC_HW_E - generic hardware failure. Consider falling back to SW.
* WC_HW_WAIT_E - waited too long for HW, fall back to SW
*/
/* exit code only used in Espressif port */
/* MP_HW_FALLBACK: signal to caller to fall back to SW for math:
* algorithm not supported in SW
* known state needing only SW, (e.g. ctx copy)
* any other reason to force SW */
#define MP_HW_FALLBACK (-108)
/* MP_HW_VALIDATION_ACTIVE this is informative only:
* typically also means "MP_HW_FALLBACK": fall back to SW.
* optional HW validation active, so compute in SW to compare.
* fall back to SW, typically only used during debugging
*/
#define MP_HW_VALIDATION_ACTIVE (-109)
/*
*******************************************************************************
*******************************************************************************
**
** Primary Settings:
**
** WOLFSSL_ESP32_CRYPT_RSA_PRI
** Defined in wolfSSL settings.h: this turns on or off esp32_mp math library.
** Unless turned off, this is enabled by default for the ESP32
**
** NO_ESP32_CRYPT
** When defined, disables all hardware acceleration on the ESP32
**
** NO_WOLFSSL_ESP32_CRYPT_HASH
** Used to disabled only hash hardware algorithms: SHA2, etc.
**
** WOLFSSL_NOSHA512_224
** Define to disable SHA-512/224
**
** WOLFSSL_NOSHA512_256
** Define to disable SHA-512/512
**
** NO_WOLFSSL_ESP32_CRYPT_AES
** Used to disable only AES hardware algorithms. Software used instead.
**
** NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
** Turns off hardware acceleration esp_mp_mul()
**
** NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
** Turns off hardware acceleration esp_mp_exptmod()
**
** NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
** Turns off hardware acceleration esp_mp_mulmod()
**
*******************************************************************************
** Math library settings: TFM
*******************************************************************************
** Listed in increasing order of complexity:
**
** WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
** When defined, use hardware acceleration esp_mp_mul()
** for Large Number Multiplication: Z = X * Y
**
** WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
** When defined, use hardware acceleration esp_mp_exptmod()
** for Large Number Modular Exponentiation Z = X^Y mod M
**
** WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
** When defined, use hardware acceleration esp_mp_mulmod()
** for Large Number Modular Multiplication: Z = X * Y mod M
**
*******************************************************************************
** Optional Settings:
*******************************************************************************
**
** WOLFSSL_HW_METRICS
** Enables metric counters for calls to HW, success, fall back, oddities.
**
** DEBUG_WOLFSSL
** Turns on development testing. Validates HW accelerated results to software
** - Automatically turns on WOLFSSL_HW_METRICS
**
** LOG_LOCAL_LEVEL
** Debugging. Default value is ESP_LOG_DEBUG
**
** ESP_VERIFY_MEMBLOCK
** Used to re-read data from registers in esp32_mp & verify written contents
** actually match the source data.
**
** WOLFSSL_ESP32_CRYPT_DEBUG
** When defined, enables hardware cryptography debugging
**
** NO_HW_MATH_TEST
** Even if HW is enabled, do not run HW math tests. See HW_MATH_ENABLED.
**
** NO_ESP_MP_MUL_EVEN_ALT_CALC
** Used during Z = X × Y mod M
** By default, even moduli use a two step HW esp_mp_mul with SW mp_mod.
** Enable this to instead fall back to pure software mp_mulmod.
**
** NO_RECOVER_SOFTWARE_CALC
** When defined, will NOT recover software calculation result when not
** matched with hardware. Useful only during development. Needs DEBUG_WOLFSSL
**
** ESP_PROHIBIT_SMALL_X
** When set to 1 X operands less than 8 bits will fall back to SW
**
** ESP_NO_ERRATA_MITIGATION
** Disable all errata mitigation code.
**
** USE_ESP_DPORT_ACCESS_READ_BUFFER
** Sets ESP_NO_ERRATA_MITIGATION and uses esp_dport_access_read_buffer()
**
*******************************************************************************
** Settings used from <esp_idf_version.h>
*******************************************************************************
**
** ESP_IDF_VERSION_MAJOR
**
**
*******************************************************************************
** Settings used from ESP-IDF (sdkconfig.h)
*******************************************************************************
**
**
*******************************************************************************
**
**
*******************************************************************************
** Informative settings. Not meant to be edited
*******************************************************************************
**
** HW_MATH_ENABLED
** Used to detect if any hardware math acceleration algorithms are used.
** This is typically only used to flag wolfCrypt tests to run HW tests.
** See NO_HW_MATH_TEST.
**
*******************************************************************************
*/
#ifdef WOLFSSL_ESP32_CRYPT_DEBUG #ifdef WOLFSSL_ESP32_CRYPT_DEBUG
#undef LOG_LOCAL_LEVEL #undef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
@@ -38,17 +185,8 @@
#endif #endif
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#if defined(CONFIG_IDF_TARGET_ESP32C3)
/* no includes for ESP32C3 at this time (no HW implemented yet) */ #if defined(CONFIG_IDF_TARGET_ESP32)
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h"
#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR >= 5
#include "esp_private/periph_ctrl.h"
#else
#include "driver/periph_ctrl.h"
#endif
#else
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/hwcrypto_reg.h" #include "soc/hwcrypto_reg.h"
@@ -67,19 +205,72 @@
#else #else
#include <rom/ets_sys.h> #include <rom/ets_sys.h>
#endif #endif
#define ESP_PROHIBIT_SMALL_X 0
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
#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
#define ESP_PROHIBIT_SMALL_X 0
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#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
#define ESP_PROHIBIT_SMALL_X 0
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
/* no includes for ESP32C3 at this time (no HW implemented yet) */
#else
/* not yet supported. no HW */
#endif #endif
#if defined(USE_ESP_DPORT_ACCESS_READ_BUFFER)
#define ESP_NO_ERRATA_MITIGATION
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
int esp_ShowExtendedSystemInfo(void); /*
******************************************************************************
** Some common esp utilities
******************************************************************************
*/
int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex); WOLFSSL_LOCAL int esp_ShowExtendedSystemInfo(void);
int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBloxkTime);
int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex); /* Compare MATH_INT_T A to MATH_INT_T B
* During debug, the strings name_A and name_B can help
* identify variable name. */
WOLFSSL_LOCAL int esp_mp_cmp(char* name_A, MATH_INT_T* A, char* name_B, MATH_INT_T* B);
/* Show MATH_INT_T value attributes. */
WOLFSSL_LOCAL int esp_show_mp_attributes(char* c, MATH_INT_T* X);
/* Show MATH_INT_T value.
*
* Calls esp_show_mp_attributes().
*
* During debug, the string name_A can help
* identify variable name. */
WOLFSSL_LOCAL int esp_show_mp(char* name_X, MATH_INT_T* X);
/* To use a Mutex, if must first be initialized */
WOLFSSL_LOCAL int esp_CryptHwMutexInit(wolfSSL_Mutex* mutex);
/* When the HW is in use, the mutex will be locked. */
WOLFSSL_LOCAL int esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t block_time);
/* Release the mutex to indicate the HW is no longer in use. */
WOLFSSL_LOCAL int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#ifndef NO_AES #ifndef NO_AES
@@ -89,7 +280,8 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#include "rom/aes.h" #include "rom/aes.h"
#endif #endif
typedef enum tagES32_AES_PROCESS { typedef enum tagES32_AES_PROCESS
{
ESP32_AES_LOCKHW = 1, ESP32_AES_LOCKHW = 1,
ESP32_AES_UPDATEKEY_ENCRYPT = 2, ESP32_AES_UPDATEKEY_ENCRYPT = 2,
ESP32_AES_UPDATEKEY_DECRYPT = 3, ESP32_AES_UPDATEKEY_DECRYPT = 3,
@@ -97,12 +289,20 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
} ESP32_AESPROCESS; } ESP32_AESPROCESS;
struct Aes; /* see aes.h */ struct Aes; /* see aes.h */
int wc_esp32AesCbcEncrypt(struct Aes* aes, byte* out, const byte* in, word32 sz); WOLFSSL_LOCAL int wc_esp32AesSupportedKeyLenValue(int keylen);
int wc_esp32AesCbcDecrypt(struct Aes* aes, byte* out, const byte* in, word32 sz); WOLFSSL_LOCAL int wc_esp32AesSupportedKeyLen(struct Aes* aes);
int wc_esp32AesEncrypt(struct Aes *aes, const byte* in, byte* out); WOLFSSL_LOCAL int wc_esp32AesCbcEncrypt(struct Aes* aes,
int wc_esp32AesDecrypt(struct Aes *aes, const byte* in, byte* out); byte* out,
const byte* in,
word32 sz);
WOLFSSL_LOCAL int wc_esp32AesCbcDecrypt(struct Aes* aes,
byte* out,
const byte* in,
word32 sz);
WOLFSSL_LOCAL int wc_esp32AesEncrypt(struct Aes *aes, const byte* in, byte* out);
WOLFSSL_LOCAL int wc_esp32AesDecrypt(struct Aes *aes, const byte* in, byte* out);
#endif #endif /* ! NO_AES */
#ifdef WOLFSSL_ESP32_CRYPT_DEBUG #ifdef WOLFSSL_ESP32_CRYPT_DEBUG
@@ -116,14 +316,34 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) \ 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
#define SHA_CTX ETS_SHAContext #define SHA_CTX ETS_SHAContext
#if ESP_IDF_VERSION_MAJOR >= 4 #if ESP_IDF_VERSION_MAJOR >= 4
#if defined(CONFIG_IDF_TARGET_ESP32)
#include "esp32/rom/sha.h" #include "esp32/rom/sha.h"
#define WC_ESP_SHA_TYPE enum SHA_TYPE
#elif defined(CONFIG_IDF_TARGET_ESP32C2)
#include "esp32c2/rom/sha.h"
#define WC_ESP_SHA_TYPE SHA_TYPE
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
#include "esp32c3/rom/sha.h"
#define WC_ESP_SHA_TYPE SHA_TYPE
#elif defined(CONFIG_IDF_TARGET_ESP32H2)
#include "esp32h2/rom/sha.h"
#define WC_ESP_SHA_TYPE SHA_TYPE
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
#include "esp32s2/rom/sha.h"
#define WC_ESP_SHA_TYPE SHA_TYPE
#elif defined(CONFIG_IDF_TARGET_ESP32S3) #elif defined(CONFIG_IDF_TARGET_ESP32S3)
#include "esp32s3/rom/sha.h" #include "esp32s3/rom/sha.h"
#define WC_ESP_SHA_TYPE SHA_TYPE
#else
#include "rom/sha.h"
#define WC_ESP_SHA_TYPE SHA_TYPE
#endif
#else #else
#include "rom/sha.h" #include "rom/sha.h"
#endif #endif
@@ -154,48 +374,49 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
** **
** the Espressif type: SHA1, SHA256, etc. ** the Espressif type: SHA1, SHA256, etc.
*/ */
enum SHA_TYPE sha_type;
WC_ESP_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
** **
** 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. */ byte lockDepth : 7; /* 7 bits for a small number, pack with below. */
/* 0 (false) this is NOT first block. /* 0 (false) this is NOT first block.
** 1 (true ) this is first block. */ ** 1 (true ) this is first block. */
byte isfirstblock:1; /* 1 bit only for true / false */ byte isfirstblock : 1; /* 1 bit only for true / false */
} WC_ESP32SHA; } WC_ESP32SHA;
int esp_sha_init(WC_ESP32SHA* ctx, enum wc_HashType hash_type); WOLFSSL_LOCAL int esp_sha_init(WC_ESP32SHA* ctx, enum wc_HashType hash_type);
int esp_sha_init_ctx(WC_ESP32SHA* ctx); WOLFSSL_LOCAL int esp_sha_init_ctx(WC_ESP32SHA* ctx);
int esp_sha_try_hw_lock(WC_ESP32SHA* ctx); WOLFSSL_LOCAL int esp_sha_try_hw_lock(WC_ESP32SHA* ctx);
int esp_sha_hw_unlock(WC_ESP32SHA* ctx); WOLFSSL_LOCAL 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); WOLFSSL_LOCAL int esp_sha_ctx_copy(struct wc_Sha* src, struct wc_Sha* dst);
int esp_sha_digest_process(struct wc_Sha* sha, byte blockprocess); WOLFSSL_LOCAL int esp_sha_digest_process(struct wc_Sha* sha, byte blockprocess);
int esp_sha_process(struct wc_Sha* sha, const byte* data); WOLFSSL_LOCAL 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); WOLFSSL_LOCAL 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); WOLFSSL_LOCAL int esp_sha256_ctx_copy(struct wc_Sha256* src, struct wc_Sha256* dst);
int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess); WOLFSSL_LOCAL int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess);
int esp_sha256_process(struct wc_Sha256* sha, const byte* data); WOLFSSL_LOCAL int esp_sha256_process(struct wc_Sha256* sha, const byte* data);
int esp32_Transform_Sha256_demo(struct wc_Sha256* sha256, const byte* data); WOLFSSL_LOCAL 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); WOLFSSL_LOCAL 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); WOLFSSL_LOCAL int esp_sha512_ctx_copy(struct wc_Sha512* src, struct wc_Sha512* dst);
int esp_sha512_process(struct wc_Sha512* sha); WOLFSSL_LOCAL int esp_sha512_process(struct wc_Sha512* sha);
int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc); WOLFSSL_LOCAL int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc);
#endif #endif
#endif /* NO_SHA && */ #endif /* NO_SHA && etc */
#if !defined(NO_RSA) || defined(HAVE_ECC) #if !defined(NO_RSA) || defined(HAVE_ECC)
@@ -204,6 +425,7 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
#define ESP_RSA_TIMEOUT_CNT 0x249F00 #define ESP_RSA_TIMEOUT_CNT 0x249F00
#endif #endif
#ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
/* /*
* The parameter names in the Espressif implementation are arbitrary. * The parameter names in the Espressif implementation are arbitrary.
* *
@@ -214,26 +436,120 @@ int esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);
/* Z = (X ^ Y) mod M : Espressif generic notation */ /* Z = (X ^ Y) mod M : Espressif generic notation */
/* Y = (G ^ X) mod P : wolfSSL DH reference notation */ /* Y = (G ^ X) mod P : wolfSSL DH reference notation */
int esp_mp_exptmod(MATH_INT_T* X, /* G */ WOLFSSL_LOCAL int esp_mp_exptmod(MATH_INT_T* X, /* G */
MATH_INT_T* Y, /* X */ MATH_INT_T* Y, /* X */
word32 Xbits, /* Ys typically = mp_count_bits (X) */
MATH_INT_T* M, /* P */ MATH_INT_T* M, /* P */
MATH_INT_T* Z); /* Y */ MATH_INT_T* Z); /* Y */
/* HW_MATH_ENABLED is typically used in wolfcrypt tests */
#undef HW_MATH_ENABLED
#define HW_MATH_ENABLED
#endif /* ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
#ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
/* Z = X * Y */ /* Z = X * Y */
int esp_mp_mul(MATH_INT_T* X, WOLFSSL_LOCAL int esp_mp_mul(MATH_INT_T* X,
MATH_INT_T* Y, MATH_INT_T* Y,
MATH_INT_T* Z); MATH_INT_T* Z);
/* HW_MATH_ENABLED is typically used in wolfcrypt tests */
#undef HW_MATH_ENABLED
#define HW_MATH_ENABLED
#endif /* ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
#ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
/* Z = X * Y (mod M) */ /* Z = X * Y (mod M) */
int esp_mp_mulmod(MATH_INT_T* X, WOLFSSL_LOCAL int esp_mp_mulmod(MATH_INT_T* X,
MATH_INT_T* Y, MATH_INT_T* Y,
MATH_INT_T* M, MATH_INT_T* M,
MATH_INT_T* Z); MATH_INT_T* Z);
/* HW_MATH_ENABLED is typically used in wolfcrypt tests */
#undef HW_MATH_ENABLED
#define HW_MATH_ENABLED
#endif /* ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
#endif /* !NO_RSA || HAVE_ECC*/ #endif /* !NO_RSA || HAVE_ECC*/
WOLFSSL_LOCAL int esp_hw_validation_active(void);
#ifdef WOLFSSL_HW_METRICS
int esp_hw_show_mp_metrics(void);
#endif
#define ESP_MP_HW_LOCK_MAX_DELAY ( TickType_t ) 0xffUL
/*
* Errata Mitigation. See
* https://www.espressif.com/sites/default/files/documentation/esp32_errata_en.pdf
* https://www.espressif.com/sites/default/files/documentation/esp32-c3_errata_en.pdf
* https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf
*/
#if defined(CONFIG_IDF_TARGET_ESP32) && !defined(ESP_NO_ERRATA_MITIGATION)
/* some of these may be tuned for specific silicon versions */
#define ESP_EM__MP_HW_WAIT_CLEAN {__asm__ __volatile__("memw");}
#define ESP_EM__MP_HW_WAIT_DONE {__asm__ __volatile__("memw");}
#define ESP_EM__POST_SP_MP_HW_LOCK {__asm__ __volatile__("memw");}
#define ESP_EM__PRE_MP_HW_WAIT_CLEAN {__asm__ __volatile__("memw");}
#define ESP_EM__PRE_DPORT_READ {__asm__ __volatile__("memw");}
#define ESP_EM__PRE_DPORT_WRITE {__asm__ __volatile__("memw");}
/* Non-FIFO read may not be needed in chip revision v3.0. */
#define ESP_EM__READ_NON_FIFO_REG {DPORT_SEQUENCE_REG_READ(0x3FF40078);}
/* When the CPU frequency is 160 MHz, add six <20>nop<6F> between two consecutive
** FIFO reads. When the CPU frequency is 240 MHz, add seven <20>nop<6F> between
** two consecutive FIFO reads. See 3.16 */
#if defined(CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80)
#define ESP_EM__3_16 { \
__asm__ __volatile__("memw"); \
__asm__ __volatile__("nop"); /* 1 */ \
__asm__ __volatile__("nop"); /* 2 */ \
__asm__ __volatile__("nop"); /* 3 */ \
__asm__ __volatile__("nop"); /* 4 */ \
__asm__ __volatile__("nop"); /* 5 */ \
};
#elif defined(CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160)
#define ESP_EM__3_16 { \
__asm__ __volatile__("memw"); \
__asm__ __volatile__("nop"); /* 1 */ \
__asm__ __volatile__("nop"); /* 2 */ \
__asm__ __volatile__("nop"); /* 3 */ \
__asm__ __volatile__("nop"); /* 4 */ \
__asm__ __volatile__("nop"); /* 5 */ \
__asm__ __volatile__("nop"); /* 6 */ \
__asm__ __volatile__("nop"); /* 7 */ \
};
#elif defined(CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240)
#define ESP_EM__3_16 { \
__asm__ __volatile__("memw"); \
__asm__ __volatile__("nop"); /* 1 */ \
__asm__ __volatile__("nop"); /* 2 */ \
__asm__ __volatile__("nop"); /* 3 */ \
__asm__ __volatile__("nop"); /* 4 */ \
__asm__ __volatile__("nop"); /* 5 */ \
__asm__ __volatile__("nop"); /* 6 */ \
__asm__ __volatile__("nop"); /* 7 */ \
__asm__ __volatile__("nop"); /* 8 */ \
__asm__ __volatile__("nop"); /* 9 */ \
};
#else
#define ESP_EM__3_16 {};
#endif
#define ESP_EM__POST_PROCESS_START { ESP_EM__3_16 };
#define ESP_EM__DPORT_FIFO_READ { ESP_EM__3_16 };
#else
#define ESP_EM__3_16 {};
#define ESP_EM__MP_HW_WAIT_CLEAN {};
#define ESP_EM__MP_HW_WAIT_DONE {};
#define ESP_EM__POST_SP_MP_HW_LOCK {};
#define ESP_EM__PRE_MP_HW_WAIT_CLEAN {};
#define ESP_EM__POST_PROCESS_START {};
#define ESP_EM__DPORT_FIFO_READ {};
#define ESP_EM__READ_NON_FIFO_REG {};
#define ESP_EM__PRE_DPORT_READ {};
#define ESP_EM__PRE_DPORT_WRITE {};
#endif
/* end c++ wrapper */ /* end c++ wrapper */
#ifdef __cplusplus #ifdef __cplusplus
} }