Skip to content

Commit

Permalink
Merge pull request #6990 from gojimmypi/PR-Espressif-C3-C6-S2-HW
Browse files Browse the repository at this point in the history
Espressif ESP32-C3 ESP32-C6 ESP32-S2 Hardware Acceleration
  • Loading branch information
JacobBarthelmeh authored Nov 22, 2023
2 parents 5b3f549 + 2da8811 commit 2e89e46
Show file tree
Hide file tree
Showing 18 changed files with 3,723 additions and 794 deletions.
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

0 comments on commit 2e89e46

Please sign in to comment.