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 +