Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Espressif ESP32-C3 ESP32-C6 ESP32-S2 Hardware Acceleration #6990

Merged
merged 3 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion IDE/Espressif/ESP-IDF/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,40 @@ Including the following examples:

1. [ESP-IDF development framework](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)

## Setup for Linux
## wolfSSL as an Espressif component

There are various methods available for using wolfSSL as a component:

* Managed Component - easiest to get started.
* Local component directory - best for development.
* Install locally - least flexible, but project is fully self-contained.

## Espressif Managed Components

Visit https://components.espressif.com/components/wolfssl/wolfssl and see the instructions. Typically:

```
idf.py add-dependency "wolfssl/wolfssl^5.6.0-stable"
```

## Standard local component:

See the [template example](./examples/template/README.md). Simply created a `wolfssl` directory in the
local project `components` directory and place the [CMakeLists.txt](./examples/template/components/CMakeLists.txt)
file there. Then add a `components/wolfssl/include` directory and place the [user_settings.h](/examples/template/components/wolfssl/include/user_settings.h)
file there. If wolfSSL is in a structure such as `./workspace/wolfssl` with respect to your project at `./workspace/wolfssl`,
then the cmake file should automatically find the wolfSSL source code. Otherwise set the cmake `WOLFSSL_ROOT` variable
in the top-level CMake file. Examples:

```cmake
set(WOLFSSL_ROOT "C:/some-path/wolfssl")
set(WOLFSSL_ROOT "c:/workspace/wolfssl-[username]")
set(WOLFSSL_ROOT "/mnt/c/somepath/wolfssl")
```

See the specific examples for additional details.

## Setup for Linux (wolfSSL local copy)

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/`
Expand Down
150 changes: 120 additions & 30 deletions IDE/Espressif/ESP-IDF/user_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
#define WOLFSSL_AES_DIRECT
#endif

/* when you want to use aes counter mode */
/* when you want to use AES counter mode */
/* #define WOLFSSL_AES_DIRECT */
/* #define WOLFSSL_AES_COUNTER */

Expand All @@ -102,10 +102,17 @@
/* Define USE_FAST_MATH and SMALL_STACK */
#define ESP32_USE_RSA_PRIMITIVE
/* threshold for performance adjustment for HW primitive use */

/* NOTE HW unreliable for small values on older original ESP32!*/
/* threshold for performance adjustment for HW primitive use */
/* X bits of G^X mod P greater than */
#define EPS_RSA_EXPT_XBTIS 36
#undef ESP_RSA_EXPT_XBITS
#define ESP_RSA_EXPT_XBITS 32

/* X and Y of X * Y mod P greater than */
#define ESP_RSA_MULM_BITS 2000
#undef ESP_RSA_MULM_BITS
#define ESP_RSA_MULM_BITS 16

#endif

/* debug options */
Expand All @@ -123,46 +130,129 @@
/* adjust wait-timeout count if you see timeout in RSA HW acceleration */
#define ESP_RSA_TIMEOUT_CNT 0x249F00

/* Default is HW enabled unless turned off.
** Uncomment these lines to force SW instead of HW acceleration */

#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 */
/* wolfSSL HW Acceleration supported on ESP32. Uncomment to disable: */
/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */

/* These are defined automatically in esp32-crypt.h, here for clarity: */
#define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224 /* no SHA224 HW on ESP32 */
/* end CONFIG_IDF_TARGET_ESP32 */
#undef ESP_RSA_MULM_BITS
#define ESP_RSA_MULM_BITS 16 /* TODO add compile-time warning */
/***** END CONFIG_IDF_TARGET_ESP32 *****/

#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
/* wolfSSL HW Acceleration supported on ESP32-S2. Uncomment to disable: */
/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
/* Note: There's no AES192 HW on the ESP32-S2; falls back to SW */
/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
/***** END CONFIG_IDF_TARGET_ESP32S2 *****/

#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 */
/* wolfSSL HW Acceleration supported on ESP32-S3. Uncomment to disable: */
/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
/* Note: There's no AES192 HW on the ESP32-S3; falls back to SW */
/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
/***** END CONFIG_IDF_TARGET_ESP32S3 *****/

#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
/* wolfSSL HW Acceleration supported on ESP32-C2. Uncomment to disable: */

/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH */ /* to disable all SHA HW */

/* These are defined automatically in esp32-crypt.h, here for clarity: */
#define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384 /* no SHA384 HW on C6 */
#define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512 /* no SHA512 HW on C6 */

/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
/***** END CONFIG_IDF_TARGET_ESP32C3 *****/

#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
/* wolfSSL HW Acceleration supported on ESP32-C6. Uncomment to disable: */

/* #define NO_ESP32_CRYPT */
/* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
/* These are defined automatically in esp32-crypt.h, here for clarity: */
#define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384 /* no SHA384 HW on C6 */
#define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512 /* no SHA512 HW on C6 */

/* #define NO_WOLFSSL_ESP32_CRYPT_AES */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
/***** END CONFIG_IDF_TARGET_ESP32C6 *****/

#elif defined(CONFIG_IDF_TARGET_ESP32H2)
/* ESP32-H2 disabled by default, not implemented */
/* wolfSSL Hardware Acceleration not yet implemented */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
/***** END CONFIG_IDF_TARGET_ESP32H2 *****/

#else
/* anything else unknown will have HW disabled by default */
/* Anything else encountered, disable HW accleration */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
#endif /* CONFIG_IDF_TARGET Check */

/* optional SM4 Ciphers. See https://github.com/wolfSSL/wolfsm
#define WOLFSSL_SM2
#define WOLFSSL_SM3
#define WOLFSSL_SM4
*/

#if defined(WOLFSSL_SM2) || defined(WOLFSSL_SM3) || defined(WOLFSSL_SM4)
#include <wolfssl/certs_test_sm.h>
#define CTX_CA_CERT root_sm2
#define CTX_CA_CERT_SIZE sizeof_root_sm2
#define CTX_CA_CERT_TYPE WOLFSSL_FILETYPE_PEM
#define CTX_SERVER_CERT server_sm2
#define CTX_SERVER_CERT_SIZE sizeof_server_sm2
#define CTX_SERVER_CERT_TYPE WOLFSSL_FILETYPE_PEM
#define CTX_SERVER_KEY server_sm2_priv
#define CTX_SERVER_KEY_SIZE sizeof_server_sm2_priv
#define CTX_SERVER_KEY_TYPE WOLFSSL_FILETYPE_PEM

#undef WOLFSSL_BASE16
#define WOLFSSL_BASE16
#else
#define USE_CERT_BUFFERS_2048
#define USE_CERT_BUFFERS_256
#define CTX_CA_CERT ca_cert_der_2048
#define CTX_CA_CERT_SIZE sizeof_ca_cert_der_2048
#define CTX_CA_CERT_TYPE WOLFSSL_FILETYPE_ASN1
#define CTX_SERVER_CERT server_cert_der_2048
#define CTX_SERVER_CERT_SIZE sizeof_server_cert_der_2048
#define CTX_SERVER_CERT_TYPE WOLFSSL_FILETYPE_ASN1
#define CTX_SERVER_KEY server_key_der_2048
#define CTX_SERVER_KEY_SIZE sizeof_server_key_der_2048
#define CTX_SERVER_KEY_TYPE WOLFSSL_FILETYPE_ASN1
#endif
49 changes: 38 additions & 11 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#undef WOLFSSL_AES_DIRECT
#define WOLFSSL_AES_DIRECT

/* If we choose to never have a fallback to SW: */
/* Encrypt: If we choose to never have a fallback to SW: */
#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)
Expand All @@ -501,7 +501,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
}
#endif

/* If we choose to never have a fallback to SW */
/* Decrypt: 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(
Aes* aes, const byte* inBlock, byte* outBlock)
Expand Down Expand Up @@ -882,10 +882,9 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#ifdef NEED_AES_TABLES

#ifndef WC_AES_BITSLICED
#if (!defined(WOLFSSL_SILABS_SE_ACCEL) && \
!defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) \
) || \
(defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && defined(NEED_AES_HW_FALLBACK))
#if !defined(WOLFSSL_SILABS_SE_ACCEL) || \
defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
defined(NEED_AES_HW_FALLBACK)
static const FLASH_QUALIFIER word32 rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
Expand Down Expand Up @@ -1535,8 +1534,8 @@ static WARN_UNUSED_RESULT word32 inv_col_mul(
byte t0 = t9 ^ tb ^ td;
return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
}
#endif
#endif
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
#endif /* WOLFSSL_AES_SMALL_TABLES */
#endif

#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
Expand Down Expand Up @@ -3894,8 +3893,29 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
XMEMCPY(rk, key, keySz);
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
(!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES))
ByteReverseWords(rk, rk, keySz);
#endif
/* Always reverse words when using only SW */
{
ByteReverseWords(rk, rk, keySz);
}
#else
/* Sometimes reverse words when using supported HW */
#if defined(WOLFSSL_ESPIDF)
/* Some platforms may need SW fallback (e.g. AES192) */
#if defined(NEED_AES_HW_FALLBACK)
{
ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
if (wc_esp32AesSupportedKeyLen(aes)) {
/* don't reverse for HW supported key lengths */
}
else {
ByteReverseWords(rk, rk, keySz);
}
}
#else
/* If we don't need SW fallback, don't need to reverse words. */
#endif /* NEED_AES_HW_FALLBACK */
#endif /* WOLFSSL_ESPIDF */
#endif /* LITTLE_ENDIAN_ORDER, etc */

switch (keySz) {
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
Expand Down Expand Up @@ -4345,13 +4365,20 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
}
else {
#if defined(WOLFSSL_HW_METRICS)
/* It is interesting to know how many times we could not complete
* AES in hardware due to unsupported lengths. */
wc_esp32AesUnupportedLengthCountAdd();
#endif
#ifdef DEBUG_WOLFSSL
ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
keylen);
#endif
}
#endif
#endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */

return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);

} /* wc_AesSetKey() */

#if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
Expand Down
Loading