Here are some notes on removing the mbedTLS and using the commercial-grade wolfSSL encryption libraries with the Espressif ESP32.
This blog is still a work-in progress.
Initial Review
Note that the wolfSSL libraries are all open source GPLv2 and free for makers! Contact wolfSSL for commercial license info.
The 4.x versions of the Espressif ESP-IDF toolchain allow configuration of application-level TLS provider selection between either mbedTLS or wolfSSL. More specifically: a selection between mbedTLS and the Espressif esp-wolfssl component.
In order to use esp-wolfssl, it should be installed in the local project “components” directory.
Be sure to add it to the project-level set(COMPONENTS
list in the CMakeFiles.txt file.
Note the esp-wolfssl uses a fixed point-in-time submodule of wolfssl and is not recommended for production environments. As of the date of this blog, that esp-wolfssl submodule is 2 months old. See the wolfSSL Releases for the latest wolfSSL release.
Select TLS Provider
Selection between the TLS providers is a simple matter of right-clicking on a VisualGDB project and typing “TLS” in the filter box and choosing “wolfSSL”:
Selection can also be made at the command prompt using idf.py menuconfig
. Select “Component Config”, then “ESP-TLS”, then “Choose SSL/TLS Library”:
Warning about mbedTLS Revert
NOTE: The esp-wolfssl must be properly installed int the local project components
directory and exactly, perfectly configured. If any problems are encountered the idf.py build
process will quietly revert back to mbedTLS.
It is not immediately obvious just what mechanism is used to revert to mbedTLS when the esp-wolfssl
is not properly configured. The key statement is
the kconfig.cmake execute_process()
which calls confgen.py. Debugging that script is beyond the scope of this blog.
The key point is that a Kconfig
file must be present in the root of the respective component directory in order to not have the ESP-IDF revert to mbedTLS
when the CMake files are reloaded.
The important file for wolfSSL is the user_settings.h
, which for the esp-wolfssl
would be found in the project directory: components/esp-wolfssl/include
.
For more information on user settings, see Chapter 2 of the wolfSSL Documentation.
Although it would be nice if the Espressif ESP-IDF included wolfSSL source code, or even just a directory for the component to be easily installed, per #9288, it is unlikely that will ever happen.
For now, the wolfSSL component will need to be installed in the local project component directory.
Moving beyond the stale esp-wolfssl
component should be one of the first orders of business.
Note that the mbedTLS component includes
an even older version of the Espressif fork of mbedTLS from Mbed-TLS/mbedtls.
As of the date of this blog, that Espressif submodule is 9 months old.
Migration Steps
There’s a Sample WiFi STA Example which is the out-of-the-box experience when first creating an Example App with VisualGDB.
Private Config
Rather than hard-code values such as SSID and password) in the main app and/or SDK config, it is probably best to keep all those values someplace else to ensure they don’t get accidentally pushed to GitHub.
Some developers choose to include the sdkconfig
file in the .gitignore
list. That may not always be the wisest choice, as other valuable settings in that file would then also be excluded from GitHub.
A better way is to reference a file completely outside the scope of GitHub. For instance, if all projects are located in a clone from a workspace
directory, that could be
a good location to store a my_private_config.h
file. Then from the root of any project, the secret file would be in the ‘../’ parent directory.
One possible way to use such a file is by including a main/my_config.h
file in the project, such as the one for the SSH to UART server.
That my_config.h
file also includes some comments for robustly including the my_private_config.h
regardless of environment path syntax (e.g. Windows, WSL, Linux, etc.) - note these
changes are applied to the example project CMakeFile.txt:
if(EXISTS "/c/workspace/my_private_config.h")
message(STATUS "found SYSPROGS_MY_PRIVATE_CONFIG")
add_definitions( -DSYSPROGS_MY_PRIVATE_CONFIG="/c/workspace/my_private_config.h" )
endif()
if(EXISTS "/workspace/my_private_config.h")
message(STATUS "found WINDOWS_MY_PRIVATE_CONFIG")
add_definitions( -DWINDOWS_MY_PRIVATE_CONFIG="/workspace/my_private_config.h" )
endif()
if(EXISTS "/mnt/c/workspace/my_private_config.h")
message(STATUS "found WSL_MY_PRIVATE_CONFIG")
add_definitions( -DWSL_MY_PRIVATE_CONFIG="/mnt/c/workspace/my_private_config.h" )
endif()
if(EXISTS "(~/my_private_config.h")
message(STATUS "found LINUX_MY_PRIVATE_CONFIG")
add_definitions( -DWSL_MY_PRIVATE_CONFIG="~/my_private_config.h" )
endif()
## ESF-IDF Revisions for wolfSSL
There are some minor changes needed to the ESP-IDF to properly support wolfSSL as a local component.
The ESP-IDF repo is massive, so be patient when cloning. To clone the ESP-IDF locally, don’t forget the submodules:
git clone https://github.com/gojimmypi/esp-idf.git
git submodule update --init --recursive
But in all likelihood, the ESP-IDF is probably already installed. If not, check out the installation instructions.
In the case of VisualGDB, the ESP-IDF toolchain was installed in C:\SysGCC\esp32\esp-idf\v4.4.2
in a “detached head” mode.
It would probably be best to create a branch of the ESP-IDF in case things go sideways. In VisualGDB, this is quite easy with the “Git - Managed Remotes…” selection from the toolbar:
Note that sometimes Visual Studio may not immediately “see” git changes made via command-line. Exit and restart.
As noted in a prior blog, it can be helpful to add an “upstream” remote. (See also Managing remote repositories)
Here are some git commands:
# change to the directory where your ESP-IDF toolchain was installed.
cd .
# View current remotes:
git remote -v
# View the current commit hash (helpful to return when in detached head mode)
git rev-parse HEAD
# change the remote to your fork of esp-idf
git remote set-url origin https://github.com/gojimmypi/esp-idf.git
# add an upstream remote
git remote add upstream https://github.com/espressif/esp-idf.git
# update any submodules needed
git submodule update --init --recursive
# keep the master branch in sync with upstream
git fetch upstream
git pull upstream master
# got back to the detached head branch from the git rev-parse HEAD command (see above)
# in this case: 1b16ef6cfc2479a08136782f9dc57effefa86f66
git branch 1b16ef6cfc2
Intializat the ESP-IDF environment
# change to the directory that contains your project:
#
cd /mnt/c/workspace/wolfssl-examples/ESP32/mbedTLS-to-wolfSSL-Migration
# if the above was installed via VisualGDB, this may need to be run from a command prompt
# to use the same idf.py toolchain from outside of VisualGDB:
#
# /mnt/c/SysGCC/esp32/esp-idf/v4.4.2/install.sh
#
# The export command below will prompt if the install is needed.
# this is the typical setup of a fresh command prompt to run the idf.py
# be sure to run export.sh from the desired version directory:
#
. /mnt/c/SysGCC/esp32/esp-idf/v4.4.2/export.sh
Install the wolfSSL component
Create a project ./components/wolfssl
directory and run either the wolfSSL setup.sh
or setup_win.bat.
Alternatively, there’s a new experimental git sparse install
Memory
The mbedTLS has some settings in esp-idf/components/mbedtls/port/esp_mem.c that chose where and how to allocate memory on the ESP32 (assumed to be Xtensa architecture only: TODO review for RISC-V)
hostapd/wpa_supplicant
is hosted at w1.fi/cgit/hostap/,
The version 2.10 is available in a zip download
The Espressif hostap/supplicant didn’t always have all code open source. ESP-IDF #3003 resolved that.
git clone https://w1.fi/cgit/hostap
wpa_supplicant
Take a few wolfSSL files from w1.fi/cgit/hostap/tree/src/crypto and put them
into esp-idf\[version]\components\wpa_supplicant\src\crypto
. (here),
Specifically:
https://w1.fi/cgit/hostap/tree/src/crypto/tls_wolfssl.c
https://w1.fi/cgit/hostap/tree/src/crypto/crypto_wolfssl.c
Put them into: https://github.com/espressif/esp-idf/tree/master/components/wpa_supplicant/src/crypto
Additional Resources
- Espressif [Heap Memory Allocation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/mem_alloc.html
- Espressif ESP32 Memory Analysis - Case Study
- esp32.com Where’s the rest of the internal memory?
- visualgdb toolchain documentation
- w1.fi hostapd/wpa_supplicant
- w1.fi wpa_supplicant / hostapd: Porting to different target boards and operating systems
- Espressif esp-wolfssl component
- Espressif Heap Debug
- Espressif Minimizing RAM Usage
- Espressif Minimizing Binary Size
- Espressif esp-idf wpa_supplicant CMakeLists.txt
- Espressif esp-idf wpa_supplicant crypto.h
- Espressif esp-idf components/esp-tls/esp_tls.c
- Espressif Request to provide source code of EspressIf’s hostap fork (IDFGH-592) #3003
- Espressif ESP32 Memory Analysis - Case Study
- GitHub dgarske/hostap
- stackoverflow CMake: Print out all accessible variables in a script
- wolfSSL hostap/wpa_supplicant
- wolfSSL SSL/TLS Tutorial
- wolfSSL wolfSSL_CTX_UseSNI #1900 Server Name Indicator (SNI)
- wolfSSL Azure Sphere - WolfSSL API
- wolfSSL Building wolfSSL
- wolfSSL wolfMQTT/examples/aws/awsiot.c
- gojimmypi ESP32 RISC-V wolfSSL Benchmark
- Kaleb’s wolfSoFT - wolf Suite of Frameworks and Tools
wolfSSL - How to find and load the right root CA Post Quantum Crypto in wolfSSL