Skip to content

Commit

Permalink
Espressif ESP32-C3 ESP32-C6 ESP32-S2 Hardware Acceleration
Browse files Browse the repository at this point in the history
  • Loading branch information
gojimmypi committed Nov 21, 2023
1 parent 665469f commit 7e69030
Show file tree
Hide file tree
Showing 17 changed files with 3,617 additions and 760 deletions.
36 changes: 35 additions & 1 deletion IDE/Espressif/ESP-IDF/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,48 @@ Including the following examples:
* Simple [TLS client](./examples/wolfssl_client/)/[server](./examples/wolfssl_server/)
* Cryptographic [test](./examples/wolfssl_test/)
* Cryptographic [benchmark](./examples/wolfssl_benchmark/)
* Bare-bones [template](./examples/template/)

The *user_settings.h* file enables some of the hardened settings.

## Requirements

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
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
13 changes: 9 additions & 4 deletions wolfcrypt/src/port/Espressif/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ For detail about ESP32 HW Acceleration, you can find in [Technical Reference Man

### Building

To enable hw acceleration :
```
git clone --recurse-submodules -j8 https://github.com/espressif/esp-idf master
```

* Uncomment out `#define WOLFSSL_ESPIDF` in `/path/to/wolfssl/wolfssl/wolfcrypt/settings.h`
* Uncomment out `#define WOLFSSL_ESP32` in `/path/to/wolfssl/wolfssl/wolfcrypt/settings.h`
Hardware acceleration is enabled by default.

To disable portions of the hardware acceleration you can optionally define:

Expand All @@ -28,7 +29,11 @@ To disable portions of the hardware acceleration you can optionally define:

### 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:

To view disassembly, add `__attribute__((section(".iram1")))` decorator. Foe example:

Expand Down
Loading

0 comments on commit 7e69030

Please sign in to comment.