diff --git a/ide/Espressif/ESP-IDF/examples/README.md b/ide/Espressif/ESP-IDF/examples/README.md
new file mode 100644
index 000000000..405693138
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/README.md
@@ -0,0 +1,6 @@
+# wolfSSL Espressif Managed Component examples
+
+
+wolfssh [server](./wolfssh_server/README.md)
+
+wolfssl [template](./wolfssh_template/README.md)
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_server/CMakeLists.txt
new file mode 100644
index 000000000..6aeb4f518
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/CMakeLists.txt
@@ -0,0 +1,68 @@
+# The following lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+# enable wolfssl user_settings.h project-wide
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
+
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSH_TERM")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG_WOLFSSH")
+
+# set(WOLFSSL_ROOT "~/workspace/wolfssl-other-source")
+
+# Optional WOLFSSL_CMAKE_SYSTEM_NAME detection to find
+# USE_MY_PRIVATE_CONFIG path for my_private_config.h
+#
+if(WIN32)
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_WINDOWS")
+ message("Detected Windows")
+endif()
+if(CMAKE_HOST_UNIX)
+ message("Detected UNIX")
+endif()
+if(APPLE)
+ message("Detected APPLE")
+endif()
+if(CMAKE_HOST_UNIX AND (NOT APPLE) AND EXISTS "/proc/sys/fs/binfmt_misc/WSLInterop")
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_WSL")
+ message("Detected WSL")
+endif()
+if(CMAKE_HOST_UNIX AND (NOT APPLE) AND (NOT WIN32))
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_LINUX")
+ message("Detected Linux")
+endif()
+if(APPLE)
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_APPLE")
+ message("Detected Apple")
+endif()
+# End optional WOLFSSL_CMAKE_SYSTEM_NAME
+
+# Check that there are not conflicting wolfSSL components
+# The ESP Registry Component will be in ./managed_components/wolfssl__wolfssl
+# The local component wolfSSL directory will be in ./components/wolfssl
+if( EXISTS "${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolfssl" AND EXISTS "${CMAKE_HOME_DIRECTORY}/components/wolfssl" )
+ # These exclude statements don't seem to be honored by the $ENV{IDF_PATH}/tools/cmake/project.cmake'
+ # add_subdirectory("${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolfssl" EXCLUDE_FROM_ALL)
+ # add_subdirectory("${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolfssl/include" EXCLUDE_FROM_ALL)
+ # So we'll error out and let the user decide how to proceed:
+ message(WARNING "\nFound wolfSSL components in\n"
+ "./managed_components/wolfssl__wolfssl\n"
+ "and\n"
+ "./components/wolfssl\n"
+ "in project directory: \n"
+ "${CMAKE_HOME_DIRECTORY}")
+ message(FATAL_ERROR "\nPlease use either the ESP Registry Managed Component or the wolfSSL component directory but not both.\n"
+ "If removing the ./managed_components/wolfssl__wolfssl directory, remember to also remove "
+ "or rename the idf_component.yml file typically found in ./main/")
+else()
+ message(STATUS "No conflicting wolfSSL components found.")
+endif()
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+
+project(wolfssh_server)
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/README.md b/ide/Espressif/ESP-IDF/examples/wolfssh_server/README.md
new file mode 100644
index 000000000..8ed8996cc
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/README.md
@@ -0,0 +1,75 @@
+# wolfSSL Server Project
+
+This is an example wolfSSH Server based on the minimally viable wolfSSL [template](../wolfssh_template/README.md)
+
+See the [command line example client](https://github.com/wolfSSL/wolfssh/tree/master/examples/client)
+and the instructions in [wolfssh README.md](https://github.com/wolfSSL/wolfssh#readme)
+
+To connect:
+
+```bash
+TODO
+
+ssh -p 22222 jack@192.168.1.32
+```
+
+### Prerequisites
+
+It is assumed the [ESP-IDF environment](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/) has been installed.
+
+### Files Included
+
+- [main.c](./main/main.c) with a simple call to an Espressif library (`ESP_LOGI`) and a call to a wolfSSL library (`esp_ShowExtendedSystemInfo`) .
+
+- See [components/wolfssl/include](./components/wolfssl/include/user_settings.h) directory to edit the wolfSSL `user_settings.h`.
+
+- Edit [main/CMakeLists.txt](./main/CMakeLists.txt) to add/remove source files.
+
+- The [components/wolfssl/CMakeLists.txt](./components/wolfssl/CMakeLists.txt) typically does not need to be changed.
+
+- Optional [VisualGDB Project](./VisualGDB/wolfssl_template_IDF_v5.1_ESP32.vgdbproj) for Visual Studio using ESP32 and ESP-IDF v5.1.
+
+- Edit the project [CMakeLists.txt](./CMakeLists.txt) to optionally point this project's wolfSSL component source code at a different directory:
+
+```
+set(WOLFSSL_ROOT "~/workspace/wolfssl-other-source")
+```
+
+
+## Getting Started:
+
+Here's an example using the command-line [idf.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-py.html).
+
+Edit your `WRK_IDF_PATH`to point to your ESP-IDF install directory.
+
+```
+WRK_IDF_PATH=/mnt/c/SysGCC/esp32/esp-idf/v5.1
+
+echo "Run export.sh from ${WRK_IDF_PATH}"
+. ${WRK_IDF_PATH}/export.sh
+
+# build the example:
+idf.py build
+
+# flash the code onto the serial device at /dev/ttyS19
+idf.py flash -p /dev/ttyS19 -b 115200
+
+# build, flash, and view UART output with one command:
+idf.py flash -p /dev/ttyS19 -b 115200 monitor
+```
+
+Press `Ctrl+]` to exit `idf.py monitor`. See [additional monitor keyboard commands](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-monitor.html).
+
+## Other Examples:
+
+For examples, see:
+
+- [TLS Client](../wolfssl_client/README.md)
+- [TLS Server](../wolfssl_server/README.md)
+- [Benchmark](../wolfssl_benchmark/README.md)
+- [Test](../wolfssl_test/README.md)
+- [wolfssl-examples](https://github.com/wolfSSL/wolfssl-examples/tree/master/ESP32)
+- [wolfssh-examples](https://github.com/wolfSSL/wolfssh-examples/tree/main/Espressif)
+
+
+
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/VisualGDB/wolfssh_server_IDF_v5.1_ESP32.sln b/ide/Espressif/ESP-IDF/examples/wolfssh_server/VisualGDB/wolfssh_server_IDF_v5.1_ESP32.sln
new file mode 100644
index 000000000..fabc45dac
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/VisualGDB/wolfssh_server_IDF_v5.1_ESP32.sln
@@ -0,0 +1,36 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34031.279
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{803FD0C6-D64E-4E16-9DC3-1DAEC859A3D2}") = "wolfssh_server_IDF_v5.1_ESP32", "wolfssh_server_IDF_v5.1_ESP32.vgdbproj", "{EADCC9AB-72B3-4B51-A838-593E5D80DDF7}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{510C1DEE-DFFB-4C38-864E-DCE7A172ABB7}"
+ ProjectSection(SolutionItems) = preProject
+ ..\README.md = ..\README.md
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|VisualGDB = Debug|VisualGDB
+ Release|VisualGDB = Release|VisualGDB
+ Tests (Debug)|VisualGDB = Tests (Debug)|VisualGDB
+ Tests (Release)|VisualGDB = Tests (Release)|VisualGDB
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Debug|VisualGDB.ActiveCfg = Debug|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Debug|VisualGDB.Build.0 = Debug|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Release|VisualGDB.ActiveCfg = Release|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Release|VisualGDB.Build.0 = Release|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Debug)|VisualGDB.ActiveCfg = Tests (Debug)|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Debug)|VisualGDB.Build.0 = Tests (Debug)|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Release)|VisualGDB.ActiveCfg = Tests (Release)|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Release)|VisualGDB.Build.0 = Tests (Release)|VisualGDB
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C3DD3774-E396-475C-B78D-604D7CD9B732}
+ EndGlobalSection
+EndGlobal
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/VisualGDB/wolfssh_server_IDF_v5.1_ESP32.vgdbproj b/ide/Espressif/ESP-IDF/examples/wolfssh_server/VisualGDB/wolfssh_server_IDF_v5.1_ESP32.vgdbproj
new file mode 100644
index 000000000..9edbb41e2
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/VisualGDB/wolfssh_server_IDF_v5.1_ESP32.vgdbproj
@@ -0,0 +1,269 @@
+
+
+
+
+
+ Unknown
+
+ true
+
+ 7bbd1486-d457-4e49-92ba-0cfc9d80849e
+ true
+ true
+ SourceDirs
+
+
+
+
+
+ com.visualgdb.xtensa-esp32-elf
+
+ 12.2.0
+ 12.1
+ 1
+
+
+ ..
+ DEBUG
+ build/$(PlatformName)/$(ConfigurationName)
+
+ false
+ $(ToolchainNinja)
+ $(BuildDir)
+
+
+
+ false
+ $(SYSPROGS_CMAKE_PATH)
+
+
+ true
+ false
+ false
+ Ninja
+ false
+ RemoveBuildDirectory
+ false
+
+
+ true
+ true
+ true
+ false
+ true
+ false
+ true
+ HideOuterProjectTargets
+ true
+ false
+ true
+
+
+ true
+ eadcc9ab-72b3-4b51-a838-593e5d80ddf7
+
+ Upper
+ HeaderDirectoryAndSubdirectories
+ true
+
+
+ release/v5.1
+ esp-idf/v5.1
+ ESPIDF
+
+ COM9
+ false
+ false
+ ESP32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+ COM9
+
+ 115200
+ 8
+ None
+ One
+ None
+
+
+ 0
+ false
+ false
+ false
+ ASCII
+
+
+ 255
+ 0
+ 0
+ 0
+
+
+ 255
+ 169
+ 169
+ 169
+
+
+ 255
+ 211
+ 211
+ 211
+
+
+ 255
+ 144
+ 238
+ 144
+
+
+ 255
+ 169
+ 169
+ 169
+
+
+
+ 16
+ true
+ true
+ true
+ true
+ 0
+
+ LF
+ false
+ false
+ false
+
+
+
+ true
+
+
+
+
+ Unknown
+
+ true
+ true
+ true
+
+
+
+ false
+
+
+
+
+ Debug
+
+
+
+ Release
+
+
+
+
+
+
+
+
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+ false
+ false
+ false
+ false
+ false
+ false
+ true
+ false
+ None
+ false
+ false
+ app_main
+ true
+ false
+ false
+ true
+ 0
+ false
+ 0
+ true
+ false
+
+
+ openocd
+
+ -f interface/ftdi/tigard.cfg -c "adapter_khz 15000" -f target/esp32.cfg
+
+
+
+ false
+
+ 131072
+ Enabled
+
+ set remotetimeout 60
+ target remote :$$SYS:GDB_PORT$$
+ mon gdb_breakpoint_override hard
+ mon reset halt
+ load
+
+ false
+ 0
+ 0
+ false
+
+ 5000
+ 1
+ true
+
+ size2MB
+ freq40M
+ DIO
+
+ true
+
+
+ true
+ Disabled
+ 0
+ false
+ false
+ true
+ false
+ false
+
+ _estack
+ 0
+ false
+
+ true
+
+
\ No newline at end of file
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssh/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssh/CMakeLists.txt
new file mode 100644
index 000000000..0bdf01e5d
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssh/CMakeLists.txt
@@ -0,0 +1,456 @@
+#
+# Copyright (C) 2006-2023 WOLFSSL Inc.
+#
+# This file is part of WOLFSSH.
+#
+# WOLFSSH is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# WOLFSSH is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+#
+# cmake for WOLFSSH Espressif projects
+#
+# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html
+#
+
+cmake_minimum_required(VERSION 3.16)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSH_USER_SETTINGS")
+set(CMAKE_CURRENT_SOURCE_DIR ".")
+set(COMPONENT_REQUIRES lwip wolfssl)
+
+# COMPONENT_NAME = wolfssh
+# The component name is the directory name. "No feature to change this".
+# See https://github.com/espressif/esp-idf/issues/8978#issuecomment-1129892685
+
+# set the root of WOLFSSH in top-level project CMakelists.txt:
+# set(WOLFSSH_ROOT "C:/some path/with/spaces")
+# set(WOLFSSH_ROOT "c:/workspace/WOLFSSH-[username]")
+# set(WOLFSSH_ROOT "/mnt/c/some path/with/spaces")
+# or use this logic to assign value from Environment Variable WOLFSSH_ROOT,
+# or assume this is an example 7 subdirectories below:
+
+# We are typically in [root]/IDE/Espressif/ESP-IDF/examples/WOLFSSH_test/components/WOLFSSH
+# The root of WOLFSSH is 7 directories up from here:
+
+if(CMAKE_BUILD_EARLY_EXPANSION)
+ message(STATUS "WOLFSSH component CMAKE_BUILD_EARLY_EXPANSION:")
+ idf_component_register(
+ REQUIRES "${COMPONENT_REQUIRES}"
+ PRIV_REQUIRES esp_timer driver wolfssl # this will typically only be needed for WOLFSSH benchmark
+ )
+
+else()
+ # not CMAKE_BUILD_EARLY_EXPANSION
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssh component config:")
+ message(STATUS "************************************************************************************************")
+
+ # Check to see if we're already in WOLFSSH, and only if WOLFSSH_ROOT not specified
+ if ("${WOLFSSH_ROOT}" STREQUAL "")
+ # WOLFSSH examples are 7 directories deep from WOLFSSH repo root
+ # 1 2 3 4 5 6 7
+ set(THIS_RELATIVE_PATH "../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching in path = ${THIS_SEARCH_PATH}")
+
+ if (EXISTS "${THIS_SEARCH_PATH}/wolfcrypt/src")
+ # we're already in WOLFSSH examples!
+ get_filename_component(WOLFSSH_ROOT "${THIS_SEARCH_PATH}" ABSOLUTE)
+ message(STATUS "Using WOLFSSH example with root ${WOLFSSH_ROOT}")
+ else()
+ # We're in some other repo such as wolfssh, so we'll search for an
+ # adjacent-level directory for WOLFSSH. (8 directories up, then down one)
+ #
+ # For example WOLFSSH examples:
+ # C:\workspace\WOLFSSH-gojimmypi\IDE\Espressif\ESP-IDF\examples\WOLFSSH_benchmark\components\WOLFSSH
+ #
+ # For example wolfSSH examples:
+ # C:\workspace\wolfssh-gojimmypi\ide\Espressif\ESP-IDF\examples\wolfssh_benchmark\components\WOLFSSH
+ #
+ # 1 2 3 4 5 6 7 8
+ set(THIS_RELATIVE_PATH "../../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching next in path = ${THIS_SEARCH_PATH}")
+ endif()
+ endif()
+
+ # search other possible locations
+ if ("${WOLFSSH_ROOT}" STREQUAL "")
+ # there's not a hard-coded WOLFSSH_ROOT value above, so let's see if we can find it.
+ if( "$ENV{WOLFSSH_ROOT}" STREQUAL "" )
+ message(STATUS "Environment Variable WOLFSSH_ROOT not set. Will search common locations.")
+
+ message(STATUS "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
+ get_filename_component(THIS_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
+ message(STATUS "THIS_DIR = ${THIS_DIR}")
+
+ # find the user name to search for possible "WOLFSSH-username"
+ message(STATUS "USERNAME = $ENV{USERNAME}")
+ if( "$ENV{USER}" STREQUAL "" ) # the bash user
+ if( "$ENV{USERNAME}" STREQUAL "" ) # the Windows user
+ message(STATUS "could not find USER or USERNAME")
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USERNAME}")
+ endif()
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USER}")
+ endif()
+ message(STATUS "THIS_USER = ${THIS_USER}")
+
+ # This same makefile is used for both the WOLFSSH component, and other
+ # components that may depend on WOLFSSH, such as wolfssh. Therefore
+ # we need to determine if this makefile is in the WOLFSSH repo, or
+ # some other repo.
+
+ if( "{THIS_USER}" STREQUAL "" )
+ # This is highly unusual to not find a user name.
+ # In this case, we'll just search for a "WOLFSSH" directory:
+ message(STATUS "No username found!")
+ get_filename_component(WOLFSSH_ROOT "${THIS_RELATIVE_PATH}/WOLFSSH" ABSOLUTE)
+ else()
+ # We found an environment USER name!
+ # The first place to look for WOLFSSH will be in a user-clone called "WOLFSSH-[username]"
+ message(STATUS "Using [THIS_USER = ${THIS_USER}] to see if there's a [relative path]/WOLFSSH-${THIS_USER} directory.")
+ get_filename_component(WOLFSSH_ROOT "${THIS_RELATIVE_PATH}/WOLFSSH-${THIS_USER}" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ message(STATUS "Found WOLFSSH in user-suffix ${WOLFSSH_ROOT}")
+ else()
+ # If there's not a user-clone called "WOLFSSH-[username]",
+ # perhaps there's simply a git clone called "WOLFSSH"?
+ message(STATUS "Did not find WOLFSSH-${THIS_USER}; continuing search...")
+ get_filename_component(WOLFSSH_ROOT "${THIS_RELATIVE_PATH}/WOLFSSH" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ message(STATUS "Found WOLFSSH in standard ${WOLFSSH_ROOT}")
+ else()
+ # Things are looking pretty bleak. We'll likely not be able to compile.
+ message(STATUS "Did not find WOLFSSH in ${WOLFSSH_ROOT}")
+ endif()
+ endif()
+ endif()
+
+ else()
+ # there's an environment variable, so use it.
+ set(WOLFSSH_ROOT "$ENV{WOLFSSH_ROOT}")
+
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ get_filename_component(WOLFSSH_ROOT "$ENV{WOLFSSH_ROOT}" ABSOLUTE)
+ message(STATUS "Found WOLFSSH_ROOT via Environment Variable:")
+ else()
+ message(FATAL_ERROR "WOLFSSH_ROOT Environment Variable defined, but path not found:")
+ message(STATUS "$ENV{WOLFSSH_ROOT}")
+ endif()
+ endif()
+ # end of search for WOLFSSH component root
+ else()
+ # There's already a value assigned; we won't search for anything else.
+ message(STATUS "Found user-specified WOLFSSH_ROOT value.")
+ endif() # WOLFSSH_ROOT user defined
+
+ # After all the logic above, does our WOLFSSH_ROOT actually exist?
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ message(STATUS "WOLFSSH_ROOT = ${WOLFSSH_ROOT}")
+ else()
+ # Abort. We need WOLFSSH _somewhere_.
+ message(FATAL_ERROR "Could not find WOLFSSH in ${WOLFSSH_ROOT}. Try setting environment variable or git clone.")
+ endif()
+
+
+ set(INCLUDE_PATH ${WOLFSSH_ROOT})
+
+ set(COMPONENT_SRCDIRS
+ "\"${WOLFSSH_ROOT}/src/\""
+ ) # COMPONENT_SRCDIRS
+ message(STATUS "This COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+
+ set(WOLFSSH_PROJECT_DIR "${CMAKE_HOME_DIRECTORY}/components/wolfssh")
+
+ # Espressif may take several passes through this makefile. Check to see if we found IDF
+ string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "" WOLFSSH_FOUND_IDF)
+
+ message(STATUS "IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
+ message(STATUS "EXCLUDE_ASM = ${EXCLUDE_ASM}")
+
+ #
+ # Check to see if there's both a local copy and EDP-IDF copy of the WOLFSSH and/or wolfssh components.
+ #
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/WOLFSSH/" )
+ #
+ # WOLFSSH found in both ESP-IDF and local project - needs to be resolved by user
+ #
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+ message(STATUS "Error: Found components/WOLFSSH in both local project and IDF_PATH")
+ message(STATUS "")
+ message(STATUS "To proceed: ")
+ message(STATUS "")
+ message(STATUS "Remove either the local project component: ${WOLFSSH_PROJECT_DIR} ")
+ message(STATUS "or the Espressif shared component installed at: $ENV{IDF_PATH}/components/WOLFSSH/ ")
+ message(STATUS "")
+ message(FATAL_ERROR "Please use WOLFSSH in either local project or Espressif components, but not both.")
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+
+ # Optional: if you change the above FATAL_ERROR to STATUS you can warn at runtime with this macro definition:
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSH_MULTI_INSTALL_WARNING")
+
+ else()
+ if( EXISTS "$ENV{IDF_PATH}/components/WOLFSSH/" )
+ #
+ # WOLFSSH found in ESP-IDF components and is assumed to be already configured in user_settings.h via setup.
+ #
+ message(STATUS "")
+ message(STATUS "Using components/WOLFSSH in IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "")
+ else()
+ #
+ # WOLFSSH is not an ESP-IDF component.
+ # We need to now determine if it is local and if so if it is part of the WOLFSSH repo,
+ # or if WOLFSSH is simply installed as a local component.
+ #
+
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}" )
+ #
+ # WOLFSSH found in local project.
+ #
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}/wolfcrypt/" )
+ message(STATUS "")
+ message(STATUS "Using installed project ./components/WOLFSSH in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+ #
+ # Note we already checked above and confirmed there's not another WOLFSSH installed in the ESP-IDF components.
+ #
+ # We won't do anything else here, as it will be assumed the original install completed successfully.
+ #
+ else() # full WOLFSSH not installed in local project
+ #
+ # This is the developer repo mode. WOLFSSH will be assumed to be not installed to ESP-IDF nor local project
+ # In this configuration, we are likely running a WOLFSSH example found directly in the repo.
+ #
+ message(STATUS "")
+ message(STATUS "Using developer repo ./components/WOLFSSH in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+
+ message(STATUS "************************************************************************************************")
+ # When in developer mode, we are typically running WOLFSSH examples such as benchmark or test directories.
+ # However, the as-cloned or distributed WOLFSSH does not have the ./include/ directory, so we'll add it as needed.
+ #
+ # first check if there's a [root]/include/user_settings.h
+ if( EXISTS "${WOLFSSH_ROOT}/include/user_settings.h" )
+ message(FATAL_ERROR "Found stray WOLFSSH user_settings.h in "
+ "${WOLFSSH_ROOT}/include/user_settings.h "
+ " (please move it to ${WOLFSSH_PROJECT_DIR}/include/user_settings.h )")
+ else()
+ # we won't overwrite an existing user settings file, just note that we already have one:
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}/include/user_settings.h" )
+ message(STATUS "Using existing WOLFSSH user_settings.h in "
+ "${WOLFSSH_PROJECT_DIR}/include/user_settings.h")
+ else()
+ message(STATUS "Installing WOLFSSH user_settings.h to "
+ "${WOLFSSH_PROJECT_DIR}/include/user_settings.h")
+ # file(COPY "${WOLFSSH_ROOT}/IDE/Espressif/ESP-IDF/user_settings.h"
+ # DESTINATION "${CMAKE_HOME_DIRECTORY}/WOLFSSH/include/")
+ endif()
+ endif() # user_settings.h
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "")
+ endif()
+
+ else()
+ # we did not find a ./components/WOLFSSH/include/ directory from this pass of cmake.
+ if($WOLFSSH_FOUND_IDF)
+ message(STATUS "")
+ message(STATUS "WARNING: WOLFSSH not found.")
+ message(STATUS "")
+ else()
+ # probably needs to be re-parsed by Espressif
+ message(STATUS "WOLFSSH found IDF. Project Source:${PROJECT_SOURCE_DIR}")
+ endif() # else we have not found ESP-IDF yet
+ endif() # else not a local WOLFSSH component
+
+ endif() #else not an ESP-IDF component
+ endif() # else not local copy and EDP-IDF WOLFSSH
+
+
+ # RTOS_IDF_PATH is typically:
+ # "/Users/{username}/Desktop/esp-idf/components/freertos/include/freertos"
+ # depending on the environment, we may need to swap backslashes with forward slashes
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos")
+
+ string(REPLACE "\\" "/" WOLFSSH_ROOT ${WOLFSSH_ROOT})
+
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ # ESP-IDF prior version 4.4x has a different RTOS directory structure
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/include/freertos")
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found legacy RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ message(STATUS "Could not find RTOS path")
+ endif()
+ endif()
+
+
+ set(COMPONENT_ADD_INCLUDEDIRS
+ # "./include" # not used! See wolfSSL include/user_settings.h
+ "\"${WOLFSSH_ROOT}/\""
+ "\"${WOLFSSH_ROOT}/wolfssh/\""
+ "\"${RTOS_IDF_PATH}/\""
+ )
+
+
+ if(IS_DIRECTORY ${IDF_PATH}/components/cryptoauthlib)
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "../cryptoauthlib/lib")
+ endif()
+
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "\"${WOLFSSH_ROOT}/wolfssh/\"")
+
+
+
+ set(COMPONENT_SRCEXCLUDE
+ # wolfSSH
+ # TODO: we likely need to check #if !defined(WOLFSSH_MISC_INCLUDED) && !defined(NO_INLINE) && !defined(WOLFSSH_IGNORE_FILE_WARN)
+ # here in cmake if we actually want to always exclude wolfssh misc.c file. (see source; ok for demo)
+ "\"${WOLFSSH_ROOT}/src/misc.c\"" # misc.c does not need to be compiled when using inline (NO_INLINE not defined))
+ )
+
+ spaces2list(COMPONENT_REQUIRES)
+
+ separate_arguments(COMPONENT_SRCDIRS NATIVE_COMMAND "${COMPONENT_SRCDIRS}")
+ separate_arguments(COMPONENT_SRCEXCLUDE NATIVE_COMMAND "${COMPONENT_SRCEXCLUDE}")
+ separate_arguments(COMPONENT_ADD_INCLUDEDIRS NATIVE_COMMAND "${COMPONENT_ADD_INCLUDEDIRS}")
+
+ #
+ # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#example-component-requirements
+ #
+ message(STATUS "COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+ message(STATUS "COMPONENT_ADD_INCLUDEDIRS = ${COMPONENT_ADD_INCLUDEDIRS}")
+ message(STATUS "COMPONENT_REQUIRES = ${COMPONENT_REQUIRES}")
+ message(STATUS "COMPONENT_SRCEXCLUDE = ${COMPONENT_SRCEXCLUDE}")
+
+ #
+ # see https://docs.espressif.com/projects/esp-idf/en/stable/esp32/migration-guides/release-5.x/build-system.html?highlight=space%20path
+ #
+ set(EXTRA_COMPONENT_DIRS "${COMPONENT_SRCDIRS}")
+ idf_component_register(
+ SRC_DIRS "${COMPONENT_SRCDIRS}"
+ INCLUDE_DIRS "${COMPONENT_ADD_INCLUDEDIRS}"
+ REQUIRES "${COMPONENT_REQUIRES}"
+ EXCLUDE_SRCS "${COMPONENT_SRCEXCLUDE}"
+ PRIV_REQUIRES esp_timer driver wolfssl # this will typically only be needed for WOLFSSH benchmark
+ )
+ # some optional diagnostics
+ if (1)
+ get_cmake_property(_variableNames VARIABLES)
+ list (SORT _variableNames)
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES BEGIN")
+ message(STATUS "")
+ foreach (_variableName ${_variableNames})
+ message(STATUS "${_variableName}=${${_variableName}}")
+ endforeach()
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES END")
+ message(STATUS "")
+ endif()
+
+ # target_sources(WOLFSSH PRIVATE "\"${WOLFSSH_ROOT}/WOLFSSH/\"" "\"${WOLFSSH_ROOT}/WOLFSSH/wolfcrypt\"")
+endif() # CMAKE_BUILD_EARLY_EXPANSION
+
+
+
+# check to see if there's both a local copy and EDP-IDF copy of the WOLFSSH components
+if( EXISTS "${WOLFSSH_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/WOLFSSH/" )
+ message(STATUS "")
+ message(STATUS "")
+ message(STATUS "********************************************************************")
+ message(STATUS "WARNING: Found components/WOLFSSH in both local project and IDF_PATH")
+ message(STATUS "********************************************************************")
+ message(STATUS "")
+endif()
+# end multiple component check
+
+
+#
+# LIBWOLFSSH_SAVE_INFO(VAR_OUPUT THIS_VAR VAR_RESULT)
+#
+# Save the THIS_VAR as a string in a macro called VAR_OUPUT
+#
+# VAR_OUPUT: the name of the macro to define
+# THIS_VAR: the OUTPUT_VARIABLE result from a execute_process()
+# VAR_RESULT: the RESULT_VARIABLE from a execute_process(); "0" if successful.
+#
+function ( LIBWOLFSSH_SAVE_INFO VAR_OUPUT THIS_VAR VAR_RESULT )
+ # is the RESULT_VARIABLE output value 0? If so, IS_VALID_VALUE is true.
+ string(COMPARE EQUAL "${VAR_RESULT}" "0" IS_VALID_VALUE)
+
+ # if we had a successful operation, save the THIS_VAR in VAR_OUPUT
+ if(${IS_VALID_VALUE})
+ # strip newline chars in THIS_VAR parameter and save in VAR_VALUE
+ string(REPLACE "\n" "" VAR_VALUE ${THIS_VAR})
+
+ # we'll could percolate the value to the parent for possible later use
+ # set(${VAR_OUPUT} ${VAR_VALUE} PARENT_SCOPE)
+
+ # but we're only using it here in this function
+ set(${VAR_OUPUT} ${VAR_VALUE})
+
+ # we'll print what we found to the console
+ message(STATUS "Found ${VAR_OUPUT}=${VAR_VALUE}")
+
+ # the interesting part is defining the VAR_OUPUT name a value to use in the app
+ add_definitions(-D${VAR_OUPUT}=\"${VAR_VALUE}\")
+ else()
+ # if we get here, check the execute_process command and parameters.
+ message(STATUS "LIBWOLFSSH_SAVE_INFO encountered a non-zero VAR_RESULT")
+ set(${VAR_OUPUT} "Unknown")
+ endif()
+endfunction() # LIBWOLFSSH_SAVE_INFO
+
+# create some programmatic #define values that will be used by ShowExtendedSystemInfo().
+# see wolfcrypt\src\port\Espressif\esp32_utl.c
+if(NOT CMAKE_BUILD_EARLY_EXPANSION)
+ set (git_cmd "git")
+ message(STATUS "Adding macro definitions:")
+
+ # LIBWOLFSSH_VERSION_GIT_ORIGIN: git config --get remote.origin.url
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "config" "--get" "remote.origin.url" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_ORIGIN "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_BRANCH: git rev-parse --abbrev-ref HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "rev-parse" "--abbrev-ref" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_BRANCH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_HASH: git rev-parse HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "rev-parse" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_SHORT_HASH: git rev-parse --short HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "rev-parse" "--short" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_SHORT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_HASH_DATE git show --no-patch --no-notes --pretty=\'\%cd\'
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "show" "--no-patch" "--no-notes" "--pretty=\'\%cd\'" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_HASH_DATE "${TMP_OUT}" "${TMP_RES}")
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "WOLFSSH component config complete!")
+ message(STATUS "************************************************************************************************")
+endif()
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssl/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssl/CMakeLists.txt
new file mode 100644
index 000000000..7f482a4f8
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssl/CMakeLists.txt
@@ -0,0 +1,488 @@
+#
+# Copyright (C) 2006-2023 wolfSSL Inc.
+#
+# This file is part of wolfSSL.
+#
+# wolfSSL is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# wolfSSL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+#
+# cmake for wolfssl Espressif projects
+#
+# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html
+#
+
+cmake_minimum_required(VERSION 3.16)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
+set(CMAKE_CURRENT_SOURCE_DIR ".")
+set(COMPONENT_REQUIRES lwip) # we typically don't need lwip directly in wolfssl component
+
+# COMPONENT_NAME = wolfssl
+# The component name is the directory name. "No feature to change this".
+# See https://github.com/espressif/esp-idf/issues/8978#issuecomment-1129892685
+
+# set the root of wolfSSL in top-level project CMakelists.txt:
+# set(WOLFSSL_ROOT "C:/some path/with/spaces")
+# set(WOLFSSL_ROOT "c:/workspace/wolfssl-[username]")
+# set(WOLFSSL_ROOT "/mnt/c/some path/with/spaces")
+# or use this logic to assign value from Environment Variable WOLFSSL_ROOT,
+# or assume this is an example 7 subdirectories below:
+
+# We are typically in [root]/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl
+# The root of wolfSSL is 7 directories up from here:
+
+if(CMAKE_BUILD_EARLY_EXPANSION)
+ message(STATUS "wolfssl component CMAKE_BUILD_EARLY_EXPANSION:")
+ idf_component_register(
+ REQUIRES "${COMPONENT_REQUIRES}"
+ PRIV_REQUIRES esp_timer driver # this will typically only be needed for wolfSSL benchmark
+ )
+
+else()
+ # not CMAKE_BUILD_EARLY_EXPANSION
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssl component config:")
+ message(STATUS "************************************************************************************************")
+
+ # Check to see if we're already in wolfssl, and only if WOLFSSL_ROOT not specified
+ if ("${WOLFSSL_ROOT}" STREQUAL "")
+ # wolfssl examples are 7 directories deep from wolfssl repo root
+ # 1 2 3 4 5 6 7
+ set(THIS_RELATIVE_PATH "../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching in path = ${THIS_SEARCH_PATH}")
+
+ if (EXISTS "${THIS_SEARCH_PATH}/wolfcrypt/src")
+ # we're already in wolfssl examples!
+ get_filename_component(WOLFSSL_ROOT "${THIS_SEARCH_PATH}" ABSOLUTE)
+ message(STATUS "Using wolfSSL example with root ${WOLFSSL_ROOT}")
+ else()
+ # We're in some other repo such as wolfssh, so we'll search for an
+ # adjacent-level directory for wolfssl. (8 directories up, then down one)
+ #
+ # For example wolfSSL examples:
+ # C:\workspace\wolfssl-gojimmypi\IDE\Espressif\ESP-IDF\examples\wolfssl_benchmark\components\wolfssl
+ #
+ # For example wolfSSH examples:
+ # C:\workspace\wolfssh-gojimmypi\ide\Espressif\ESP-IDF\examples\wolfssh_benchmark\components\wolfssl
+ #
+ # 1 2 3 4 5 6 7 8
+ set(THIS_RELATIVE_PATH "../../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching next in path = ${THIS_SEARCH_PATH}")
+ endif()
+ endif()
+
+ # search other possible locations
+ if ("${WOLFSSL_ROOT}" STREQUAL "")
+ # there's not a hard-coded WOLFSSL_ROOT value above, so let's see if we can find it.
+ if( "$ENV{WOLFSSL_ROOT}" STREQUAL "" )
+ message(STATUS "Environment Variable WOLFSSL_ROOT not set. Will search common locations.")
+
+ message(STATUS "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
+ get_filename_component(THIS_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
+ message(STATUS "THIS_DIR = ${THIS_DIR}")
+
+ # find the user name to search for possible "wolfssl-username"
+ message(STATUS "USERNAME = $ENV{USERNAME}")
+ if( "$ENV{USER}" STREQUAL "" ) # the bash user
+ if( "$ENV{USERNAME}" STREQUAL "" ) # the Windows user
+ message(STATUS "could not find USER or USERNAME")
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USERNAME}")
+ endif()
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USER}")
+ endif()
+ message(STATUS "THIS_USER = ${THIS_USER}")
+
+ # This same makefile is used for both the wolfssl component, and other
+ # components that may depend on wolfssl, such as wolfssh. Therefore
+ # we need to determine if this makefile is in the wolfssl repo, or
+ # some other repo.
+
+ if( "{THIS_USER}" STREQUAL "" )
+ # This is highly unusual to not find a user name.
+ # In this case, we'll just search for a "wolfssl" directory:
+ message(STATUS "No username found!")
+ get_filename_component(WOLFSSL_ROOT "${THIS_RELATIVE_PATH}/wolfssl" ABSOLUTE)
+ else()
+ # We found an environment USER name!
+ # The first place to look for wolfssl will be in a user-clone called "wolfssl-[username]"
+ message(STATUS "Using [THIS_USER = ${THIS_USER}] to see if there's a [relative path]/wolfssl-${THIS_USER} directory.")
+ get_filename_component(WOLFSSL_ROOT "${THIS_RELATIVE_PATH}/wolfssl-${THIS_USER}" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ message(STATUS "Found wolfssl in user-suffix ${WOLFSSL_ROOT}")
+ else()
+ # If there's not a user-clone called "wolfssl-[username]",
+ # perhaps there's simply a git clone called "wolfssl"?
+ message(STATUS "Did not find wolfssl-${THIS_USER}; continuing search...")
+ get_filename_component(WOLFSSL_ROOT "${THIS_RELATIVE_PATH}/wolfssl" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ message(STATUS "Found wolfssl in standard ${WOLFSSL_ROOT}")
+ else()
+ # Things are looking pretty bleak. We'll likely not be able to compile.
+ message(STATUS "Did not find wolfssl in ${WOLFSSL_ROOT}")
+ endif()
+ endif()
+ endif()
+
+ else()
+ # there's an environment variable, so use it.
+ set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}")
+
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ get_filename_component(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" ABSOLUTE)
+ message(STATUS "Found WOLFSSL_ROOT via Environment Variable:")
+ else()
+ message(FATAL_ERROR "WOLFSSL_ROOT Environment Variable defined, but path not found:")
+ message(STATUS "$ENV{WOLFSSL_ROOT}")
+ endif()
+ endif()
+ # end of search for wolfssl component root
+ else()
+ # There's already a value assigned; we won't search for anything else.
+ message(STATUS "Found user-specified WOLFSSL_ROOT value.")
+ endif() # WOLFSSL_ROOT user defined
+
+ # After all the logic above, does our WOLFSSL_ROOT actually exist?
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ message(STATUS "WOLFSSL_ROOT = ${WOLFSSL_ROOT}")
+ else()
+ # Abort. We need wolfssl _somewhere_.
+ message(FATAL_ERROR "Could not find wolfssl in ${WOLFSSL_ROOT}. Try setting environment variable or git clone.")
+ endif()
+
+
+ set(INCLUDE_PATH ${WOLFSSL_ROOT})
+
+ set(COMPONENT_SRCDIRS "\"${WOLFSSL_ROOT}/src/\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/port/atmel\""
+ # "\"${WOLFSSL_ROOT}/wolfcrypt/benchmark\"" # the benchmark application
+ # "\"${WOLFSSL_ROOT}/wolfcrypt/test\"" # the test application
+ ) # COMPONENT_SRCDIRS
+ message(STATUS "This COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+
+ set(WOLFSSL_PROJECT_DIR "${CMAKE_HOME_DIRECTORY}/components/wolfssl")
+
+ # Espressif may take several passes through this makefile. Check to see if we found IDF
+ string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "" WOLFSSL_FOUND_IDF)
+
+ # get a list of all wolfcrypt assembly files; we'll exclude them as they don't target Xtensa
+ file(GLOB EXCLUDE_ASM *.S)
+ file(GLOB_RECURSE EXCLUDE_ASM ${CMAKE_SOURCE_DIR} "${WOLFSSL_ROOT}/wolfcrypt/src/*.S")
+
+ message(STATUS "IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
+ message(STATUS "EXCLUDE_ASM = ${EXCLUDE_ASM}")
+
+ #
+ # Check to see if there's both a local copy and EDP-IDF copy of the wolfssl and/or wolfssh components.
+ #
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ #
+ # wolfSSL found in both ESP-IDF and local project - needs to be resolved by user
+ #
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+ message(STATUS "Error: Found components/wolfssl in both local project and IDF_PATH")
+ message(STATUS "")
+ message(STATUS "To proceed: ")
+ message(STATUS "")
+ message(STATUS "Remove either the local project component: ${WOLFSSL_PROJECT_DIR} ")
+ message(STATUS "or the Espressif shared component installed at: $ENV{IDF_PATH}/components/wolfssl/ ")
+ message(STATUS "")
+ message(FATAL_ERROR "Please use wolfSSL in either local project or Espressif components, but not both.")
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+
+ # Optional: if you change the above FATAL_ERROR to STATUS you can warn at runtime with this macro definition:
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_MULTI_INSTALL_WARNING")
+
+ else()
+ if( EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ #
+ # wolfSSL found in ESP-IDF components and is assumed to be already configured in user_settings.h via setup.
+ #
+ message(STATUS "")
+ message(STATUS "Using components/wolfssl in IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "")
+ else()
+ #
+ # wolfSSL is not an ESP-IDF component.
+ # We need to now determine if it is local and if so if it is part of the wolfSSL repo,
+ # or if wolfSSL is simply installed as a local component.
+ #
+
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}" )
+ #
+ # wolfSSL found in local project.
+ #
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}/wolfcrypt/" )
+ message(STATUS "")
+ message(STATUS "Using installed project ./components/wolfssl in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+ #
+ # Note we already checked above and confirmed there's not another wolfSSL installed in the ESP-IDF components.
+ #
+ # We won't do anything else here, as it will be assumed the original install completed successfully.
+ #
+ else() # full wolfSSL not installed in local project
+ #
+ # This is the developer repo mode. wolfSSL will be assumed to be not installed to ESP-IDF nor local project
+ # In this configuration, we are likely running a wolfSSL example found directly in the repo.
+ #
+ message(STATUS "")
+ message(STATUS "Using developer repo ./components/wolfssl in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+
+ message(STATUS "************************************************************************************************")
+ # When in developer mode, we are typically running wolfSSL examples such as benchmark or test directories.
+ # However, the as-cloned or distributed wolfSSL does not have the ./include/ directory, so we'll add it as needed.
+ #
+ # first check if there's a [root]/include/user_settings.h
+ if( EXISTS "${WOLFSSL_ROOT}/include/user_settings.h" )
+ message(FATAL_ERROR "Found stray wolfSSL user_settings.h in "
+ "${WOLFSSL_ROOT}/include/user_settings.h "
+ " (please move it to ${WOLFSSL_PROJECT_DIR}/include/user_settings.h )")
+ else()
+ # we won't overwrite an existing user settings file, just note that we already have one:
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}/include/user_settings.h" )
+ message(STATUS "Using existing wolfSSL user_settings.h in "
+ "${WOLFSSL_PROJECT_DIR}/include/user_settings.h")
+ else()
+ message(STATUS "Installing wolfSSL user_settings.h to "
+ "${WOLFSSL_PROJECT_DIR}/include/user_settings.h")
+ file(COPY "${WOLFSSL_ROOT}/IDE/Espressif/ESP-IDF/user_settings.h"
+ DESTINATION "${CMAKE_HOME_DIRECTORY}/wolfssl/include/")
+ endif()
+ endif() # user_settings.h
+
+ # next check if there's a [root]/include/config.h
+ if( EXISTS "${WOLFSSL_ROOT}/include/config.h" )
+ message(FATAL_ERROR "Found stray wolfSSL config.h in ${WOLFSSL_ROOT}/include/config.h (please move it to ${WOLFSSL_PROJECT_DIR}/include/config.h")
+ else()
+ # we won't overwrite an existing user settings file, just note that we already have one:
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}/include/config.h" )
+ message(STATUS "Using existing wolfSSL config.h ${WOLFSSL_PROJECT_DIR}/include/config.h")
+ else()
+ message(STATUS "Installing wolfSSL config.h to ${WOLFSSL_PROJECT_DIR}/include/config.h")
+ file(COPY "${WOLFSSL_ROOT}/IDE/Espressif/ESP-IDF/dummy_config_h" DESTINATION "${WOLFSSL_PROJECT_DIR}/include/")
+ file(RENAME "${WOLFSSL_PROJECT_DIR}/include/dummy_config_h" "${WOLFSSL_PROJECT_DIR}/include/config.h")
+ endif() # Project config.h
+ endif() # WOLFSSL_ROOT config.h
+ message(STATUS "************************************************************************************************")
+ message(STATUS "")
+ endif()
+
+ else()
+ # we did not find a ./components/wolfssl/include/ directory from this pass of cmake.
+ if($WOLFSSL_FOUND_IDF)
+ message(STATUS "")
+ message(STATUS "WARNING: wolfSSL not found.")
+ message(STATUS "")
+ else()
+ # probably needs to be re-parsed by Espressif
+ message(STATUS "wolfSSL found IDF. Project Source:${PROJECT_SOURCE_DIR}")
+ endif() # else we have not found ESP-IDF yet
+ endif() # else not a local wolfSSL component
+
+ endif() #else not an ESP-IDF component
+ endif() # else not local copy and EDP-IDF wolfSSL
+
+
+ # RTOS_IDF_PATH is typically:
+ # "/Users/{username}/Desktop/esp-idf/components/freertos/include/freertos"
+ # depending on the environment, we may need to swap backslashes with forward slashes
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos")
+
+ string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT})
+
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ # ESP-IDF prior version 4.4x has a different RTOS directory structure
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/include/freertos")
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found legacy RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ message(STATUS "Could not find RTOS path")
+ endif()
+ endif()
+
+
+ set(COMPONENT_ADD_INCLUDEDIRS
+ "./include" # this is the location of wolfssl user_settings.h
+ "\"${WOLFSSL_ROOT}/\""
+ "\"${WOLFSSL_ROOT}/wolfssl/\""
+ "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt/\""
+ "\"${RTOS_IDF_PATH}/\""
+ )
+
+
+ if(IS_DIRECTORY ${IDF_PATH}/components/cryptoauthlib)
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "../cryptoauthlib/lib")
+ endif()
+
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "\"${WOLFSSL_ROOT}/wolfssl/\"")
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt/\"")
+
+
+
+ set(COMPONENT_SRCEXCLUDE
+ "\"${WOLFSSL_ROOT}/src/bio.c\""
+ "\"${WOLFSSL_ROOT}/src/conf.c\""
+ "\"${WOLFSSL_ROOT}/src/misc.c\""
+ "\"${WOLFSSL_ROOT}/src/pk.c\""
+ "\"${WOLFSSL_ROOT}/src/ssl_asn1.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_bn.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/x509.c\""
+ "\"${WOLFSSL_ROOT}/src/x509_str.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/evp.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/misc.c\""
+ "\"${EXCLUDE_ASM}\""
+ )
+
+ spaces2list(COMPONENT_REQUIRES)
+
+ separate_arguments(COMPONENT_SRCDIRS NATIVE_COMMAND "${COMPONENT_SRCDIRS}")
+ separate_arguments(COMPONENT_SRCEXCLUDE NATIVE_COMMAND "${COMPONENT_SRCEXCLUDE}")
+ separate_arguments(COMPONENT_ADD_INCLUDEDIRS NATIVE_COMMAND "${COMPONENT_ADD_INCLUDEDIRS}")
+
+ #
+ # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#example-component-requirements
+ #
+ message(STATUS "COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+ message(STATUS "COMPONENT_ADD_INCLUDEDIRS = ${COMPONENT_ADD_INCLUDEDIRS}")
+ message(STATUS "COMPONENT_REQUIRES = ${COMPONENT_REQUIRES}")
+ message(STATUS "COMPONENT_SRCEXCLUDE = ${COMPONENT_SRCEXCLUDE}")
+
+ #
+ # see https://docs.espressif.com/projects/esp-idf/en/stable/esp32/migration-guides/release-5.x/build-system.html?highlight=space%20path
+ #
+ set(EXTRA_COMPONENT_DIRS "${COMPONENT_SRCDIRS}")
+ idf_component_register(
+ SRC_DIRS "${COMPONENT_SRCDIRS}"
+ INCLUDE_DIRS "${COMPONENT_ADD_INCLUDEDIRS}"
+ REQUIRES "${COMPONENT_REQUIRES}"
+ EXCLUDE_SRCS "${COMPONENT_SRCEXCLUDE}"
+ PRIV_REQUIRES esp_timer driver # this will typically only be needed for wolfSSL benchmark
+ )
+ # some optional diagnostics
+ if (1)
+ get_cmake_property(_variableNames VARIABLES)
+ list (SORT _variableNames)
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES BEGIN")
+ message(STATUS "")
+ foreach (_variableName ${_variableNames})
+ message(STATUS "${_variableName}=${${_variableName}}")
+ endforeach()
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES END")
+ message(STATUS "")
+ endif()
+
+ # target_sources(wolfssl PRIVATE "\"${WOLFSSL_ROOT}/wolfssl/\"" "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt\"")
+endif() # CMAKE_BUILD_EARLY_EXPANSION
+
+
+
+# check to see if there's both a local copy and EDP-IDF copy of the wolfssl components
+if( EXISTS "${WOLFSSL_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ message(STATUS "")
+ message(STATUS "")
+ message(STATUS "********************************************************************")
+ message(STATUS "WARNING: Found components/wolfssl in both local project and IDF_PATH")
+ message(STATUS "********************************************************************")
+ message(STATUS "")
+endif()
+# end multiple component check
+
+
+#
+# LIBWOLFSSL_SAVE_INFO(VAR_OUPUT THIS_VAR VAR_RESULT)
+#
+# Save the THIS_VAR as a string in a macro called VAR_OUPUT
+#
+# VAR_OUPUT: the name of the macro to define
+# THIS_VAR: the OUTPUT_VARIABLE result from a execute_process()
+# VAR_RESULT: the RESULT_VARIABLE from a execute_process(); "0" if successful.
+#
+function ( LIBWOLFSSL_SAVE_INFO VAR_OUPUT THIS_VAR VAR_RESULT )
+ # is the RESULT_VARIABLE output value 0? If so, IS_VALID_VALUE is true.
+ string(COMPARE EQUAL "${VAR_RESULT}" "0" IS_VALID_VALUE)
+
+ # if we had a successful operation, save the THIS_VAR in VAR_OUPUT
+ if(${IS_VALID_VALUE})
+ # strip newline chars in THIS_VAR parameter and save in VAR_VALUE
+ string(REPLACE "\n" "" VAR_VALUE ${THIS_VAR})
+
+ # we'll could percolate the value to the parent for possible later use
+ # set(${VAR_OUPUT} ${VAR_VALUE} PARENT_SCOPE)
+
+ # but we're only using it here in this function
+ set(${VAR_OUPUT} ${VAR_VALUE})
+
+ # we'll print what we found to the console
+ message(STATUS "Found ${VAR_OUPUT}=${VAR_VALUE}")
+
+ # the interesting part is defining the VAR_OUPUT name a value to use in the app
+ add_definitions(-D${VAR_OUPUT}=\"${VAR_VALUE}\")
+ else()
+ # if we get here, check the execute_process command and parameters.
+ message(STATUS "LIBWOLFSSL_SAVE_INFO encountered a non-zero VAR_RESULT")
+ set(${VAR_OUPUT} "Unknown")
+ endif()
+endfunction() # LIBWOLFSSL_SAVE_INFO
+
+# create some programmatic #define values that will be used by ShowExtendedSystemInfo().
+# see wolfcrypt\src\port\Espressif\esp32_utl.c
+if(NOT CMAKE_BUILD_EARLY_EXPANSION)
+ set (git_cmd "git")
+ message(STATUS "Adding macro definitions:")
+
+ # LIBWOLFSSL_VERSION_GIT_ORIGIN: git config --get remote.origin.url
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "config" "--get" "remote.origin.url" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_ORIGIN "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_BRANCH: git rev-parse --abbrev-ref HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "rev-parse" "--abbrev-ref" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_BRANCH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_HASH: git rev-parse HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "rev-parse" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_SHORT_HASH: git rev-parse --short HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "rev-parse" "--short" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_SHORT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_HASH_DATE git show --no-patch --no-notes --pretty=\'\%cd\'
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "show" "--no-patch" "--no-notes" "--pretty=\'\%cd\'" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH_DATE "${TMP_OUT}" "${TMP_RES}")
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssl component config complete!")
+ message(STATUS "************************************************************************************************")
+endif()
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssl/include/user_settings.h b/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssl/include/user_settings.h
new file mode 100644
index 000000000..e08f666d8
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/components/wolfssl/include/user_settings.h
@@ -0,0 +1,261 @@
+/* user_settings.h
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#include /* essential to chip set detection */
+
+#undef WOLFSSL_ESPIDF
+#undef WOLFSSL_ESP32
+#undef WOLFSSL_ESPWROOM32SE
+#undef WOLFSSL_ESP32
+#undef WOLFSSL_ESP8266
+
+/* The Espressif sdkconfig will have chipset info.
+**
+** Possible values:
+**
+** CONFIG_IDF_TARGET_ESP32
+** CONFIG_IDF_TARGET_ESP32S2
+** CONFIG_IDF_TARGET_ESP32S3
+** CONFIG_IDF_TARGET_ESP32C3
+** CONFIG_IDF_TARGET_ESP32C6
+*/
+
+/* wolfSSH */
+#undef WOLFSSH_TERM /* may be defined in cmake for other examples */
+#define WOLFSSH_TERM
+#undef DEBUG_WOLFSSH /* may be defined in cmake for other examples */
+#define DEBUG_WOLFSSH
+
+#define WOLFSSL_ESPIDF
+
+/*
+ * choose ONE of these Espressif chips to define:
+ *
+ * WOLFSSL_ESP32
+ * WOLFSSL_ESPWROOM32SE
+ * WOLFSSL_ESP8266
+ */
+
+#define WOLFSSL_ESP32
+
+/* optionally turn off SHA512/224 SHA512/256 */
+/* #define WOLFSSL_NOSHA512_224 */
+/* #define WOLFSSL_NOSHA512_256 */
+
+#define BENCH_EMBEDDED
+#define USE_CERT_BUFFERS_2048
+
+/* TLS 1.3 */
+#define WOLFSSL_TLS13
+#define HAVE_TLS_EXTENSIONS
+#define WC_RSA_PSS
+#define HAVE_HKDF
+#define HAVE_AEAD
+#define HAVE_SUPPORTED_CURVES
+
+#define WOLFSSL_BENCHMARK_FIXED_UNITS_KB
+
+/* when you want to use SINGLE THREAD */
+#define SINGLE_THREADED
+
+#define NO_FILESYSTEM
+
+#define HAVE_AESGCM
+
+#define WOLFSSL_RIPEMD
+/* when you want to use SHA224 */
+/* #define WOLFSSL_SHA224 */
+
+#define NO_OLD_TLS
+
+/* when you want to use SHA384 */
+/* #define WOLFSSL_SHA384 */
+
+/* #define WOLFSSL_SHA3 */
+
+#define WOLFSSL_SHA512
+#define HAVE_ECC
+#define HAVE_CURVE25519
+#define CURVE25519_SMALL
+#define HAVE_ED25519
+
+/* when you want to use pkcs7 */
+/* #define HAVE_PKCS7 */
+
+#if defined(HAVE_PKCS7)
+ #define HAVE_AES_KEYWRAP
+ #define HAVE_X963_KDF
+ #define WOLFSSL_AES_DIRECT
+#endif
+
+/* when you want to use aes counter mode */
+/* #define WOLFSSL_AES_DIRECT */
+/* #define WOLFSSL_AES_COUNTER */
+
+/* esp32-wroom-32se specific definition */
+#if defined(WOLFSSL_ESPWROOM32SE)
+ #define WOLFSSL_ATECC508A
+ #define HAVE_PK_CALLBACKS
+ /* when you want to use a custom slot allocation for ATECC608A */
+ /* unless your configuration is unusual, you can use default */
+ /* implementation. */
+ /* #define CUSTOM_SLOT_ALLOCATION */
+#endif
+
+/* rsa primitive specific definition */
+#if defined(WOLFSSL_ESP32) || defined(WOLFSSL_ESPWROOM32SE)
+ /* Define USE_FAST_MATH and SMALL_STACK */
+ #define ESP32_USE_RSA_PRIMITIVE
+ /* threshold for performance adjustment for HW primitive use */
+ /* X bits of G^X mod P greater than */
+ #define EPS_RSA_EXPT_XBTIS 32
+ /* X and Y of X * Y mod P greater than */
+ #define ESP_RSA_MULM_BITS 9
+#endif
+#define RSA_LOW_MEM
+
+/* debug options */
+/* #define DEBUG_WOLFSSL */
+/* #define WOLFSSL_ESP32_CRYPT_DEBUG */
+/* #define WOLFSSL_ATECC508A_DEBUG */
+
+/* date/time */
+/* if it cannot adjust time in the device, */
+/* enable macro below */
+/* #define NO_ASN_TIME */
+/* #define XTIME time */
+
+/* adjust wait-timeout count if you see timeout in RSA HW acceleration */
+#define ESP_RSA_TIMEOUT_CNT 0x249F00
+
+#define HASH_SIZE_LIMIT /* for test.c */
+
+#define USE_FAST_MATH
+
+/* optionally use SP_MATH */
+/* #define SP_MATH */
+
+#define WOLFSSL_SMALL_STACK
+
+#define HAVE_VERSION_EXTENDED_INFO
+#define HAVE_WC_INTROSPECTION
+
+/* allows for all version info, even that suppressed with introspection */
+#define ALLOW_BINARY_MISMATCH_INTROSPECTION
+
+/* The ESP32 has some detailed statup information available:*/
+#define HAVE_VERSION_EXTENDED_INFO
+
+/* 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)
+ /* SM settings, possible cipher suites:
+
+ TLS13-AES128-GCM-SHA256
+ TLS13-CHACHA20-POLY1305-SHA256
+ TLS13-SM4-GCM-SM3
+ TLS13-SM4-CCM-SM3
+
+ #define WOLFSSL_ESP32_CIPHER_SUITE "TLS13-SM4-GCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "TLS13-SM4-CCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "ECDHE-ECDSA-SM4-CBC-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "ECDHE-ECDSA-SM4-GCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "ECDHE-ECDSA-SM4-CCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "TLS13-SM4-GCM-SM3:" \
+ "TLS13-SM4-CCM-SM3:"
+ */
+
+ #undef WOLFSSL_BASE16
+ #define WOLFSSL_BASE16 /* required for WOLFSSL_SM2 */
+
+ #undef WOLFSSL_SM4_ECB
+ #define WOLFSSL_SM4_ECB
+
+ #undef WOLFSSL_SM4_CBC
+ #define WOLFSSL_SM4_CBC
+
+ #undef WOLFSSL_SM4_CTR
+ #define WOLFSSL_SM4_CTR
+
+ #undef WOLFSSL_SM4_GCM
+ #define WOLFSSL_SM4_GCM
+
+ #undef WOLFSSL_SM4_CCM
+ #define WOLFSSL_SM4_CCM
+
+ #define HAVE_POLY1305
+ #define HAVE_CHACHA
+
+ #undef HAVE_AESGCM
+ #define HAVE_AESGCM
+#else
+ /* default settings */
+ #define USE_CERT_BUFFERS_2048
+#endif
+
+/* Default is HW enabled unless turned off.
+** Uncomment these lines for SW: */
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ /* #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)
+ #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)
+ /* #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_ESP32C2)
+ #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)
+ #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)
+ #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)
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+#else
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+#endif
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/CMakeLists.txt
new file mode 100644
index 000000000..6adee0ff5
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/CMakeLists.txt
@@ -0,0 +1,78 @@
+# This tag is used to include this file in the ESP Component Registry:
+# __ESP_COMPONENT_SOURCE__
+
+#
+# wolfssl client test
+#
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
+
+set (git_cmd "git")
+
+if( EXISTS "${CMAKE_HOME_DIRECTORY}/components/wolfssl/" AND EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ #
+ # wolfSSL found in both ESP-IDF and local project - needs to be resolved by user
+ #
+ message(STATUS "")
+ message(STATUS "WARNING: Found components/wolfssl in both local project and IDF_PATH")
+ message(STATUS "")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_MULTI_INSTALL_WARNING")
+endif()
+
+## register_component()
+idf_component_register(
+ SRCS main.c server.c time_helper.c wifi_connect.c
+ INCLUDE_DIRS "." "./include")
+#
+
+#
+# LIBWOLFSSL_SAVE_INFO(VAR_OUPUT THIS_VAR VAR_RESULT)
+#
+# Save the THIS_VAR as a string in a macro called VAR_OUPUT
+#
+# VAR_OUPUT: the name of the macro to define
+# THIS_VAR: the OUTPUT_VARIABLE result from a execute_process()
+# VAR_RESULT: the RESULT_VARIABLE from a execute_process(); "0" if successful.
+#
+function ( LIBWOLFSSL_SAVE_INFO VAR_OUPUT THIS_VAR VAR_RESULT )
+ # is the RESULT_VARIABLE output value 0? If so, IS_VALID_VALUE is true.
+ string(COMPARE EQUAL "${VAR_RESULT}" "0" IS_VALID_VALUE)
+
+ # if we had a successful operation, save the THIS_VAR in VAR_OUPUT
+ if(${IS_VALID_VALUE})
+ # strip newline chars in THIS_VAR parameter and save in VAR_VALUE
+ string(REPLACE "\n" "" VAR_VALUE ${THIS_VAR})
+
+ # we'll could percolate the value to the parent for possible later use
+ # set(${VAR_OUPUT} ${VAR_VALUE} PARENT_SCOPE)
+
+ # but we're only using it here in this function
+ set(${VAR_OUPUT} ${VAR_VALUE})
+
+ # we'll print what we found to the console
+ message(STATUS "Found ${VAR_OUPUT}=${VAR_VALUE}")
+
+ # the interesting part is defining the VAR_OUPUT name a value to use in the app
+ add_definitions(-D${VAR_OUPUT}=\"${VAR_VALUE}\")
+ else()
+ # if we get here, check the execute_process command and parameters.
+ message(STATUS "LIBWOLFSSL_SAVE_INFO encountered a non-zero VAR_RESULT")
+ set(${VAR_OUPUT} "Unknown")
+ endif()
+endfunction() # LIBWOLFSSL_SAVE_INFO
+
+if(NOT CMAKE_BUILD_EARLY_EXPANSION)
+ # LIBWOLFSSL_VERSION_GIT_HASH
+ execute_process(COMMAND ${git_cmd} "rev-parse" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_SHORT_HASH
+ execute_process(COMMAND ${git_cmd} "rev-parse" "--short" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_SHORT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_HASH_DATE
+ execute_process(COMMAND ${git_cmd} "show" "--no-patch" "--no-notes" "--pretty=\'\%cd\'" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH_DATE "${TMP_OUT}" "${TMP_RES}")
+endif()
+
+message(STATUS "")
+
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/main.h b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/main.h
new file mode 100644
index 000000000..7e07ec1df
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/main.h
@@ -0,0 +1,38 @@
+/* template main.h
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+/* Espressif libraries */
+#include "sdkconfig.h"
+#include
+#include
+
+/* wolfSSL */
+#include "user_settings.h" /* always include wolfSSL user_settings.h first */
+#include
+#include
+
+/* wolfSSH */
+#include
+#include
+
+#endif
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/time_helper.h b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/time_helper.h
new file mode 100644
index 000000000..5a7fc82da
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/time_helper.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+#ifndef _TIME_HELPER_H
+#define _TIME_HELPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int set_time(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* #ifndef _TIME_HELPER_H */
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/wifi_connect.h b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/wifi_connect.h
new file mode 100644
index 000000000..30dac129b
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/include/wifi_connect.h
@@ -0,0 +1,77 @@
+/* wifi_connect.h
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+#ifndef _WIFI_CONNECT_H
+#define _WIFI_CONNECT_H
+
+#include "esp_idf_version.h"
+#include "esp_log.h"
+#include "esp_wifi.h"
+#if ESP_IDF_VERSION_MAJOR >= 4
+ #include "esp_event.h"
+#else
+ #include "esp_event_loop.h"
+#endif
+
+/* ESP lwip */
+#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY
+
+/**
+ ******************************************************************************
+ ******************************************************************************
+ ** USER APPLICATION SETTINGS BEGIN
+ ******************************************************************************
+ ******************************************************************************
+ **/
+
+/* when using a private config with plain text passwords, not my_private_config.h should be excluded from git updates */
+#define USE_MY_PRIVATE_CONFIG
+
+#ifdef USE_MY_PRIVATE_CONFIG
+ #if defined(WOLFSSL_CMAKE_SYSTEM_NAME_WINDOWS)
+ #include "/workspace/my_private_config.h"
+ #elif defined(WOLFSSL_CMAKE_SYSTEM_NAME_WSL)
+ #include "/mnt/c/workspace/my_private_config.h"
+ #elif defined(WOLFSSL_CMAKE_SYSTEM_NAME_LINUX)
+ #include "~/workspace/my_private_config.h"
+ #elif defined(WOLFSSL_CMAKE_SYSTEM_NAME_APPLE)
+ #include "~/Documents/my_private_config.h"
+ #else
+ #warning "did not detect environment. using ~/my_private_config.h"
+ #include "~/my_private_config.h"
+ #endif
+#else
+
+ /*
+ ** The examples use WiFi configuration that you can set via project
+ ** configuration menu
+ **
+ ** If you'd rather not, just change the below entries to strings with
+ ** the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
+ */
+ #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
+ #define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
+#endif
+
+int wifi_init_sta(void);
+
+int wifi_show_ip(void);
+
+#endif /* _WIFI_CONNECT_H_ */
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/main.c b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/main.c
new file mode 100644
index 000000000..ada619692
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/main.c
@@ -0,0 +1,107 @@
+/* main.c
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+#include "main.h"
+#include "server.h"
+#include "wifi_connect.h"
+#include "time_helper.h"
+
+static const char* const TAG = "My Project";
+
+void app_main(void)
+{
+ func_args args = {0};
+
+ ESP_LOGI(TAG, "------------ wolfSSL wolfSSH template Example ----------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+ ESP_LOGI(TAG, "---------------------- BEGIN MAIN ----------------------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+
+ ESP_LOGI(TAG, "Hello wolfSSL!");
+
+#ifdef DEBUG_WOLFSSH
+ wolfSSH_Debugging_ON();
+#else
+ ESP_LOGI(TAG, "DEBUG_WOLFSSH is not defined, "
+ "so nothing will happen for teh next statement");
+#endif
+
+#ifdef HAVE_VERSION_EXTENDED_INFO
+ esp_ShowExtendedSystemInfo();
+#endif
+
+#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)));
+#endif
+
+/* the simplest check of the wolfSSL library presence: */
+#ifdef LIBWOLFSSL_VERSION_STRING
+ ESP_LOGI(TAG, "");
+ ESP_LOGI(TAG, "Found wolfSSL Version %s\n", LIBWOLFSSL_VERSION_STRING);
+#else
+ ESP_LOGW(TAG, "Warning: Could not find wolfSSL Version");
+#endif
+
+/* the simplest check of the wolfSSH library presence: */
+#ifdef LIBWOLFSSH_VERSION_STRING
+ ESP_LOGI(TAG, "");
+ ESP_LOGI(TAG, "Found wolfSSH Version %s\n", LIBWOLFSSH_VERSION_STRING);
+ wolfSSH_Log(WS_LOG_INFO, "[wolfssh] Hello World!");
+#else
+ ESP_LOGW(TAG, "Warning: Could not find wolfSSH Version");
+#endif
+
+ /* Initialize NVS */
+ esp_err_t ret = nvs_flash_init();
+ if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
+ ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
+ ESP_ERROR_CHECK(nvs_flash_erase());
+ ret = nvs_flash_init();
+ }
+ ESP_ERROR_CHECK(ret);
+
+ /* Initialize WiFi */
+ ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
+ ret = wifi_init_sta();
+ if (ret != 0) {
+ ESP_LOGV(TAG, "\n\nFailed to connect to WiFi. Halt.\n\n");
+#if defined(SINGLE_THREADED)
+ while (1);
+#else
+ vTaskDelay(60000);
+#endif
+ }
+
+ /* set time for cert validation */
+ set_time();
+
+ ESP_LOGI(TAG, "Starting wolfSSH server_test...");
+ server_test(&args);
+
+ ESP_LOGI(TAG, "\n\nDone!\n\n"
+ "If running from idf.py monitor, press twice: Ctrl+]\n\n"
+ "WOLFSSL_COMPLETE\n" /* exit keyword for wolfssl_monitor.py */
+ );
+} /* app_main */
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/server.c b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/server.c
new file mode 100644
index 000000000..a2390d260
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/server.c
@@ -0,0 +1,824 @@
+/* server.c
+ *
+ * Copyright (C) 2014-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSH.
+ *
+ * wolfSSH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wolfSSH. If not, see .
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include
+#endif
+
+#define WOLFSSH_TEST_SERVER
+#define WOLFSSH_TEST_THREADING
+
+
+#ifdef WOLFSSL_USER_SETTINGS
+ #include
+#else
+ #include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "server.h"
+
+#ifdef NO_FILESYSTEM
+ #include
+ #ifdef WOLFSSH_SCP
+ #include
+ #endif
+#endif
+
+
+#ifndef NO_WOLFSSH_SERVER
+
+static const char serverBanner[] = "wolfSSH Example Server\n";
+
+
+typedef struct {
+ WOLFSSH* ssh;
+ SOCKET_T fd;
+ word32 id;
+ char nonBlock;
+} thread_ctx_t;
+
+
+#ifndef EXAMPLE_HIGHWATER_MARK
+ #define EXAMPLE_HIGHWATER_MARK 0x3FFF8000 /* 1GB - 32kB */
+#endif
+#ifndef EXAMPLE_BUFFER_SZ
+ #define EXAMPLE_BUFFER_SZ 4096
+#endif
+#define SCRATCH_BUFFER_SZ 1200
+
+
+static byte find_char(const byte* str, const byte* buf, word32 bufSz)
+{
+ const byte* cur;
+
+ while (bufSz) {
+ cur = str;
+ while (*cur != '\0') {
+ if (*cur == *buf)
+ return *cur;
+ cur++;
+ }
+ buf++;
+ bufSz--;
+ }
+
+ return 0;
+}
+
+
+static int dump_stats(thread_ctx_t* ctx)
+{
+ char stats[1024];
+ word32 statsSz;
+ word32 txCount, rxCount, seq, peerSeq;
+
+ wolfSSH_GetStats(ctx->ssh, &txCount, &rxCount, &seq, &peerSeq);
+
+ WSNPRINTF(stats, sizeof(stats),
+ "Statistics for Thread #%u:\r\n"
+ " txCount = %u\r\n rxCount = %u\r\n"
+ " seq = %u\r\n peerSeq = %u\r\n",
+ ctx->id, txCount, rxCount, seq, peerSeq);
+ statsSz = (word32)strlen(stats);
+
+ fprintf(stderr, "%s", stats);
+ return wolfSSH_stream_send(ctx->ssh, (byte*)stats, statsSz);
+}
+
+
+static int NonBlockSSH_accept(WOLFSSH* ssh)
+{
+ int ret;
+ int error;
+ SOCKET_T sockfd;
+ int select_ret = 0;
+
+ ret = wolfSSH_accept(ssh);
+ error = wolfSSH_get_error(ssh);
+ sockfd = (SOCKET_T)wolfSSH_get_fd(ssh);
+
+ while (ret != WS_SUCCESS &&
+ (error == WS_WANT_READ || error == WS_WANT_WRITE))
+ {
+ if (error == WS_WANT_READ)
+ printf("... client would read block\n");
+ else if (error == WS_WANT_WRITE)
+ printf("... client would write block\n");
+
+ select_ret = tcp_select(sockfd, 1);
+ if (select_ret == WS_SELECT_RECV_READY ||
+ select_ret == WS_SELECT_ERROR_READY ||
+ error == WS_WANT_WRITE)
+ {
+ ret = wolfSSH_accept(ssh);
+ error = wolfSSH_get_error(ssh);
+ }
+ else if (select_ret == WS_SELECT_TIMEOUT)
+ error = WS_WANT_READ;
+ else
+ error = WS_FATAL_ERROR;
+ }
+
+ return ret;
+}
+
+
+static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)
+{
+ int ret;
+ thread_ctx_t* threadCtx = (thread_ctx_t*)vArgs;
+
+#if defined(WOLFSSH_SCP) && defined(NO_FILESYSTEM)
+ ScpBuffer scpBufferRecv, scpBufferSend;
+ byte fileBuffer[49000];
+ byte fileTmp[] = "wolfSSH SCP buffer file";
+
+ WMEMSET(&scpBufferRecv, 0, sizeof(ScpBuffer));
+ scpBufferRecv.buffer = fileBuffer;
+ scpBufferRecv.bufferSz = sizeof(fileBuffer);
+ wolfSSH_SetScpRecvCtx(threadCtx->ssh, (void*)&scpBufferRecv);
+
+ /* make buffer file to send if asked */
+ WMEMSET(&scpBufferSend, 0, sizeof(ScpBuffer));
+ WMEMCPY(scpBufferSend.name, "test.txt", sizeof("test.txt"));
+ scpBufferSend.nameSz = WSTRLEN("test.txt");
+ scpBufferSend.buffer = fileTmp;
+ scpBufferSend.bufferSz = sizeof(fileBuffer);
+ scpBufferSend.fileSz = sizeof(fileTmp);
+ scpBufferSend.mode = 0x1A4;
+ wolfSSH_SetScpSendCtx(threadCtx->ssh, (void*)&scpBufferSend);
+#endif
+
+ if (!threadCtx->nonBlock)
+ ret = wolfSSH_accept(threadCtx->ssh);
+ else
+ ret = NonBlockSSH_accept(threadCtx->ssh);
+
+ if (ret == WS_SUCCESS) {
+ byte* buf = NULL;
+ byte* tmpBuf;
+ int bufSz, backlogSz = 0, rxSz, txSz, stop = 0, txSum;
+
+ do {
+ bufSz = EXAMPLE_BUFFER_SZ + backlogSz;
+
+ tmpBuf = (byte*)realloc(buf, bufSz);
+ if (tmpBuf == NULL)
+ stop = 1;
+ else
+ buf = tmpBuf;
+
+ if (!stop) {
+ do {
+ rxSz = wolfSSH_stream_read(threadCtx->ssh,
+ buf + backlogSz,
+ EXAMPLE_BUFFER_SZ);
+ if (rxSz <= 0)
+ rxSz = wolfSSH_get_error(threadCtx->ssh);
+ } while (rxSz == WS_WANT_READ || rxSz == WS_WANT_WRITE);
+
+ if (rxSz > 0) {
+ backlogSz += rxSz;
+ txSum = 0;
+ txSz = 0;
+
+ while (backlogSz != txSum && txSz >= 0 && !stop) {
+ txSz = wolfSSH_stream_send(threadCtx->ssh,
+ buf + txSum,
+ backlogSz - txSum);
+
+ if (txSz > 0) {
+ byte c;
+ const byte matches[] = { 0x03, 0x05, 0x06, 0x00 };
+
+ c = find_char(matches, buf + txSum, txSz);
+ switch (c) {
+ case 0x03:
+ stop = 1;
+ break;
+ case 0x06:
+ if (wolfSSH_TriggerKeyExchange(threadCtx->ssh)
+ != WS_SUCCESS)
+ stop = 1;
+ break;
+ case 0x05:
+ if (dump_stats(threadCtx) <= 0)
+ stop = 1;
+ break;
+ }
+ txSum += txSz;
+ }
+ else if (txSz != WS_REKEYING)
+ stop = 1;
+ }
+
+ if (txSum < backlogSz)
+ memmove(buf, buf + txSum, backlogSz - txSum);
+ backlogSz -= txSum;
+ }
+ else
+ stop = 1;
+ }
+ } while (!stop);
+
+ free(buf);
+ } else if (ret == WS_SCP_COMPLETE) {
+ printf("scp file transfer completed\n");
+ #if defined(WOLFSSH_SCP) && defined(NO_FILESYSTEM)
+ if (scpBufferRecv.fileSz > 0) {
+ word32 z;
+
+ printf("file name : %s\n", scpBufferRecv.name);
+ printf(" size : %d\n", scpBufferRecv.fileSz);
+ printf(" mode : %o\n", scpBufferRecv.mode);
+ printf(" mTime : %lu\n", scpBufferRecv.mTime);
+ printf("\n");
+
+ for (z = 0; z < scpBufferRecv.fileSz; z++)
+ printf("%c", scpBufferRecv.buffer[z]);
+ printf("\n");
+ }
+ #endif
+ } else if (ret == WS_SFTP_COMPLETE) {
+ printf("Use example/echoserver/echoserver for SFTP\n");
+ }
+ wolfSSH_stream_exit(threadCtx->ssh, 0);
+ WCLOSESOCKET(threadCtx->fd);
+ wolfSSH_free(threadCtx->ssh);
+ free(threadCtx);
+
+ return 0;
+}
+
+#ifndef NO_FILESYSTEM
+static int load_file(const char* fileName, byte* buf, word32 bufSz)
+{
+ FILE* file;
+ word32 fileSz;
+ word32 readSz;
+
+ if (fileName == NULL) return 0;
+
+ if (WFOPEN(NULL, &file, fileName, "rb") != 0)
+ return 0;
+ fseek(file, 0, SEEK_END);
+ fileSz = (word32)ftell(file);
+ rewind(file);
+
+ if (fileSz > bufSz) {
+ fclose(file);
+ return 0;
+ }
+
+ readSz = (word32)fread(buf, 1, fileSz, file);
+ if (readSz < fileSz) {
+ fclose(file);
+ return 0;
+ }
+
+ fclose(file);
+
+ return fileSz;
+}
+#endif /* !NO_FILESYSTEM */
+
+/* returns buffer size on success */
+static int load_key(byte isEcc, byte* buf, word32 bufSz)
+{
+ word32 sz = 0;
+
+#ifndef NO_FILESYSTEM
+ const char* bufName;
+ bufName = isEcc ? "./keys/server-key-ecc.der" :
+ "./keys/server-key-rsa.der" ;
+ sz = load_file(bufName, buf, bufSz);
+#else
+ /* using buffers instead */
+ if (isEcc) {
+ if ((word32)sizeof_ecc_key_der_256 > bufSz) {
+ return 0;
+ }
+ WMEMCPY(buf, ecc_key_der_256, sizeof_ecc_key_der_256);
+ sz = sizeof_ecc_key_der_256;
+ }
+ else {
+ if ((word32)sizeof_rsa_key_der_2048 > bufSz) {
+ return 0;
+ }
+ WMEMCPY(buf, rsa_key_der_2048, sizeof_rsa_key_der_2048);
+ sz = sizeof_rsa_key_der_2048;
+ }
+#endif
+
+ return sz;
+}
+
+
+static INLINE void c32toa(word32 u32, byte* c)
+{
+ c[0] = (u32 >> 24) & 0xff;
+ c[1] = (u32 >> 16) & 0xff;
+ c[2] = (u32 >> 8) & 0xff;
+ c[3] = u32 & 0xff;
+}
+
+
+/* Map user names to passwords */
+/* Use arrays for username and p. The password or public key can
+ * be hashed and the hash stored here. Then I won't need the type. */
+typedef struct PwMap {
+ byte type;
+ byte username[32];
+ word32 usernameSz;
+ byte p[WC_SHA256_DIGEST_SIZE];
+ struct PwMap* next;
+} PwMap;
+
+
+typedef struct PwMapList {
+ PwMap* head;
+} PwMapList;
+
+
+static PwMap* PwMapNew(PwMapList* list, byte type, const byte* username,
+ word32 usernameSz, const byte* p, word32 pSz)
+{
+ PwMap* map;
+
+ map = (PwMap*)malloc(sizeof(PwMap));
+ if (map != NULL) {
+ wc_Sha256 sha;
+ byte flatSz[4];
+
+ map->type = type;
+ if (usernameSz >= sizeof(map->username))
+ usernameSz = sizeof(map->username) - 1;
+ memcpy(map->username, username, usernameSz + 1);
+ map->username[usernameSz] = 0;
+ map->usernameSz = usernameSz;
+
+ wc_InitSha256(&sha);
+ c32toa(pSz, flatSz);
+ wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
+ wc_Sha256Update(&sha, p, pSz);
+ wc_Sha256Final(&sha, map->p);
+
+ map->next = list->head;
+ list->head = map;
+ }
+
+ return map;
+}
+
+
+static void PwMapListDelete(PwMapList* list)
+{
+ if (list != NULL) {
+ PwMap* head = list->head;
+
+ while (head != NULL) {
+ PwMap* cur = head;
+ head = head->next;
+ memset(cur, 0, sizeof(PwMap));
+ free(cur);
+ }
+ }
+}
+
+
+static const char samplePasswordBuffer[] =
+ "jill:upthehill\n"
+ "jack:fetchapail\n";
+
+
+static const char samplePublicKeyEccBuffer[] =
+ "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA"
+ "BBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25"
+ "qUzgDtH7oyaQROUnNvk= hansel\n"
+ "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA"
+ "BBBKAtH8cqaDbtJFjtviLobHBmjCtG56DMkP6A4M2H9zX2/YCg1h9bYS7WHd9UQDwXO1Hh"
+ "IZzRYecXh7SG9P4GhRY= gretel\n";
+
+
+static const char samplePublicKeyRsaBuffer[] =
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho"
+ "MNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3G"
+ "p2yEhUZUEkDhtOXyqjns1ickC9Gh4u80aSVtwHRnJZh9xPhSq5tLOhId4eP61s+a5pwjTj"
+ "nEhBaIPUJO2C/M0pFnnbZxKgJlX7t1Doy7h5eXxviymOIvaCZKU+x5OopfzM/wFkey0EPW"
+ "NmzI5y/+pzU5afsdeEWdiQDIQc80H6Pz8fsoFPvYSG+s4/wz0duu7yeeV1Ypoho65Zr+pE"
+ "nIf7dO0B8EblgWt+ud+JI8wrAhfE4x hansel\n"
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqDwRVTRVk/wjPhoo66+Mztrc31KsxDZ"
+ "+kAV0139PHQ+wsueNpba6jNn5o6mUTEOrxrz0LMsDJOBM7CmG0983kF4gRIihECpQ0rcjO"
+ "P6BSfbVTE9mfIK5IsUiZGd8SoE9kSV2pJ2FvZeBQENoAxEFk0zZL9tchPS+OCUGbK4SDjz"
+ "uNZl/30Mczs73N3MBzi6J1oPo7sFlqzB6ecBjK2Kpjus4Y1rYFphJnUxtKvB0s+hoaadru"
+ "biE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdI"
+ "RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n";
+
+
+static int LoadPasswordBuffer(byte* buf, word32 bufSz, PwMapList* list)
+{
+ char* str = (char*)buf;
+ char* delimiter;
+ char* username;
+ char* password;
+
+ /* Each line of passwd.txt is in the format
+ * username:password\n
+ * This function modifies the passed-in buffer. */
+
+ if (list == NULL)
+ return -1;
+
+ if (buf == NULL || bufSz == 0)
+ return 0;
+
+ while (*str != 0) {
+ delimiter = strchr(str, ':');
+ if (delimiter == NULL) {
+ return -1;
+ }
+ username = str;
+ *delimiter = 0;
+ password = delimiter + 1;
+ str = strchr(password, '\n');
+ if (str == NULL) {
+ return -1;
+ }
+ *str = 0;
+ str++;
+ if (PwMapNew(list, WOLFSSH_USERAUTH_PASSWORD,
+ (byte*)username, (word32)strlen(username),
+ (byte*)password, (word32)strlen(password)) == NULL ) {
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int LoadPublicKeyBuffer(byte* buf, word32 bufSz, PwMapList* list)
+{
+ char* str = (char*)buf;
+ char* delimiter;
+ byte* publicKey64;
+ word32 publicKey64Sz;
+ byte* username;
+ word32 usernameSz;
+ byte publicKey[300];
+ word32 publicKeySz;
+
+ /* Each line of passwd.txt is in the format
+ * ssh-rsa AAAB3BASE64ENCODEDPUBLICKEYBLOB username\n
+ * This function modifies the passed-in buffer. */
+ if (list == NULL)
+ return -1;
+
+ if (buf == NULL || bufSz == 0)
+ return 0;
+
+ while (*str != 0) {
+ /* Skip the public key type. This example will always be ssh-rsa. */
+ delimiter = strchr(str, ' ');
+ if (delimiter == NULL) {
+ return -1;
+ }
+ str = delimiter + 1;
+ delimiter = strchr(str, ' ');
+ if (delimiter == NULL) {
+ return -1;
+ }
+ publicKey64 = (byte*)str;
+ *delimiter = 0;
+ publicKey64Sz = (word32)(delimiter - str);
+ str = delimiter + 1;
+ delimiter = strchr(str, '\n');
+ if (delimiter == NULL) {
+ return -1;
+ }
+ username = (byte*)str;
+ *delimiter = 0;
+ usernameSz = (word32)(delimiter - str);
+ str = delimiter + 1;
+ publicKeySz = sizeof(publicKey);
+
+ if (Base64_Decode(publicKey64, publicKey64Sz,
+ publicKey, &publicKeySz) != 0) {
+
+ return -1;
+ }
+
+ if (PwMapNew(list, WOLFSSH_USERAUTH_PUBLICKEY,
+ username, usernameSz,
+ publicKey, publicKeySz) == NULL ) {
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int wsUserAuth(byte authType,
+ WS_UserAuthData* authData,
+ void* ctx)
+{
+ PwMapList* list;
+ PwMap* map;
+ byte authHash[WC_SHA256_DIGEST_SIZE];
+
+ if (ctx == NULL) {
+ fprintf(stderr, "wsUserAuth: ctx not set");
+ return WOLFSSH_USERAUTH_FAILURE;
+ }
+
+ if (authType != WOLFSSH_USERAUTH_PASSWORD &&
+ authType != WOLFSSH_USERAUTH_PUBLICKEY) {
+
+ return WOLFSSH_USERAUTH_FAILURE;
+ }
+
+ /* Hash the password or public key with its length. */
+ {
+ wc_Sha256 sha;
+ byte flatSz[4];
+ wc_InitSha256(&sha);
+ if (authType == WOLFSSH_USERAUTH_PASSWORD) {
+ c32toa(authData->sf.password.passwordSz, flatSz);
+ wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
+ wc_Sha256Update(&sha,
+ authData->sf.password.password,
+ authData->sf.password.passwordSz);
+ }
+ else if (authType == WOLFSSH_USERAUTH_PUBLICKEY) {
+ c32toa(authData->sf.publicKey.publicKeySz, flatSz);
+ wc_Sha256Update(&sha, flatSz, sizeof(flatSz));
+ wc_Sha256Update(&sha,
+ authData->sf.publicKey.publicKey,
+ authData->sf.publicKey.publicKeySz);
+ }
+ wc_Sha256Final(&sha, authHash);
+ }
+
+ list = (PwMapList*)ctx;
+ map = list->head;
+
+ while (map != NULL) {
+ if (authData->usernameSz == map->usernameSz &&
+ memcmp(authData->username, map->username, map->usernameSz) == 0) {
+
+ if (authData->type == map->type) {
+ if (memcmp(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
+ return WOLFSSH_USERAUTH_SUCCESS;
+ }
+ else {
+ return (authType == WOLFSSH_USERAUTH_PASSWORD ?
+ WOLFSSH_USERAUTH_INVALID_PASSWORD :
+ WOLFSSH_USERAUTH_INVALID_PUBLICKEY);
+ }
+ }
+ else {
+ return WOLFSSH_USERAUTH_INVALID_AUTHTYPE;
+ }
+ }
+ map = map->next;
+ }
+
+ return WOLFSSH_USERAUTH_INVALID_USER;
+}
+
+
+static void ShowUsage(void)
+{
+ printf("server %s\n", LIBWOLFSSH_VERSION_STRING);
+ printf(" -h display this help and exit\n");
+ printf(" -m allow multiple connections\n");
+ printf(" -e use ECC private key\n");
+ printf(" -N use non-blocking sockets\n");
+}
+
+
+THREAD_RETURN WOLFSSH_THREAD server_test(void* args)
+{
+ WOLFSSH_CTX* ctx = NULL;
+ PwMapList pwMapList;
+ SOCKET_T listenFd = 0;
+ word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
+ word32 threadCount = 0;
+ word16 port = wolfSshPort;
+ char multipleConnections = 0;
+ char useEcc = 0;
+ int ch;
+ char nonBlock = 0;
+
+ int argc = ((func_args*)args)->argc;
+ char** argv = ((func_args*)args)->argv;
+ ((func_args*)args)->return_code = 0;
+
+ while ((ch = mygetopt(argc, argv, "hmeN")) != -1) {
+ switch (ch) {
+ case 'h' :
+ ShowUsage();
+ exit(EXIT_SUCCESS);
+
+ case 'm' :
+ multipleConnections = 1;
+ break;
+
+ case 'e' :
+ useEcc = 1;
+ break;
+
+ case 'N' :
+ nonBlock = 1;
+ break;
+
+ default:
+ ShowUsage();
+ exit(MY_EX_USAGE);
+ }
+ }
+ myoptind = 0; /* reset for test cases */
+
+#ifdef WOLFSSH_NO_RSA
+ /* If wolfCrypt isn't built with RSA, force ECC on. */
+ useEcc = 1;
+#endif
+
+ if (wolfSSH_Init() != WS_SUCCESS) {
+ fprintf(stderr, "Couldn't initialize wolfSSH.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
+ if (ctx == NULL) {
+ fprintf(stderr, "Couldn't allocate SSH CTX data.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&pwMapList, 0, sizeof(pwMapList));
+ wolfSSH_SetUserAuth(ctx, wsUserAuth);
+ wolfSSH_CTX_SetBanner(ctx, serverBanner);
+
+ {
+ const char* bufName;
+ byte buf[SCRATCH_BUFFER_SZ];
+ word32 bufSz;
+
+ bufSz = load_key(useEcc, buf, SCRATCH_BUFFER_SZ);
+ if (bufSz == 0) {
+ fprintf(stderr, "Couldn't load key.\n");
+ exit(EXIT_FAILURE);
+ }
+ if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, buf, bufSz,
+ WOLFSSH_FORMAT_ASN1) < 0) {
+ fprintf(stderr, "Couldn't use key buffer.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ bufSz = (word32)strlen(samplePasswordBuffer);
+ memcpy(buf, samplePasswordBuffer, bufSz);
+ buf[bufSz] = 0;
+ LoadPasswordBuffer(buf, bufSz, &pwMapList);
+
+ bufName = useEcc ? samplePublicKeyEccBuffer :
+ samplePublicKeyRsaBuffer;
+ bufSz = (word32)strlen(bufName);
+ memcpy(buf, bufName, bufSz);
+ buf[bufSz] = 0;
+ LoadPublicKeyBuffer(buf, bufSz, &pwMapList);
+ }
+
+ tcp_listen(&listenFd, &port, 1);
+
+ do {
+ SOCKET_T clientFd = 0;
+ SOCKADDR_IN_T clientAddr;
+ socklen_t clientAddrSz = sizeof(clientAddr);
+#ifndef SINGLE_THREADED
+ THREAD_TYPE thread;
+#endif
+ WOLFSSH* ssh;
+ thread_ctx_t* threadCtx;
+
+ threadCtx = (thread_ctx_t*)malloc(sizeof(thread_ctx_t));
+ if (threadCtx == NULL) {
+ fprintf(stderr, "Couldn't allocate thread context data.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ ssh = wolfSSH_new(ctx);
+ if (ssh == NULL) {
+ fprintf(stderr, "Couldn't allocate SSH data.\n");
+ exit(EXIT_FAILURE);
+ }
+ wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
+ /* Use the session object for its own highwater callback ctx */
+ if (defaultHighwater > 0) {
+ wolfSSH_SetHighwaterCtx(ssh, (void*)ssh);
+ wolfSSH_SetHighwater(ssh, defaultHighwater);
+ }
+
+ clientFd = accept(listenFd, (struct sockaddr*)&clientAddr,
+ &clientAddrSz);
+ if (clientFd == -1)
+ err_sys("tcp accept failed");
+
+ if (nonBlock)
+ tcp_set_nonblocking(&clientFd);
+
+ wolfSSH_set_fd(ssh, (int)clientFd);
+
+ threadCtx->ssh = ssh;
+ threadCtx->fd = clientFd;
+ threadCtx->id = threadCount++;
+ threadCtx->nonBlock = nonBlock;
+
+#ifndef SINGLE_THREADED
+ ThreadStart(server_worker, threadCtx, &thread);
+
+ if (multipleConnections)
+ ThreadDetach(thread);
+ else
+ ThreadJoin(thread);
+#else
+ server_worker(threadCtx);
+#endif /* SINGLE_THREADED */
+ } while (multipleConnections);
+
+ PwMapListDelete(&pwMapList);
+ wolfSSH_CTX_free(ctx);
+ if (wolfSSH_Cleanup() != WS_SUCCESS) {
+ fprintf(stderr, "Couldn't clean up wolfSSH.\n");
+ exit(EXIT_FAILURE);
+ }
+#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
+ wc_ecc_fp_free(); /* free per thread cache */
+#endif
+
+ return 0;
+}
+
+#endif /* NO_WOLFSSH_SERVER */
+
+
+#ifndef NO_MAIN_DRIVER
+
+ int main(int argc, char** argv)
+ {
+ func_args args;
+
+ args.argc = argc;
+ args.argv = argv;
+ args.return_code = 0;
+
+ WSTARTTCP();
+
+ ChangeToWolfSshRoot();
+ #ifdef DEBUG_WOLFSSH
+ wolfSSH_Debugging_ON();
+ #endif
+
+ wolfSSH_Init();
+
+#ifndef NO_WOLFSSH_SERVER
+ server_test(&args);
+#else
+ printf("wolfSSH compiled without server support\n");
+#endif
+
+ wolfSSH_Cleanup();
+
+ return args.return_code;
+ }
+
+
+ int myoptind = 0;
+ char* myoptarg = NULL;
+
+#endif /* NO_MAIN_DRIVER */
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/server.h b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/server.h
new file mode 100644
index 000000000..67a9dabb8
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/server.h
@@ -0,0 +1,30 @@
+/* server.h
+ *
+ * Copyright (C) 2014-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSH.
+ *
+ * wolfSSH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wolfSSH. If not, see .
+ */
+
+
+#ifndef _WOLFSSH_EXAMPLES_SERVER_H_
+#define _WOLFSSH_EXAMPLES_SERVER_H_
+
+#include
+
+THREAD_RETURN WOLFSSH_THREAD server_test(void* args);
+
+
+#endif /* _WOLFSSH_EXAMPLES_SERVER_H_ */
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/time_helper.c b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/time_helper.c
new file mode 100644
index 000000000..e6d5f752b
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/time_helper.c
@@ -0,0 +1,120 @@
+/* time_helper.c
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#include
+#include
+
+#include "sdkconfig.h"
+#include "esp_log.h"
+
+#include "time_helper.h"
+
+const static char* TAG = "Time Helper";
+
+#define TIME_ZONE "PST-8"
+/* NELEMS(x) number of elements
+ * To determine the number of elements in the array, we can divide the total size of
+ * the array by the size of the array element
+ * See https://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c
+ **/
+#define NELEMS(x) ( (int)(sizeof(x) / sizeof((x)[0])) )
+#define NTP_SERVER_LIST ( (char*[]) { \
+ "pool.ntp.org", \
+ "time.nist.gov", \
+ "utcnist.colorado.edu" \
+ } \
+ )
+/* #define NTP_SERVER_COUNT using NELEMS:
+ *
+ * (int)(sizeof(NTP_SERVER_LIST) / sizeof(NTP_SERVER_LIST[0]))
+ */
+#define NTP_SERVER_COUNT NELEMS(NTP_SERVER_LIST)
+char* ntpServerList[NTP_SERVER_COUNT] = NTP_SERVER_LIST;
+
+/* our NTP server list is global info */
+extern char* ntpServerList[NTP_SERVER_COUNT];
+
+
+int set_time(void)
+{
+ /* we'll also return a result code of zero */
+ int res = 0;
+ int i = 0; /* counter for time servers */
+ time_t interim_time;
+
+ /* ideally, we'd like to set time from network,
+ * but let's set a default time, just in case */
+ struct tm timeinfo = {
+ .tm_year = 2023 - 1900,
+ .tm_mon = 7,
+ .tm_mday = 18,
+ .tm_hour = 9,
+ .tm_min = 49,
+ .tm_sec = 0
+ };
+ struct timeval now;
+
+#ifndef NTP_SERVER_COUNT
+ #define NTP_SERVER_COUNT 0
+ char* ntpServerList[NTP_SERVER_COUNT];
+#endif /* not defined: NTP_SERVER_COUNT */
+
+#ifndef TIME_ZONE
+ #define TIME_ZONE "PST-8"
+#endif /* not defined: TIME_ZONE */
+
+
+ /* set interim static time */
+ interim_time = mktime(&timeinfo);
+ now = (struct timeval){ .tv_sec = interim_time };
+ settimeofday(&now, NULL);
+
+
+ /* set timezone */
+ setenv("TZ", TIME_ZONE, 1);
+ tzset();
+
+ if (NTP_SERVER_COUNT) {
+ /* next, let's setup NTP time servers
+ *
+ * see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/system_time.html#sntp-time-synchronization
+ */
+ sntp_setoperatingmode(SNTP_OPMODE_POLL);
+
+ ESP_LOGI(TAG, "sntp_setservername:");
+ for (i = 0; i < NTP_SERVER_COUNT; i++) {
+ const char* thisServer = ntpServerList[i];
+ if (strncmp(thisServer, "\x00", 1) == 0) {
+ /* just in case we run out of NTP servers */
+ break;
+ }
+ ESP_LOGI(TAG, "%s", thisServer);
+ sntp_setservername(i, thisServer);
+ }
+ sntp_init();
+ ESP_LOGI(TAG, "sntp_init done.");
+ }
+ else {
+ ESP_LOGI(TAG, "No sntp time servers found.");
+ }
+ return res;
+}
+
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/wifi_connect.c b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/wifi_connect.c
new file mode 100644
index 000000000..3579e2326
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/main/wifi_connect.c
@@ -0,0 +1,235 @@
+/* wifi_connect.c
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+/*ESP specific */
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "wifi_connect.h"
+#include "lwip/sockets.h"
+#include "lwip/netdb.h"
+#include "lwip/apps/sntp.h"
+#include "nvs_flash.h"
+
+/* wolfSSL */
+#include
+#include
+#include
+#ifndef WOLFSSL_ESPIDF
+ #warning "problem with wolfSSL user_settings. Check components/wolfssl/include"
+#endif
+
+#if ESP_IDF_VERSION_MAJOR >= 4
+// #include "protocol_examples_common.h"
+#else
+ const static int CONNECTED_BIT = BIT0;
+ static EventGroupHandle_t wifi_event_group;
+#endif
+
+/* breadcrumb prefix for logging */
+const static char *TAG = "wifi_connect";
+
+#if ESP_IDF_VERSION_MAJOR < 4
+/* event handler for wifi events */
+static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
+{
+ switch (event->event_id)
+ {
+ case SYSTEM_EVENT_STA_START:
+ esp_wifi_connect();
+ break;
+ case SYSTEM_EVENT_STA_GOT_IP:
+ #if ESP_IDF_VERSION_MAJOR >= 4
+ ESP_LOGI(TAG, "got ip:" IPSTR "\n",
+ IP2STR(&event->event_info.got_ip.ip_info.ip));
+ #else
+ ESP_LOGI(TAG, "got ip:%s",
+ ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
+ #endif
+ /* see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos_idf.html */
+ xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
+ break;
+ case SYSTEM_EVENT_STA_DISCONNECTED:
+ esp_wifi_connect();
+ xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
+ break;
+ default:
+ break;
+ }
+ return ESP_OK;
+}
+#else
+#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
+#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
+
+#ifdef CONFIG_ESP_MAXIMUM_RETRY
+ #define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY
+#else
+ #define CONFIG_ESP_MAXIMUM_RETRY 5
+#endif
+
+
+#if CONFIG_ESP_WIFI_AUTH_OPEN
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
+#elif CONFIG_ESP_WIFI_AUTH_WEP
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
+#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
+#endif
+
+#ifndef ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD
+ #define CONFIG_ESP_WIFI_AUTH_WPA2_PSK 1
+ #define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD CONFIG_ESP_WIFI_AUTH_WPA2_PSK
+#endif
+
+/* FreeRTOS event group to signal when we are connected*/
+static EventGroupHandle_t s_wifi_event_group;
+
+/* The event group allows multiple bits for each event, but we only care about two events:
+ * - we are connected to the AP with an IP
+ * - we failed to connect after the maximum amount of retries */
+#define WIFI_CONNECTED_BIT BIT0
+#define WIFI_FAIL_BIT BIT1
+
+
+static int s_retry_num = 0;
+ip_event_got_ip_t* event;
+
+
+static void event_handler(void* arg, esp_event_base_t event_base,
+ int32_t event_id, void* event_data)
+{
+ if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
+ esp_wifi_connect();
+ } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
+ if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
+ esp_wifi_connect();
+ s_retry_num++;
+ ESP_LOGI(TAG, "retry to connect to the AP");
+ } else {
+ xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
+ }
+ ESP_LOGI(TAG,"connect to the AP fail");
+ } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
+ event = (ip_event_got_ip_t*) event_data;
+ wifi_show_ip();
+ s_retry_num = 0;
+ xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
+ }
+}
+
+int wifi_init_sta(void)
+{
+ int ret = 0;
+ s_wifi_event_group = xEventGroupCreate();
+
+ ESP_ERROR_CHECK(esp_netif_init());
+
+ ESP_ERROR_CHECK(esp_event_loop_create_default());
+ esp_netif_create_default_wifi_sta();
+
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+
+ esp_event_handler_instance_t instance_any_id;
+ esp_event_handler_instance_t instance_got_ip;
+ ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+ ESP_EVENT_ANY_ID,
+ &event_handler,
+ NULL,
+ &instance_any_id));
+ ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
+ IP_EVENT_STA_GOT_IP,
+ &event_handler,
+ NULL,
+ &instance_got_ip));
+
+ wifi_config_t wifi_config = {
+ .sta = {
+ .ssid = EXAMPLE_ESP_WIFI_SSID,
+ .password = EXAMPLE_ESP_WIFI_PASS,
+ /* Authmode threshold resets to WPA2 as default if password matches
+ * WPA2 standards (pasword len => 8). If you want to connect the
+ * device to deprecated WEP/WPA networks, Please set the threshold
+ * value WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with
+ * length and format matching to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK
+ * standards. */
+ .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
+ .sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
+ },
+ };
+ ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
+ ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
+ ESP_ERROR_CHECK(esp_wifi_start() );
+
+ ESP_LOGI(TAG, "wifi_init_sta finished.");
+
+ /* Waiting until either the connection is established (WIFI_CONNECTED_BIT)
+ * or connection failed for the maximum number of re-tries (WIFI_FAIL_BIT).
+ * The bits are set by event_handler() (see above) */
+ EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
+ WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
+ pdFALSE,
+ pdFALSE,
+ portMAX_DELAY);
+
+ /* xEventGroupWaitBits() returns the bits before the call returned,
+ * hence we can test which event actually happened. */
+#if defined(SHOW_SSID_AND_PASSWORD)
+ ESP_LOGW(TAG, "Undefine SHOW_SSID_AND_PASSWORD to not show SSID/password");
+ if (bits & WIFI_CONNECTED_BIT) {
+ ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
+ EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
+ } else if (bits & WIFI_FAIL_BIT) {
+ ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
+ EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
+ } else {
+ ESP_LOGE(TAG, "UNEXPECTED EVENT");
+ }
+#else
+ if (bits & WIFI_CONNECTED_BIT) {
+ ESP_LOGI(TAG, "Connected to AP");
+ } else if (bits & WIFI_FAIL_BIT) {
+ ESP_LOGI(TAG, "Failed to connect to AP");
+ ret = -1;
+ } else {
+ ESP_LOGE(TAG, "Connect to AP UNEXPECTED EVENT");
+ ret = -2;
+ }
+#endif
+ return ret;
+}
+
+int wifi_show_ip(void)
+{
+ ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
+ return 0;
+}
+#endif
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_server/sdkconfig.defaults b/ide/Espressif/ESP-IDF/examples/wolfssh_server/sdkconfig.defaults
new file mode 100644
index 000000000..2842aa34e
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_server/sdkconfig.defaults
@@ -0,0 +1,23 @@
+CONFIG_FREERTOS_HZ=1000
+CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
+
+#
+# Default main stack size
+#
+# This is typically way bigger than needed for stack size. See user_settings.h
+#
+CONFIG_ESP_MAIN_TASK_STACK_SIZE=10500
+
+# Legacy stack size for older ESP-IDF versions
+CONFIG_MAIN_TASK_STACK_SIZE=10500
+
+#
+# Compiler options
+#
+CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
+CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
+CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2
+CONFIG_COMPILER_HIDE_PATHS_MACROS=y
+CONFIG_COMPILER_STACK_CHECK_MODE_NORM=y
+CONFIG_COMPILER_STACK_CHECK=y
+
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_template/CMakeLists.txt
new file mode 100644
index 000000000..1def9d0be
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/CMakeLists.txt
@@ -0,0 +1,68 @@
+# The following lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+# enable wolfssl user_settings.h project-wide
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
+
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSH_TERM")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG_WOLFSSH")
+
+# set(WOLFSSL_ROOT "~/workspace/wolfssl-other-source")
+
+# Optional WOLFSSL_CMAKE_SYSTEM_NAME detection to find
+# USE_MY_PRIVATE_CONFIG path for my_private_config.h
+#
+if(WIN32)
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_WINDOWS")
+ message("Detected Windows")
+endif()
+if(CMAKE_HOST_UNIX)
+ message("Detected UNIX")
+endif()
+if(APPLE)
+ message("Detected APPLE")
+endif()
+if(CMAKE_HOST_UNIX AND (NOT APPLE) AND EXISTS "/proc/sys/fs/binfmt_misc/WSLInterop")
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_WSL")
+ message("Detected WSL")
+endif()
+if(CMAKE_HOST_UNIX AND (NOT APPLE) AND (NOT WIN32))
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_LINUX")
+ message("Detected Linux")
+endif()
+if(APPLE)
+ # Windows-specific configuration here
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_CMAKE_SYSTEM_NAME_APPLE")
+ message("Detected Apple")
+endif()
+# End optional WOLFSSL_CMAKE_SYSTEM_NAME
+
+# Check that there are not conflicting wolfSSL components
+# The ESP Registry Component will be in ./managed_components/wolfssl__wolfssl
+# The local component wolfSSL directory will be in ./components/wolfssl
+if( EXISTS "${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolfssl" AND EXISTS "${CMAKE_HOME_DIRECTORY}/components/wolfssl" )
+ # These exclude statements don't seem to be honored by the $ENV{IDF_PATH}/tools/cmake/project.cmake'
+ # add_subdirectory("${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolfssl" EXCLUDE_FROM_ALL)
+ # add_subdirectory("${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolfssl/include" EXCLUDE_FROM_ALL)
+ # So we'll error out and let the user decide how to proceed:
+ message(WARNING "\nFound wolfSSL components in\n"
+ "./managed_components/wolfssl__wolfssl\n"
+ "and\n"
+ "./components/wolfssl\n"
+ "in project directory: \n"
+ "${CMAKE_HOME_DIRECTORY}")
+ message(FATAL_ERROR "\nPlease use either the ESP Registry Managed Component or the wolfSSL component directory but not both.\n"
+ "If removing the ./managed_components/wolfssl__wolfssl directory, remember to also remove "
+ "or rename the idf_component.yml file typically found in ./main/")
+else()
+ message(STATUS "No conflicting wolfSSL components found.")
+endif()
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+
+project(wolfssh_template)
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/README.md b/ide/Espressif/ESP-IDF/examples/wolfssh_template/README.md
new file mode 100644
index 000000000..d6dd17ff7
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/README.md
@@ -0,0 +1,64 @@
+# wolfSSL Template Project
+
+This is an example minimally viable wolfSSL template to get started with your own project.
+
+### Prerequisites
+
+It is assumed the [ESP-IDF environment](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/) has been installed.
+
+### Files Included
+
+- [main.c](./main/main.c) with a simple call to an Espressif library (`ESP_LOGI`) and a call to a wolfSSL library (`esp_ShowExtendedSystemInfo`) .
+
+- See [components/wolfssl/include](./components/wolfssl/include/user_settings.h) directory to edit the wolfSSL `user_settings.h`.
+
+- Edit [main/CMakeLists.txt](./main/CMakeLists.txt) to add/remove source files.
+
+- The [components/wolfssl/CMakeLists.txt](./components/wolfssl/CMakeLists.txt) typically does not need to be changed.
+
+- Optional [VisualGDB Project](./VisualGDB/wolfssl_template_IDF_v5.1_ESP32.vgdbproj) for Visual Studio using ESP32 and ESP-IDF v5.1.
+
+- Edit the project [CMakeLists.txt](./CMakeLists.txt) to optionally point this project's wolfSSL component source code at a different directory:
+
+```
+set(WOLFSSL_ROOT "~/workspace/wolfssl-other-source")
+```
+
+
+## Getting Started:
+
+Here's an example using the command-line [idf.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-py.html).
+
+Edit your `WRK_IDF_PATH`to point to your ESP-IDF install directory.
+
+```
+WRK_IDF_PATH=/mnt/c/SysGCC/esp32/esp-idf/v5.1
+
+echo "Run export.sh from ${WRK_IDF_PATH}"
+. ${WRK_IDF_PATH}/export.sh
+
+# build the example:
+idf.py build
+
+# flash the code onto the serial device at /dev/ttyS19
+idf.py flash -p /dev/ttyS19 -b 115200
+
+# build, flash, and view UART output with one command:
+idf.py flash -p /dev/ttyS19 -b 115200 monitor
+```
+
+Press `Ctrl+]` to exit `idf.py monitor`. See [additional monitor keyboard commands](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-monitor.html).
+
+## Other Examples:
+
+For examples, see:
+
+- [TLS Client](../wolfssl_client/README.md)
+- [TLS Server](../wolfssl_server/README.md)
+- [Benchmark](../wolfssl_benchmark/README.md)
+- [Test](../wolfssl_test/README.md)
+- [wolfssl-examples](https://github.com/wolfSSL/wolfssl-examples/tree/master/ESP32)
+- [wolfssh-examples](https://github.com/wolfSSL/wolfssh-examples/tree/main/Espressif)
+
+
+
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/VisualGDB/wolfssh_template_IDF_v5.1_ESP32.sln b/ide/Espressif/ESP-IDF/examples/wolfssh_template/VisualGDB/wolfssh_template_IDF_v5.1_ESP32.sln
new file mode 100644
index 000000000..1396c1884
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/VisualGDB/wolfssh_template_IDF_v5.1_ESP32.sln
@@ -0,0 +1,54 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.6.33829.357
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{803FD0C6-D64E-4E16-9DC3-1DAEC859A3D2}") = "wolfssh_template_IDF_v5.1_ESP32", "wolfssh_template_IDF_v5.1_ESP32.vgdbproj", "{EADCC9AB-72B3-4B51-A838-593E5D80DDF7}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F0564364-33CD-468B-8514-D6A907B2449C}"
+ ProjectSection(SolutionItems) = preProject
+ ..\README.md = ..\README.md
+ ..\..\..\setup.sh = ..\..\..\setup.sh
+ ..\..\..\setup_win.bat = ..\..\..\setup_win.bat
+ ..\..\wolfssl_monitor.py = ..\..\wolfssl_monitor.py
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wolfssh", "wolfssh", "{A9456F78-BEB7-4057-8015-E5A63CB41D44}"
+ ProjectSection(SolutionItems) = preProject
+ ..\components\wolfssh\CMakeLists.txt = ..\components\wolfssh\CMakeLists.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wolfssl", "wolfssl", "{530EF870-BCA9-4320-AD27-1D8FC6B3770C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "include", "include", "{C3B90A14-D318-4828-BDD3-A5D018C032F5}"
+ ProjectSection(SolutionItems) = preProject
+ ..\components\wolfssl\include\user_settings.h = ..\components\wolfssl\include\user_settings.h
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|VisualGDB = Debug|VisualGDB
+ Release|VisualGDB = Release|VisualGDB
+ Tests (Debug)|VisualGDB = Tests (Debug)|VisualGDB
+ Tests (Release)|VisualGDB = Tests (Release)|VisualGDB
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Debug|VisualGDB.ActiveCfg = Debug|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Debug|VisualGDB.Build.0 = Debug|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Release|VisualGDB.ActiveCfg = Release|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Release|VisualGDB.Build.0 = Release|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Debug)|VisualGDB.ActiveCfg = Tests (Debug)|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Debug)|VisualGDB.Build.0 = Tests (Debug)|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Release)|VisualGDB.ActiveCfg = Tests (Release)|VisualGDB
+ {EADCC9AB-72B3-4B51-A838-593E5D80DDF7}.Tests (Release)|VisualGDB.Build.0 = Tests (Release)|VisualGDB
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C3B90A14-D318-4828-BDD3-A5D018C032F5} = {530EF870-BCA9-4320-AD27-1D8FC6B3770C}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {68907C18-A199-469F-8856-F03632FDA03E}
+ EndGlobalSection
+EndGlobal
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/VisualGDB/wolfssh_template_IDF_v5.1_ESP32.vgdbproj b/ide/Espressif/ESP-IDF/examples/wolfssh_template/VisualGDB/wolfssh_template_IDF_v5.1_ESP32.vgdbproj
new file mode 100644
index 000000000..9edbb41e2
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/VisualGDB/wolfssh_template_IDF_v5.1_ESP32.vgdbproj
@@ -0,0 +1,269 @@
+
+
+
+
+
+ Unknown
+
+ true
+
+ 7bbd1486-d457-4e49-92ba-0cfc9d80849e
+ true
+ true
+ SourceDirs
+
+
+
+
+
+ com.visualgdb.xtensa-esp32-elf
+
+ 12.2.0
+ 12.1
+ 1
+
+
+ ..
+ DEBUG
+ build/$(PlatformName)/$(ConfigurationName)
+
+ false
+ $(ToolchainNinja)
+ $(BuildDir)
+
+
+
+ false
+ $(SYSPROGS_CMAKE_PATH)
+
+
+ true
+ false
+ false
+ Ninja
+ false
+ RemoveBuildDirectory
+ false
+
+
+ true
+ true
+ true
+ false
+ true
+ false
+ true
+ HideOuterProjectTargets
+ true
+ false
+ true
+
+
+ true
+ eadcc9ab-72b3-4b51-a838-593e5d80ddf7
+
+ Upper
+ HeaderDirectoryAndSubdirectories
+ true
+
+
+ release/v5.1
+ esp-idf/v5.1
+ ESPIDF
+
+ COM9
+ false
+ false
+ ESP32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+ COM9
+
+ 115200
+ 8
+ None
+ One
+ None
+
+
+ 0
+ false
+ false
+ false
+ ASCII
+
+
+ 255
+ 0
+ 0
+ 0
+
+
+ 255
+ 169
+ 169
+ 169
+
+
+ 255
+ 211
+ 211
+ 211
+
+
+ 255
+ 144
+ 238
+ 144
+
+
+ 255
+ 169
+ 169
+ 169
+
+
+
+ 16
+ true
+ true
+ true
+ true
+ 0
+
+ LF
+ false
+ false
+ false
+
+
+
+ true
+
+
+
+
+ Unknown
+
+ true
+ true
+ true
+
+
+
+ false
+
+
+
+
+ Debug
+
+
+
+ Release
+
+
+
+
+
+
+
+
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+ false
+ false
+ false
+ false
+ false
+ false
+ true
+ false
+ None
+ false
+ false
+ app_main
+ true
+ false
+ false
+ true
+ 0
+ false
+ 0
+ true
+ false
+
+
+ openocd
+
+ -f interface/ftdi/tigard.cfg -c "adapter_khz 15000" -f target/esp32.cfg
+
+
+
+ false
+
+ 131072
+ Enabled
+
+ set remotetimeout 60
+ target remote :$$SYS:GDB_PORT$$
+ mon gdb_breakpoint_override hard
+ mon reset halt
+ load
+
+ false
+ 0
+ 0
+ false
+
+ 5000
+ 1
+ true
+
+ size2MB
+ freq40M
+ DIO
+
+ true
+
+
+ true
+ Disabled
+ 0
+ false
+ false
+ true
+ false
+ false
+
+ _estack
+ 0
+ false
+
+ true
+
+
\ No newline at end of file
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssh/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssh/CMakeLists.txt
new file mode 100644
index 000000000..0bdf01e5d
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssh/CMakeLists.txt
@@ -0,0 +1,456 @@
+#
+# Copyright (C) 2006-2023 WOLFSSL Inc.
+#
+# This file is part of WOLFSSH.
+#
+# WOLFSSH is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# WOLFSSH is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+#
+# cmake for WOLFSSH Espressif projects
+#
+# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html
+#
+
+cmake_minimum_required(VERSION 3.16)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSH_USER_SETTINGS")
+set(CMAKE_CURRENT_SOURCE_DIR ".")
+set(COMPONENT_REQUIRES lwip wolfssl)
+
+# COMPONENT_NAME = wolfssh
+# The component name is the directory name. "No feature to change this".
+# See https://github.com/espressif/esp-idf/issues/8978#issuecomment-1129892685
+
+# set the root of WOLFSSH in top-level project CMakelists.txt:
+# set(WOLFSSH_ROOT "C:/some path/with/spaces")
+# set(WOLFSSH_ROOT "c:/workspace/WOLFSSH-[username]")
+# set(WOLFSSH_ROOT "/mnt/c/some path/with/spaces")
+# or use this logic to assign value from Environment Variable WOLFSSH_ROOT,
+# or assume this is an example 7 subdirectories below:
+
+# We are typically in [root]/IDE/Espressif/ESP-IDF/examples/WOLFSSH_test/components/WOLFSSH
+# The root of WOLFSSH is 7 directories up from here:
+
+if(CMAKE_BUILD_EARLY_EXPANSION)
+ message(STATUS "WOLFSSH component CMAKE_BUILD_EARLY_EXPANSION:")
+ idf_component_register(
+ REQUIRES "${COMPONENT_REQUIRES}"
+ PRIV_REQUIRES esp_timer driver wolfssl # this will typically only be needed for WOLFSSH benchmark
+ )
+
+else()
+ # not CMAKE_BUILD_EARLY_EXPANSION
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssh component config:")
+ message(STATUS "************************************************************************************************")
+
+ # Check to see if we're already in WOLFSSH, and only if WOLFSSH_ROOT not specified
+ if ("${WOLFSSH_ROOT}" STREQUAL "")
+ # WOLFSSH examples are 7 directories deep from WOLFSSH repo root
+ # 1 2 3 4 5 6 7
+ set(THIS_RELATIVE_PATH "../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching in path = ${THIS_SEARCH_PATH}")
+
+ if (EXISTS "${THIS_SEARCH_PATH}/wolfcrypt/src")
+ # we're already in WOLFSSH examples!
+ get_filename_component(WOLFSSH_ROOT "${THIS_SEARCH_PATH}" ABSOLUTE)
+ message(STATUS "Using WOLFSSH example with root ${WOLFSSH_ROOT}")
+ else()
+ # We're in some other repo such as wolfssh, so we'll search for an
+ # adjacent-level directory for WOLFSSH. (8 directories up, then down one)
+ #
+ # For example WOLFSSH examples:
+ # C:\workspace\WOLFSSH-gojimmypi\IDE\Espressif\ESP-IDF\examples\WOLFSSH_benchmark\components\WOLFSSH
+ #
+ # For example wolfSSH examples:
+ # C:\workspace\wolfssh-gojimmypi\ide\Espressif\ESP-IDF\examples\wolfssh_benchmark\components\WOLFSSH
+ #
+ # 1 2 3 4 5 6 7 8
+ set(THIS_RELATIVE_PATH "../../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching next in path = ${THIS_SEARCH_PATH}")
+ endif()
+ endif()
+
+ # search other possible locations
+ if ("${WOLFSSH_ROOT}" STREQUAL "")
+ # there's not a hard-coded WOLFSSH_ROOT value above, so let's see if we can find it.
+ if( "$ENV{WOLFSSH_ROOT}" STREQUAL "" )
+ message(STATUS "Environment Variable WOLFSSH_ROOT not set. Will search common locations.")
+
+ message(STATUS "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
+ get_filename_component(THIS_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
+ message(STATUS "THIS_DIR = ${THIS_DIR}")
+
+ # find the user name to search for possible "WOLFSSH-username"
+ message(STATUS "USERNAME = $ENV{USERNAME}")
+ if( "$ENV{USER}" STREQUAL "" ) # the bash user
+ if( "$ENV{USERNAME}" STREQUAL "" ) # the Windows user
+ message(STATUS "could not find USER or USERNAME")
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USERNAME}")
+ endif()
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USER}")
+ endif()
+ message(STATUS "THIS_USER = ${THIS_USER}")
+
+ # This same makefile is used for both the WOLFSSH component, and other
+ # components that may depend on WOLFSSH, such as wolfssh. Therefore
+ # we need to determine if this makefile is in the WOLFSSH repo, or
+ # some other repo.
+
+ if( "{THIS_USER}" STREQUAL "" )
+ # This is highly unusual to not find a user name.
+ # In this case, we'll just search for a "WOLFSSH" directory:
+ message(STATUS "No username found!")
+ get_filename_component(WOLFSSH_ROOT "${THIS_RELATIVE_PATH}/WOLFSSH" ABSOLUTE)
+ else()
+ # We found an environment USER name!
+ # The first place to look for WOLFSSH will be in a user-clone called "WOLFSSH-[username]"
+ message(STATUS "Using [THIS_USER = ${THIS_USER}] to see if there's a [relative path]/WOLFSSH-${THIS_USER} directory.")
+ get_filename_component(WOLFSSH_ROOT "${THIS_RELATIVE_PATH}/WOLFSSH-${THIS_USER}" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ message(STATUS "Found WOLFSSH in user-suffix ${WOLFSSH_ROOT}")
+ else()
+ # If there's not a user-clone called "WOLFSSH-[username]",
+ # perhaps there's simply a git clone called "WOLFSSH"?
+ message(STATUS "Did not find WOLFSSH-${THIS_USER}; continuing search...")
+ get_filename_component(WOLFSSH_ROOT "${THIS_RELATIVE_PATH}/WOLFSSH" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ message(STATUS "Found WOLFSSH in standard ${WOLFSSH_ROOT}")
+ else()
+ # Things are looking pretty bleak. We'll likely not be able to compile.
+ message(STATUS "Did not find WOLFSSH in ${WOLFSSH_ROOT}")
+ endif()
+ endif()
+ endif()
+
+ else()
+ # there's an environment variable, so use it.
+ set(WOLFSSH_ROOT "$ENV{WOLFSSH_ROOT}")
+
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ get_filename_component(WOLFSSH_ROOT "$ENV{WOLFSSH_ROOT}" ABSOLUTE)
+ message(STATUS "Found WOLFSSH_ROOT via Environment Variable:")
+ else()
+ message(FATAL_ERROR "WOLFSSH_ROOT Environment Variable defined, but path not found:")
+ message(STATUS "$ENV{WOLFSSH_ROOT}")
+ endif()
+ endif()
+ # end of search for WOLFSSH component root
+ else()
+ # There's already a value assigned; we won't search for anything else.
+ message(STATUS "Found user-specified WOLFSSH_ROOT value.")
+ endif() # WOLFSSH_ROOT user defined
+
+ # After all the logic above, does our WOLFSSH_ROOT actually exist?
+ if( EXISTS "${WOLFSSH_ROOT}" )
+ message(STATUS "WOLFSSH_ROOT = ${WOLFSSH_ROOT}")
+ else()
+ # Abort. We need WOLFSSH _somewhere_.
+ message(FATAL_ERROR "Could not find WOLFSSH in ${WOLFSSH_ROOT}. Try setting environment variable or git clone.")
+ endif()
+
+
+ set(INCLUDE_PATH ${WOLFSSH_ROOT})
+
+ set(COMPONENT_SRCDIRS
+ "\"${WOLFSSH_ROOT}/src/\""
+ ) # COMPONENT_SRCDIRS
+ message(STATUS "This COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+
+ set(WOLFSSH_PROJECT_DIR "${CMAKE_HOME_DIRECTORY}/components/wolfssh")
+
+ # Espressif may take several passes through this makefile. Check to see if we found IDF
+ string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "" WOLFSSH_FOUND_IDF)
+
+ message(STATUS "IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
+ message(STATUS "EXCLUDE_ASM = ${EXCLUDE_ASM}")
+
+ #
+ # Check to see if there's both a local copy and EDP-IDF copy of the WOLFSSH and/or wolfssh components.
+ #
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/WOLFSSH/" )
+ #
+ # WOLFSSH found in both ESP-IDF and local project - needs to be resolved by user
+ #
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+ message(STATUS "Error: Found components/WOLFSSH in both local project and IDF_PATH")
+ message(STATUS "")
+ message(STATUS "To proceed: ")
+ message(STATUS "")
+ message(STATUS "Remove either the local project component: ${WOLFSSH_PROJECT_DIR} ")
+ message(STATUS "or the Espressif shared component installed at: $ENV{IDF_PATH}/components/WOLFSSH/ ")
+ message(STATUS "")
+ message(FATAL_ERROR "Please use WOLFSSH in either local project or Espressif components, but not both.")
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+
+ # Optional: if you change the above FATAL_ERROR to STATUS you can warn at runtime with this macro definition:
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSH_MULTI_INSTALL_WARNING")
+
+ else()
+ if( EXISTS "$ENV{IDF_PATH}/components/WOLFSSH/" )
+ #
+ # WOLFSSH found in ESP-IDF components and is assumed to be already configured in user_settings.h via setup.
+ #
+ message(STATUS "")
+ message(STATUS "Using components/WOLFSSH in IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "")
+ else()
+ #
+ # WOLFSSH is not an ESP-IDF component.
+ # We need to now determine if it is local and if so if it is part of the WOLFSSH repo,
+ # or if WOLFSSH is simply installed as a local component.
+ #
+
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}" )
+ #
+ # WOLFSSH found in local project.
+ #
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}/wolfcrypt/" )
+ message(STATUS "")
+ message(STATUS "Using installed project ./components/WOLFSSH in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+ #
+ # Note we already checked above and confirmed there's not another WOLFSSH installed in the ESP-IDF components.
+ #
+ # We won't do anything else here, as it will be assumed the original install completed successfully.
+ #
+ else() # full WOLFSSH not installed in local project
+ #
+ # This is the developer repo mode. WOLFSSH will be assumed to be not installed to ESP-IDF nor local project
+ # In this configuration, we are likely running a WOLFSSH example found directly in the repo.
+ #
+ message(STATUS "")
+ message(STATUS "Using developer repo ./components/WOLFSSH in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+
+ message(STATUS "************************************************************************************************")
+ # When in developer mode, we are typically running WOLFSSH examples such as benchmark or test directories.
+ # However, the as-cloned or distributed WOLFSSH does not have the ./include/ directory, so we'll add it as needed.
+ #
+ # first check if there's a [root]/include/user_settings.h
+ if( EXISTS "${WOLFSSH_ROOT}/include/user_settings.h" )
+ message(FATAL_ERROR "Found stray WOLFSSH user_settings.h in "
+ "${WOLFSSH_ROOT}/include/user_settings.h "
+ " (please move it to ${WOLFSSH_PROJECT_DIR}/include/user_settings.h )")
+ else()
+ # we won't overwrite an existing user settings file, just note that we already have one:
+ if( EXISTS "${WOLFSSH_PROJECT_DIR}/include/user_settings.h" )
+ message(STATUS "Using existing WOLFSSH user_settings.h in "
+ "${WOLFSSH_PROJECT_DIR}/include/user_settings.h")
+ else()
+ message(STATUS "Installing WOLFSSH user_settings.h to "
+ "${WOLFSSH_PROJECT_DIR}/include/user_settings.h")
+ # file(COPY "${WOLFSSH_ROOT}/IDE/Espressif/ESP-IDF/user_settings.h"
+ # DESTINATION "${CMAKE_HOME_DIRECTORY}/WOLFSSH/include/")
+ endif()
+ endif() # user_settings.h
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "")
+ endif()
+
+ else()
+ # we did not find a ./components/WOLFSSH/include/ directory from this pass of cmake.
+ if($WOLFSSH_FOUND_IDF)
+ message(STATUS "")
+ message(STATUS "WARNING: WOLFSSH not found.")
+ message(STATUS "")
+ else()
+ # probably needs to be re-parsed by Espressif
+ message(STATUS "WOLFSSH found IDF. Project Source:${PROJECT_SOURCE_DIR}")
+ endif() # else we have not found ESP-IDF yet
+ endif() # else not a local WOLFSSH component
+
+ endif() #else not an ESP-IDF component
+ endif() # else not local copy and EDP-IDF WOLFSSH
+
+
+ # RTOS_IDF_PATH is typically:
+ # "/Users/{username}/Desktop/esp-idf/components/freertos/include/freertos"
+ # depending on the environment, we may need to swap backslashes with forward slashes
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos")
+
+ string(REPLACE "\\" "/" WOLFSSH_ROOT ${WOLFSSH_ROOT})
+
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ # ESP-IDF prior version 4.4x has a different RTOS directory structure
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/include/freertos")
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found legacy RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ message(STATUS "Could not find RTOS path")
+ endif()
+ endif()
+
+
+ set(COMPONENT_ADD_INCLUDEDIRS
+ # "./include" # not used! See wolfSSL include/user_settings.h
+ "\"${WOLFSSH_ROOT}/\""
+ "\"${WOLFSSH_ROOT}/wolfssh/\""
+ "\"${RTOS_IDF_PATH}/\""
+ )
+
+
+ if(IS_DIRECTORY ${IDF_PATH}/components/cryptoauthlib)
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "../cryptoauthlib/lib")
+ endif()
+
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "\"${WOLFSSH_ROOT}/wolfssh/\"")
+
+
+
+ set(COMPONENT_SRCEXCLUDE
+ # wolfSSH
+ # TODO: we likely need to check #if !defined(WOLFSSH_MISC_INCLUDED) && !defined(NO_INLINE) && !defined(WOLFSSH_IGNORE_FILE_WARN)
+ # here in cmake if we actually want to always exclude wolfssh misc.c file. (see source; ok for demo)
+ "\"${WOLFSSH_ROOT}/src/misc.c\"" # misc.c does not need to be compiled when using inline (NO_INLINE not defined))
+ )
+
+ spaces2list(COMPONENT_REQUIRES)
+
+ separate_arguments(COMPONENT_SRCDIRS NATIVE_COMMAND "${COMPONENT_SRCDIRS}")
+ separate_arguments(COMPONENT_SRCEXCLUDE NATIVE_COMMAND "${COMPONENT_SRCEXCLUDE}")
+ separate_arguments(COMPONENT_ADD_INCLUDEDIRS NATIVE_COMMAND "${COMPONENT_ADD_INCLUDEDIRS}")
+
+ #
+ # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#example-component-requirements
+ #
+ message(STATUS "COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+ message(STATUS "COMPONENT_ADD_INCLUDEDIRS = ${COMPONENT_ADD_INCLUDEDIRS}")
+ message(STATUS "COMPONENT_REQUIRES = ${COMPONENT_REQUIRES}")
+ message(STATUS "COMPONENT_SRCEXCLUDE = ${COMPONENT_SRCEXCLUDE}")
+
+ #
+ # see https://docs.espressif.com/projects/esp-idf/en/stable/esp32/migration-guides/release-5.x/build-system.html?highlight=space%20path
+ #
+ set(EXTRA_COMPONENT_DIRS "${COMPONENT_SRCDIRS}")
+ idf_component_register(
+ SRC_DIRS "${COMPONENT_SRCDIRS}"
+ INCLUDE_DIRS "${COMPONENT_ADD_INCLUDEDIRS}"
+ REQUIRES "${COMPONENT_REQUIRES}"
+ EXCLUDE_SRCS "${COMPONENT_SRCEXCLUDE}"
+ PRIV_REQUIRES esp_timer driver wolfssl # this will typically only be needed for WOLFSSH benchmark
+ )
+ # some optional diagnostics
+ if (1)
+ get_cmake_property(_variableNames VARIABLES)
+ list (SORT _variableNames)
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES BEGIN")
+ message(STATUS "")
+ foreach (_variableName ${_variableNames})
+ message(STATUS "${_variableName}=${${_variableName}}")
+ endforeach()
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES END")
+ message(STATUS "")
+ endif()
+
+ # target_sources(WOLFSSH PRIVATE "\"${WOLFSSH_ROOT}/WOLFSSH/\"" "\"${WOLFSSH_ROOT}/WOLFSSH/wolfcrypt\"")
+endif() # CMAKE_BUILD_EARLY_EXPANSION
+
+
+
+# check to see if there's both a local copy and EDP-IDF copy of the WOLFSSH components
+if( EXISTS "${WOLFSSH_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/WOLFSSH/" )
+ message(STATUS "")
+ message(STATUS "")
+ message(STATUS "********************************************************************")
+ message(STATUS "WARNING: Found components/WOLFSSH in both local project and IDF_PATH")
+ message(STATUS "********************************************************************")
+ message(STATUS "")
+endif()
+# end multiple component check
+
+
+#
+# LIBWOLFSSH_SAVE_INFO(VAR_OUPUT THIS_VAR VAR_RESULT)
+#
+# Save the THIS_VAR as a string in a macro called VAR_OUPUT
+#
+# VAR_OUPUT: the name of the macro to define
+# THIS_VAR: the OUTPUT_VARIABLE result from a execute_process()
+# VAR_RESULT: the RESULT_VARIABLE from a execute_process(); "0" if successful.
+#
+function ( LIBWOLFSSH_SAVE_INFO VAR_OUPUT THIS_VAR VAR_RESULT )
+ # is the RESULT_VARIABLE output value 0? If so, IS_VALID_VALUE is true.
+ string(COMPARE EQUAL "${VAR_RESULT}" "0" IS_VALID_VALUE)
+
+ # if we had a successful operation, save the THIS_VAR in VAR_OUPUT
+ if(${IS_VALID_VALUE})
+ # strip newline chars in THIS_VAR parameter and save in VAR_VALUE
+ string(REPLACE "\n" "" VAR_VALUE ${THIS_VAR})
+
+ # we'll could percolate the value to the parent for possible later use
+ # set(${VAR_OUPUT} ${VAR_VALUE} PARENT_SCOPE)
+
+ # but we're only using it here in this function
+ set(${VAR_OUPUT} ${VAR_VALUE})
+
+ # we'll print what we found to the console
+ message(STATUS "Found ${VAR_OUPUT}=${VAR_VALUE}")
+
+ # the interesting part is defining the VAR_OUPUT name a value to use in the app
+ add_definitions(-D${VAR_OUPUT}=\"${VAR_VALUE}\")
+ else()
+ # if we get here, check the execute_process command and parameters.
+ message(STATUS "LIBWOLFSSH_SAVE_INFO encountered a non-zero VAR_RESULT")
+ set(${VAR_OUPUT} "Unknown")
+ endif()
+endfunction() # LIBWOLFSSH_SAVE_INFO
+
+# create some programmatic #define values that will be used by ShowExtendedSystemInfo().
+# see wolfcrypt\src\port\Espressif\esp32_utl.c
+if(NOT CMAKE_BUILD_EARLY_EXPANSION)
+ set (git_cmd "git")
+ message(STATUS "Adding macro definitions:")
+
+ # LIBWOLFSSH_VERSION_GIT_ORIGIN: git config --get remote.origin.url
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "config" "--get" "remote.origin.url" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_ORIGIN "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_BRANCH: git rev-parse --abbrev-ref HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "rev-parse" "--abbrev-ref" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_BRANCH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_HASH: git rev-parse HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "rev-parse" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_SHORT_HASH: git rev-parse --short HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "rev-parse" "--short" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_SHORT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSH_VERSION_GIT_HASH_DATE git show --no-patch --no-notes --pretty=\'\%cd\'
+ execute_process(WORKING_DIRECTORY ${WOLFSSH_ROOT} COMMAND ${git_cmd} "show" "--no-patch" "--no-notes" "--pretty=\'\%cd\'" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES )
+ LIBWOLFSSH_SAVE_INFO(LIBWOLFSSH_VERSION_GIT_HASH_DATE "${TMP_OUT}" "${TMP_RES}")
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "WOLFSSH component config complete!")
+ message(STATUS "************************************************************************************************")
+endif()
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssl/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssl/CMakeLists.txt
new file mode 100644
index 000000000..7f482a4f8
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssl/CMakeLists.txt
@@ -0,0 +1,488 @@
+#
+# Copyright (C) 2006-2023 wolfSSL Inc.
+#
+# This file is part of wolfSSL.
+#
+# wolfSSL is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# wolfSSL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+#
+# cmake for wolfssl Espressif projects
+#
+# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html
+#
+
+cmake_minimum_required(VERSION 3.16)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
+set(CMAKE_CURRENT_SOURCE_DIR ".")
+set(COMPONENT_REQUIRES lwip) # we typically don't need lwip directly in wolfssl component
+
+# COMPONENT_NAME = wolfssl
+# The component name is the directory name. "No feature to change this".
+# See https://github.com/espressif/esp-idf/issues/8978#issuecomment-1129892685
+
+# set the root of wolfSSL in top-level project CMakelists.txt:
+# set(WOLFSSL_ROOT "C:/some path/with/spaces")
+# set(WOLFSSL_ROOT "c:/workspace/wolfssl-[username]")
+# set(WOLFSSL_ROOT "/mnt/c/some path/with/spaces")
+# or use this logic to assign value from Environment Variable WOLFSSL_ROOT,
+# or assume this is an example 7 subdirectories below:
+
+# We are typically in [root]/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl
+# The root of wolfSSL is 7 directories up from here:
+
+if(CMAKE_BUILD_EARLY_EXPANSION)
+ message(STATUS "wolfssl component CMAKE_BUILD_EARLY_EXPANSION:")
+ idf_component_register(
+ REQUIRES "${COMPONENT_REQUIRES}"
+ PRIV_REQUIRES esp_timer driver # this will typically only be needed for wolfSSL benchmark
+ )
+
+else()
+ # not CMAKE_BUILD_EARLY_EXPANSION
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssl component config:")
+ message(STATUS "************************************************************************************************")
+
+ # Check to see if we're already in wolfssl, and only if WOLFSSL_ROOT not specified
+ if ("${WOLFSSL_ROOT}" STREQUAL "")
+ # wolfssl examples are 7 directories deep from wolfssl repo root
+ # 1 2 3 4 5 6 7
+ set(THIS_RELATIVE_PATH "../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching in path = ${THIS_SEARCH_PATH}")
+
+ if (EXISTS "${THIS_SEARCH_PATH}/wolfcrypt/src")
+ # we're already in wolfssl examples!
+ get_filename_component(WOLFSSL_ROOT "${THIS_SEARCH_PATH}" ABSOLUTE)
+ message(STATUS "Using wolfSSL example with root ${WOLFSSL_ROOT}")
+ else()
+ # We're in some other repo such as wolfssh, so we'll search for an
+ # adjacent-level directory for wolfssl. (8 directories up, then down one)
+ #
+ # For example wolfSSL examples:
+ # C:\workspace\wolfssl-gojimmypi\IDE\Espressif\ESP-IDF\examples\wolfssl_benchmark\components\wolfssl
+ #
+ # For example wolfSSH examples:
+ # C:\workspace\wolfssh-gojimmypi\ide\Espressif\ESP-IDF\examples\wolfssh_benchmark\components\wolfssl
+ #
+ # 1 2 3 4 5 6 7 8
+ set(THIS_RELATIVE_PATH "../../../../../../../..")
+ get_filename_component(THIS_SEARCH_PATH "${THIS_RELATIVE_PATH}" ABSOLUTE)
+ message(STATUS "Searching next in path = ${THIS_SEARCH_PATH}")
+ endif()
+ endif()
+
+ # search other possible locations
+ if ("${WOLFSSL_ROOT}" STREQUAL "")
+ # there's not a hard-coded WOLFSSL_ROOT value above, so let's see if we can find it.
+ if( "$ENV{WOLFSSL_ROOT}" STREQUAL "" )
+ message(STATUS "Environment Variable WOLFSSL_ROOT not set. Will search common locations.")
+
+ message(STATUS "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
+ get_filename_component(THIS_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
+ message(STATUS "THIS_DIR = ${THIS_DIR}")
+
+ # find the user name to search for possible "wolfssl-username"
+ message(STATUS "USERNAME = $ENV{USERNAME}")
+ if( "$ENV{USER}" STREQUAL "" ) # the bash user
+ if( "$ENV{USERNAME}" STREQUAL "" ) # the Windows user
+ message(STATUS "could not find USER or USERNAME")
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USERNAME}")
+ endif()
+ else()
+ # the bash user is not blank, so we'll use it.
+ set(THIS_USER "$ENV{USER}")
+ endif()
+ message(STATUS "THIS_USER = ${THIS_USER}")
+
+ # This same makefile is used for both the wolfssl component, and other
+ # components that may depend on wolfssl, such as wolfssh. Therefore
+ # we need to determine if this makefile is in the wolfssl repo, or
+ # some other repo.
+
+ if( "{THIS_USER}" STREQUAL "" )
+ # This is highly unusual to not find a user name.
+ # In this case, we'll just search for a "wolfssl" directory:
+ message(STATUS "No username found!")
+ get_filename_component(WOLFSSL_ROOT "${THIS_RELATIVE_PATH}/wolfssl" ABSOLUTE)
+ else()
+ # We found an environment USER name!
+ # The first place to look for wolfssl will be in a user-clone called "wolfssl-[username]"
+ message(STATUS "Using [THIS_USER = ${THIS_USER}] to see if there's a [relative path]/wolfssl-${THIS_USER} directory.")
+ get_filename_component(WOLFSSL_ROOT "${THIS_RELATIVE_PATH}/wolfssl-${THIS_USER}" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ message(STATUS "Found wolfssl in user-suffix ${WOLFSSL_ROOT}")
+ else()
+ # If there's not a user-clone called "wolfssl-[username]",
+ # perhaps there's simply a git clone called "wolfssl"?
+ message(STATUS "Did not find wolfssl-${THIS_USER}; continuing search...")
+ get_filename_component(WOLFSSL_ROOT "${THIS_RELATIVE_PATH}/wolfssl" ABSOLUTE)
+
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ message(STATUS "Found wolfssl in standard ${WOLFSSL_ROOT}")
+ else()
+ # Things are looking pretty bleak. We'll likely not be able to compile.
+ message(STATUS "Did not find wolfssl in ${WOLFSSL_ROOT}")
+ endif()
+ endif()
+ endif()
+
+ else()
+ # there's an environment variable, so use it.
+ set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}")
+
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ get_filename_component(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" ABSOLUTE)
+ message(STATUS "Found WOLFSSL_ROOT via Environment Variable:")
+ else()
+ message(FATAL_ERROR "WOLFSSL_ROOT Environment Variable defined, but path not found:")
+ message(STATUS "$ENV{WOLFSSL_ROOT}")
+ endif()
+ endif()
+ # end of search for wolfssl component root
+ else()
+ # There's already a value assigned; we won't search for anything else.
+ message(STATUS "Found user-specified WOLFSSL_ROOT value.")
+ endif() # WOLFSSL_ROOT user defined
+
+ # After all the logic above, does our WOLFSSL_ROOT actually exist?
+ if( EXISTS "${WOLFSSL_ROOT}" )
+ message(STATUS "WOLFSSL_ROOT = ${WOLFSSL_ROOT}")
+ else()
+ # Abort. We need wolfssl _somewhere_.
+ message(FATAL_ERROR "Could not find wolfssl in ${WOLFSSL_ROOT}. Try setting environment variable or git clone.")
+ endif()
+
+
+ set(INCLUDE_PATH ${WOLFSSL_ROOT})
+
+ set(COMPONENT_SRCDIRS "\"${WOLFSSL_ROOT}/src/\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/port/atmel\""
+ # "\"${WOLFSSL_ROOT}/wolfcrypt/benchmark\"" # the benchmark application
+ # "\"${WOLFSSL_ROOT}/wolfcrypt/test\"" # the test application
+ ) # COMPONENT_SRCDIRS
+ message(STATUS "This COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+
+ set(WOLFSSL_PROJECT_DIR "${CMAKE_HOME_DIRECTORY}/components/wolfssl")
+
+ # Espressif may take several passes through this makefile. Check to see if we found IDF
+ string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "" WOLFSSL_FOUND_IDF)
+
+ # get a list of all wolfcrypt assembly files; we'll exclude them as they don't target Xtensa
+ file(GLOB EXCLUDE_ASM *.S)
+ file(GLOB_RECURSE EXCLUDE_ASM ${CMAKE_SOURCE_DIR} "${WOLFSSL_ROOT}/wolfcrypt/src/*.S")
+
+ message(STATUS "IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
+ message(STATUS "EXCLUDE_ASM = ${EXCLUDE_ASM}")
+
+ #
+ # Check to see if there's both a local copy and EDP-IDF copy of the wolfssl and/or wolfssh components.
+ #
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ #
+ # wolfSSL found in both ESP-IDF and local project - needs to be resolved by user
+ #
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+ message(STATUS "Error: Found components/wolfssl in both local project and IDF_PATH")
+ message(STATUS "")
+ message(STATUS "To proceed: ")
+ message(STATUS "")
+ message(STATUS "Remove either the local project component: ${WOLFSSL_PROJECT_DIR} ")
+ message(STATUS "or the Espressif shared component installed at: $ENV{IDF_PATH}/components/wolfssl/ ")
+ message(STATUS "")
+ message(FATAL_ERROR "Please use wolfSSL in either local project or Espressif components, but not both.")
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+
+ # Optional: if you change the above FATAL_ERROR to STATUS you can warn at runtime with this macro definition:
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_MULTI_INSTALL_WARNING")
+
+ else()
+ if( EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ #
+ # wolfSSL found in ESP-IDF components and is assumed to be already configured in user_settings.h via setup.
+ #
+ message(STATUS "")
+ message(STATUS "Using components/wolfssl in IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "")
+ else()
+ #
+ # wolfSSL is not an ESP-IDF component.
+ # We need to now determine if it is local and if so if it is part of the wolfSSL repo,
+ # or if wolfSSL is simply installed as a local component.
+ #
+
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}" )
+ #
+ # wolfSSL found in local project.
+ #
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}/wolfcrypt/" )
+ message(STATUS "")
+ message(STATUS "Using installed project ./components/wolfssl in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+ #
+ # Note we already checked above and confirmed there's not another wolfSSL installed in the ESP-IDF components.
+ #
+ # We won't do anything else here, as it will be assumed the original install completed successfully.
+ #
+ else() # full wolfSSL not installed in local project
+ #
+ # This is the developer repo mode. wolfSSL will be assumed to be not installed to ESP-IDF nor local project
+ # In this configuration, we are likely running a wolfSSL example found directly in the repo.
+ #
+ message(STATUS "")
+ message(STATUS "Using developer repo ./components/wolfssl in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+
+ message(STATUS "************************************************************************************************")
+ # When in developer mode, we are typically running wolfSSL examples such as benchmark or test directories.
+ # However, the as-cloned or distributed wolfSSL does not have the ./include/ directory, so we'll add it as needed.
+ #
+ # first check if there's a [root]/include/user_settings.h
+ if( EXISTS "${WOLFSSL_ROOT}/include/user_settings.h" )
+ message(FATAL_ERROR "Found stray wolfSSL user_settings.h in "
+ "${WOLFSSL_ROOT}/include/user_settings.h "
+ " (please move it to ${WOLFSSL_PROJECT_DIR}/include/user_settings.h )")
+ else()
+ # we won't overwrite an existing user settings file, just note that we already have one:
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}/include/user_settings.h" )
+ message(STATUS "Using existing wolfSSL user_settings.h in "
+ "${WOLFSSL_PROJECT_DIR}/include/user_settings.h")
+ else()
+ message(STATUS "Installing wolfSSL user_settings.h to "
+ "${WOLFSSL_PROJECT_DIR}/include/user_settings.h")
+ file(COPY "${WOLFSSL_ROOT}/IDE/Espressif/ESP-IDF/user_settings.h"
+ DESTINATION "${CMAKE_HOME_DIRECTORY}/wolfssl/include/")
+ endif()
+ endif() # user_settings.h
+
+ # next check if there's a [root]/include/config.h
+ if( EXISTS "${WOLFSSL_ROOT}/include/config.h" )
+ message(FATAL_ERROR "Found stray wolfSSL config.h in ${WOLFSSL_ROOT}/include/config.h (please move it to ${WOLFSSL_PROJECT_DIR}/include/config.h")
+ else()
+ # we won't overwrite an existing user settings file, just note that we already have one:
+ if( EXISTS "${WOLFSSL_PROJECT_DIR}/include/config.h" )
+ message(STATUS "Using existing wolfSSL config.h ${WOLFSSL_PROJECT_DIR}/include/config.h")
+ else()
+ message(STATUS "Installing wolfSSL config.h to ${WOLFSSL_PROJECT_DIR}/include/config.h")
+ file(COPY "${WOLFSSL_ROOT}/IDE/Espressif/ESP-IDF/dummy_config_h" DESTINATION "${WOLFSSL_PROJECT_DIR}/include/")
+ file(RENAME "${WOLFSSL_PROJECT_DIR}/include/dummy_config_h" "${WOLFSSL_PROJECT_DIR}/include/config.h")
+ endif() # Project config.h
+ endif() # WOLFSSL_ROOT config.h
+ message(STATUS "************************************************************************************************")
+ message(STATUS "")
+ endif()
+
+ else()
+ # we did not find a ./components/wolfssl/include/ directory from this pass of cmake.
+ if($WOLFSSL_FOUND_IDF)
+ message(STATUS "")
+ message(STATUS "WARNING: wolfSSL not found.")
+ message(STATUS "")
+ else()
+ # probably needs to be re-parsed by Espressif
+ message(STATUS "wolfSSL found IDF. Project Source:${PROJECT_SOURCE_DIR}")
+ endif() # else we have not found ESP-IDF yet
+ endif() # else not a local wolfSSL component
+
+ endif() #else not an ESP-IDF component
+ endif() # else not local copy and EDP-IDF wolfSSL
+
+
+ # RTOS_IDF_PATH is typically:
+ # "/Users/{username}/Desktop/esp-idf/components/freertos/include/freertos"
+ # depending on the environment, we may need to swap backslashes with forward slashes
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos")
+
+ string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT})
+
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ # ESP-IDF prior version 4.4x has a different RTOS directory structure
+ string(REPLACE "\\" "/" RTOS_IDF_PATH "$ENV{IDF_PATH}/components/freertos/include/freertos")
+ if(IS_DIRECTORY "${RTOS_IDF_PATH}")
+ message(STATUS "Found legacy RTOS path: ${RTOS_IDF_PATH}")
+ else()
+ message(STATUS "Could not find RTOS path")
+ endif()
+ endif()
+
+
+ set(COMPONENT_ADD_INCLUDEDIRS
+ "./include" # this is the location of wolfssl user_settings.h
+ "\"${WOLFSSL_ROOT}/\""
+ "\"${WOLFSSL_ROOT}/wolfssl/\""
+ "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt/\""
+ "\"${RTOS_IDF_PATH}/\""
+ )
+
+
+ if(IS_DIRECTORY ${IDF_PATH}/components/cryptoauthlib)
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "../cryptoauthlib/lib")
+ endif()
+
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "\"${WOLFSSL_ROOT}/wolfssl/\"")
+ list(APPEND COMPONENT_ADD_INCLUDEDIRS "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt/\"")
+
+
+
+ set(COMPONENT_SRCEXCLUDE
+ "\"${WOLFSSL_ROOT}/src/bio.c\""
+ "\"${WOLFSSL_ROOT}/src/conf.c\""
+ "\"${WOLFSSL_ROOT}/src/misc.c\""
+ "\"${WOLFSSL_ROOT}/src/pk.c\""
+ "\"${WOLFSSL_ROOT}/src/ssl_asn1.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_bn.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/x509.c\""
+ "\"${WOLFSSL_ROOT}/src/x509_str.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/evp.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/misc.c\""
+ "\"${EXCLUDE_ASM}\""
+ )
+
+ spaces2list(COMPONENT_REQUIRES)
+
+ separate_arguments(COMPONENT_SRCDIRS NATIVE_COMMAND "${COMPONENT_SRCDIRS}")
+ separate_arguments(COMPONENT_SRCEXCLUDE NATIVE_COMMAND "${COMPONENT_SRCEXCLUDE}")
+ separate_arguments(COMPONENT_ADD_INCLUDEDIRS NATIVE_COMMAND "${COMPONENT_ADD_INCLUDEDIRS}")
+
+ #
+ # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#example-component-requirements
+ #
+ message(STATUS "COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+ message(STATUS "COMPONENT_ADD_INCLUDEDIRS = ${COMPONENT_ADD_INCLUDEDIRS}")
+ message(STATUS "COMPONENT_REQUIRES = ${COMPONENT_REQUIRES}")
+ message(STATUS "COMPONENT_SRCEXCLUDE = ${COMPONENT_SRCEXCLUDE}")
+
+ #
+ # see https://docs.espressif.com/projects/esp-idf/en/stable/esp32/migration-guides/release-5.x/build-system.html?highlight=space%20path
+ #
+ set(EXTRA_COMPONENT_DIRS "${COMPONENT_SRCDIRS}")
+ idf_component_register(
+ SRC_DIRS "${COMPONENT_SRCDIRS}"
+ INCLUDE_DIRS "${COMPONENT_ADD_INCLUDEDIRS}"
+ REQUIRES "${COMPONENT_REQUIRES}"
+ EXCLUDE_SRCS "${COMPONENT_SRCEXCLUDE}"
+ PRIV_REQUIRES esp_timer driver # this will typically only be needed for wolfSSL benchmark
+ )
+ # some optional diagnostics
+ if (1)
+ get_cmake_property(_variableNames VARIABLES)
+ list (SORT _variableNames)
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES BEGIN")
+ message(STATUS "")
+ foreach (_variableName ${_variableNames})
+ message(STATUS "${_variableName}=${${_variableName}}")
+ endforeach()
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES END")
+ message(STATUS "")
+ endif()
+
+ # target_sources(wolfssl PRIVATE "\"${WOLFSSL_ROOT}/wolfssl/\"" "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt\"")
+endif() # CMAKE_BUILD_EARLY_EXPANSION
+
+
+
+# check to see if there's both a local copy and EDP-IDF copy of the wolfssl components
+if( EXISTS "${WOLFSSL_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ message(STATUS "")
+ message(STATUS "")
+ message(STATUS "********************************************************************")
+ message(STATUS "WARNING: Found components/wolfssl in both local project and IDF_PATH")
+ message(STATUS "********************************************************************")
+ message(STATUS "")
+endif()
+# end multiple component check
+
+
+#
+# LIBWOLFSSL_SAVE_INFO(VAR_OUPUT THIS_VAR VAR_RESULT)
+#
+# Save the THIS_VAR as a string in a macro called VAR_OUPUT
+#
+# VAR_OUPUT: the name of the macro to define
+# THIS_VAR: the OUTPUT_VARIABLE result from a execute_process()
+# VAR_RESULT: the RESULT_VARIABLE from a execute_process(); "0" if successful.
+#
+function ( LIBWOLFSSL_SAVE_INFO VAR_OUPUT THIS_VAR VAR_RESULT )
+ # is the RESULT_VARIABLE output value 0? If so, IS_VALID_VALUE is true.
+ string(COMPARE EQUAL "${VAR_RESULT}" "0" IS_VALID_VALUE)
+
+ # if we had a successful operation, save the THIS_VAR in VAR_OUPUT
+ if(${IS_VALID_VALUE})
+ # strip newline chars in THIS_VAR parameter and save in VAR_VALUE
+ string(REPLACE "\n" "" VAR_VALUE ${THIS_VAR})
+
+ # we'll could percolate the value to the parent for possible later use
+ # set(${VAR_OUPUT} ${VAR_VALUE} PARENT_SCOPE)
+
+ # but we're only using it here in this function
+ set(${VAR_OUPUT} ${VAR_VALUE})
+
+ # we'll print what we found to the console
+ message(STATUS "Found ${VAR_OUPUT}=${VAR_VALUE}")
+
+ # the interesting part is defining the VAR_OUPUT name a value to use in the app
+ add_definitions(-D${VAR_OUPUT}=\"${VAR_VALUE}\")
+ else()
+ # if we get here, check the execute_process command and parameters.
+ message(STATUS "LIBWOLFSSL_SAVE_INFO encountered a non-zero VAR_RESULT")
+ set(${VAR_OUPUT} "Unknown")
+ endif()
+endfunction() # LIBWOLFSSL_SAVE_INFO
+
+# create some programmatic #define values that will be used by ShowExtendedSystemInfo().
+# see wolfcrypt\src\port\Espressif\esp32_utl.c
+if(NOT CMAKE_BUILD_EARLY_EXPANSION)
+ set (git_cmd "git")
+ message(STATUS "Adding macro definitions:")
+
+ # LIBWOLFSSL_VERSION_GIT_ORIGIN: git config --get remote.origin.url
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "config" "--get" "remote.origin.url" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_ORIGIN "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_BRANCH: git rev-parse --abbrev-ref HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "rev-parse" "--abbrev-ref" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_BRANCH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_HASH: git rev-parse HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "rev-parse" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_SHORT_HASH: git rev-parse --short HEAD
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "rev-parse" "--short" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_SHORT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_HASH_DATE git show --no-patch --no-notes --pretty=\'\%cd\'
+ execute_process(WORKING_DIRECTORY ${WOLFSSL_ROOT} COMMAND ${git_cmd} "show" "--no-patch" "--no-notes" "--pretty=\'\%cd\'" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH_DATE "${TMP_OUT}" "${TMP_RES}")
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssl component config complete!")
+ message(STATUS "************************************************************************************************")
+endif()
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssl/include/user_settings.h b/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssl/include/user_settings.h
new file mode 100644
index 000000000..e08f666d8
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/components/wolfssl/include/user_settings.h
@@ -0,0 +1,261 @@
+/* user_settings.h
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#include /* essential to chip set detection */
+
+#undef WOLFSSL_ESPIDF
+#undef WOLFSSL_ESP32
+#undef WOLFSSL_ESPWROOM32SE
+#undef WOLFSSL_ESP32
+#undef WOLFSSL_ESP8266
+
+/* The Espressif sdkconfig will have chipset info.
+**
+** Possible values:
+**
+** CONFIG_IDF_TARGET_ESP32
+** CONFIG_IDF_TARGET_ESP32S2
+** CONFIG_IDF_TARGET_ESP32S3
+** CONFIG_IDF_TARGET_ESP32C3
+** CONFIG_IDF_TARGET_ESP32C6
+*/
+
+/* wolfSSH */
+#undef WOLFSSH_TERM /* may be defined in cmake for other examples */
+#define WOLFSSH_TERM
+#undef DEBUG_WOLFSSH /* may be defined in cmake for other examples */
+#define DEBUG_WOLFSSH
+
+#define WOLFSSL_ESPIDF
+
+/*
+ * choose ONE of these Espressif chips to define:
+ *
+ * WOLFSSL_ESP32
+ * WOLFSSL_ESPWROOM32SE
+ * WOLFSSL_ESP8266
+ */
+
+#define WOLFSSL_ESP32
+
+/* optionally turn off SHA512/224 SHA512/256 */
+/* #define WOLFSSL_NOSHA512_224 */
+/* #define WOLFSSL_NOSHA512_256 */
+
+#define BENCH_EMBEDDED
+#define USE_CERT_BUFFERS_2048
+
+/* TLS 1.3 */
+#define WOLFSSL_TLS13
+#define HAVE_TLS_EXTENSIONS
+#define WC_RSA_PSS
+#define HAVE_HKDF
+#define HAVE_AEAD
+#define HAVE_SUPPORTED_CURVES
+
+#define WOLFSSL_BENCHMARK_FIXED_UNITS_KB
+
+/* when you want to use SINGLE THREAD */
+#define SINGLE_THREADED
+
+#define NO_FILESYSTEM
+
+#define HAVE_AESGCM
+
+#define WOLFSSL_RIPEMD
+/* when you want to use SHA224 */
+/* #define WOLFSSL_SHA224 */
+
+#define NO_OLD_TLS
+
+/* when you want to use SHA384 */
+/* #define WOLFSSL_SHA384 */
+
+/* #define WOLFSSL_SHA3 */
+
+#define WOLFSSL_SHA512
+#define HAVE_ECC
+#define HAVE_CURVE25519
+#define CURVE25519_SMALL
+#define HAVE_ED25519
+
+/* when you want to use pkcs7 */
+/* #define HAVE_PKCS7 */
+
+#if defined(HAVE_PKCS7)
+ #define HAVE_AES_KEYWRAP
+ #define HAVE_X963_KDF
+ #define WOLFSSL_AES_DIRECT
+#endif
+
+/* when you want to use aes counter mode */
+/* #define WOLFSSL_AES_DIRECT */
+/* #define WOLFSSL_AES_COUNTER */
+
+/* esp32-wroom-32se specific definition */
+#if defined(WOLFSSL_ESPWROOM32SE)
+ #define WOLFSSL_ATECC508A
+ #define HAVE_PK_CALLBACKS
+ /* when you want to use a custom slot allocation for ATECC608A */
+ /* unless your configuration is unusual, you can use default */
+ /* implementation. */
+ /* #define CUSTOM_SLOT_ALLOCATION */
+#endif
+
+/* rsa primitive specific definition */
+#if defined(WOLFSSL_ESP32) || defined(WOLFSSL_ESPWROOM32SE)
+ /* Define USE_FAST_MATH and SMALL_STACK */
+ #define ESP32_USE_RSA_PRIMITIVE
+ /* threshold for performance adjustment for HW primitive use */
+ /* X bits of G^X mod P greater than */
+ #define EPS_RSA_EXPT_XBTIS 32
+ /* X and Y of X * Y mod P greater than */
+ #define ESP_RSA_MULM_BITS 9
+#endif
+#define RSA_LOW_MEM
+
+/* debug options */
+/* #define DEBUG_WOLFSSL */
+/* #define WOLFSSL_ESP32_CRYPT_DEBUG */
+/* #define WOLFSSL_ATECC508A_DEBUG */
+
+/* date/time */
+/* if it cannot adjust time in the device, */
+/* enable macro below */
+/* #define NO_ASN_TIME */
+/* #define XTIME time */
+
+/* adjust wait-timeout count if you see timeout in RSA HW acceleration */
+#define ESP_RSA_TIMEOUT_CNT 0x249F00
+
+#define HASH_SIZE_LIMIT /* for test.c */
+
+#define USE_FAST_MATH
+
+/* optionally use SP_MATH */
+/* #define SP_MATH */
+
+#define WOLFSSL_SMALL_STACK
+
+#define HAVE_VERSION_EXTENDED_INFO
+#define HAVE_WC_INTROSPECTION
+
+/* allows for all version info, even that suppressed with introspection */
+#define ALLOW_BINARY_MISMATCH_INTROSPECTION
+
+/* The ESP32 has some detailed statup information available:*/
+#define HAVE_VERSION_EXTENDED_INFO
+
+/* 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)
+ /* SM settings, possible cipher suites:
+
+ TLS13-AES128-GCM-SHA256
+ TLS13-CHACHA20-POLY1305-SHA256
+ TLS13-SM4-GCM-SM3
+ TLS13-SM4-CCM-SM3
+
+ #define WOLFSSL_ESP32_CIPHER_SUITE "TLS13-SM4-GCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "TLS13-SM4-CCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "ECDHE-ECDSA-SM4-CBC-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "ECDHE-ECDSA-SM4-GCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "ECDHE-ECDSA-SM4-CCM-SM3"
+ #define WOLFSSL_ESP32_CIPHER_SUITE "TLS13-SM4-GCM-SM3:" \
+ "TLS13-SM4-CCM-SM3:"
+ */
+
+ #undef WOLFSSL_BASE16
+ #define WOLFSSL_BASE16 /* required for WOLFSSL_SM2 */
+
+ #undef WOLFSSL_SM4_ECB
+ #define WOLFSSL_SM4_ECB
+
+ #undef WOLFSSL_SM4_CBC
+ #define WOLFSSL_SM4_CBC
+
+ #undef WOLFSSL_SM4_CTR
+ #define WOLFSSL_SM4_CTR
+
+ #undef WOLFSSL_SM4_GCM
+ #define WOLFSSL_SM4_GCM
+
+ #undef WOLFSSL_SM4_CCM
+ #define WOLFSSL_SM4_CCM
+
+ #define HAVE_POLY1305
+ #define HAVE_CHACHA
+
+ #undef HAVE_AESGCM
+ #define HAVE_AESGCM
+#else
+ /* default settings */
+ #define USE_CERT_BUFFERS_2048
+#endif
+
+/* Default is HW enabled unless turned off.
+** Uncomment these lines for SW: */
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ /* #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)
+ #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)
+ /* #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_ESP32C2)
+ #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)
+ #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)
+ #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)
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+#else
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+#endif
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/CMakeLists.txt b/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/CMakeLists.txt
new file mode 100644
index 000000000..2b6768f84
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/CMakeLists.txt
@@ -0,0 +1,77 @@
+# This tag is used to include this file in the ESP Component Registry:
+# __ESP_COMPONENT_SOURCE__
+
+#
+# wolfssl client test
+#
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
+
+set (git_cmd "git")
+
+if( EXISTS "${CMAKE_HOME_DIRECTORY}/components/wolfssl/" AND EXISTS "$ENV{IDF_PATH}/components/wolfssl/" )
+ #
+ # wolfSSL found in both ESP-IDF and local project - needs to be resolved by user
+ #
+ message(STATUS "")
+ message(STATUS "WARNING: Found components/wolfssl in both local project and IDF_PATH")
+ message(STATUS "")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_MULTI_INSTALL_WARNING")
+endif()
+
+## register_component()
+idf_component_register(SRCS main.c
+ INCLUDE_DIRS "." "./include")
+#
+
+#
+# LIBWOLFSSL_SAVE_INFO(VAR_OUPUT THIS_VAR VAR_RESULT)
+#
+# Save the THIS_VAR as a string in a macro called VAR_OUPUT
+#
+# VAR_OUPUT: the name of the macro to define
+# THIS_VAR: the OUTPUT_VARIABLE result from a execute_process()
+# VAR_RESULT: the RESULT_VARIABLE from a execute_process(); "0" if successful.
+#
+function ( LIBWOLFSSL_SAVE_INFO VAR_OUPUT THIS_VAR VAR_RESULT )
+ # is the RESULT_VARIABLE output value 0? If so, IS_VALID_VALUE is true.
+ string(COMPARE EQUAL "${VAR_RESULT}" "0" IS_VALID_VALUE)
+
+ # if we had a successful operation, save the THIS_VAR in VAR_OUPUT
+ if(${IS_VALID_VALUE})
+ # strip newline chars in THIS_VAR parameter and save in VAR_VALUE
+ string(REPLACE "\n" "" VAR_VALUE ${THIS_VAR})
+
+ # we'll could percolate the value to the parent for possible later use
+ # set(${VAR_OUPUT} ${VAR_VALUE} PARENT_SCOPE)
+
+ # but we're only using it here in this function
+ set(${VAR_OUPUT} ${VAR_VALUE})
+
+ # we'll print what we found to the console
+ message(STATUS "Found ${VAR_OUPUT}=${VAR_VALUE}")
+
+ # the interesting part is defining the VAR_OUPUT name a value to use in the app
+ add_definitions(-D${VAR_OUPUT}=\"${VAR_VALUE}\")
+ else()
+ # if we get here, check the execute_process command and parameters.
+ message(STATUS "LIBWOLFSSL_SAVE_INFO encountered a non-zero VAR_RESULT")
+ set(${VAR_OUPUT} "Unknown")
+ endif()
+endfunction() # LIBWOLFSSL_SAVE_INFO
+
+if(NOT CMAKE_BUILD_EARLY_EXPANSION)
+ # LIBWOLFSSL_VERSION_GIT_HASH
+ execute_process(COMMAND ${git_cmd} "rev-parse" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_SHORT_HASH
+ execute_process(COMMAND ${git_cmd} "rev-parse" "--short" "HEAD" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES ERROR_QUIET )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_SHORT_HASH "${TMP_OUT}" "${TMP_RES}")
+
+ # LIBWOLFSSL_VERSION_GIT_HASH_DATE
+ execute_process(COMMAND ${git_cmd} "show" "--no-patch" "--no-notes" "--pretty=\'\%cd\'" OUTPUT_VARIABLE TMP_OUT RESULT_VARIABLE TMP_RES )
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_GIT_HASH_DATE "${TMP_OUT}" "${TMP_RES}")
+endif()
+
+message(STATUS "")
+
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/include/main.h b/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/include/main.h
new file mode 100644
index 000000000..7e07ec1df
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/include/main.h
@@ -0,0 +1,38 @@
+/* template main.h
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+/* Espressif libraries */
+#include "sdkconfig.h"
+#include
+#include
+
+/* wolfSSL */
+#include "user_settings.h" /* always include wolfSSL user_settings.h first */
+#include
+#include
+
+/* wolfSSH */
+#include
+#include
+
+#endif
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/main.c b/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/main.c
new file mode 100644
index 000000000..6204cc398
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/main/main.c
@@ -0,0 +1,79 @@
+/* main.c
+ *
+ * Copyright (C) 2006-2023 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+#include "main.h"
+
+/* actual working example would include WiFi & time libraries here */
+
+static const char* const TAG = "My Project";
+
+void app_main(void)
+{
+ ESP_LOGI(TAG, "------------ wolfSSL wolfSSH template Example ----------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+ ESP_LOGI(TAG, "---------------------- BEGIN MAIN ----------------------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+ ESP_LOGI(TAG, "--------------------------------------------------------");
+
+ ESP_LOGI(TAG, "Hello wolfSSL!");
+
+#ifdef DEBUG_WOLFSSH
+ wolfSSH_Debugging_ON();
+#else
+ ESP_LOGI(TAG, "DEBUG_WOLFSSH is not defined, "
+ "so nothing will happen for teh next statement");
+#endif
+
+#ifdef HAVE_VERSION_EXTENDED_INFO
+ esp_ShowExtendedSystemInfo();
+#endif
+
+#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)));
+#endif
+
+/* the simplest check of the wolfSSL library presence: */
+#ifdef LIBWOLFSSL_VERSION_STRING
+ ESP_LOGI(TAG, "");
+ ESP_LOGI(TAG, "Found wolfSSL Version %s\n", LIBWOLFSSL_VERSION_STRING);
+#else
+ ESP_LOGW(TAG, "Warning: Could not find wolfSSL Version");
+#endif
+
+/* the simplest check of the wolfSSH library presence: */
+#ifdef LIBWOLFSSH_VERSION_STRING
+ ESP_LOGI(TAG, "");
+ ESP_LOGI(TAG, "Found wolfSSH Version %s\n", LIBWOLFSSH_VERSION_STRING);
+ wolfSSH_Log(WS_LOG_INFO, "[wolfssh] Hello World!");
+#else
+ ESP_LOGW(TAG, "Warning: Could not find wolfSSH Version");
+#endif
+
+/* actual working example would initialize WiFi & time libraries here */
+
+ ESP_LOGI(TAG, "\n\nDone!\n\n"
+ "If running from idf.py monitor, press twice: Ctrl+]\n\n"
+ "WOLFSSL_COMPLETE\n" /* exit keyword for wolfssl_monitor.py */
+ );
+} /* app_main */
diff --git a/ide/Espressif/ESP-IDF/examples/wolfssh_template/sdkconfig.defaults b/ide/Espressif/ESP-IDF/examples/wolfssh_template/sdkconfig.defaults
new file mode 100644
index 000000000..2842aa34e
--- /dev/null
+++ b/ide/Espressif/ESP-IDF/examples/wolfssh_template/sdkconfig.defaults
@@ -0,0 +1,23 @@
+CONFIG_FREERTOS_HZ=1000
+CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
+
+#
+# Default main stack size
+#
+# This is typically way bigger than needed for stack size. See user_settings.h
+#
+CONFIG_ESP_MAIN_TASK_STACK_SIZE=10500
+
+# Legacy stack size for older ESP-IDF versions
+CONFIG_MAIN_TASK_STACK_SIZE=10500
+
+#
+# Compiler options
+#
+CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
+CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
+CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2
+CONFIG_COMPILER_HIDE_PATHS_MACROS=y
+CONFIG_COMPILER_STACK_CHECK_MODE_NORM=y
+CONFIG_COMPILER_STACK_CHECK=y
+