diff --git a/IDE/Espressif/CMakeLists.txt b/IDE/Espressif/CMakeLists.txt
new file mode 100644
index 00000000..fe9a16e3
--- /dev/null
+++ b/IDE/Espressif/CMakeLists.txt
@@ -0,0 +1,96 @@
+# wolfTPM Espressif Example Project CMakeLists.txt
+# v1.0
+#
+# 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.16)
+
+# The wolfTPM CMake file should be able to find the source code.
+# Otherwise, assign an environment variable or set it here:
+#
+# set(WOLFTPM_ROOT "~/workspace/wolftpm-other-source")
+#
+# Optional WOLFSSL_CMAKE_SYSTEM_NAME detection to find
+# USE_MY_PRIVATE_CONFIG path for my_private_config.h
+#
+# Expected path varies:
+#
+# WSL: /mnt/c/workspace
+# Linux: ~/workspace
+# Windows: C:\workspace
+#
+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 no 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()
+
+# Check that there are no conflicting wolfTPM components.
+#
+# The ESP Registry Component will be in ./managed_components/wolfssl__wolftpm
+# The local component wolfTPM directory will be in ./components/wolftpm
+if( EXISTS "${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolftpm" AND EXISTS "${CMAKE_HOME_DIRECTORY}/components/wolftpm" )
+ # 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__wolftpm" EXCLUDE_FROM_ALL)
+ # add_subdirectory("${CMAKE_HOME_DIRECTORY}/managed_components/wolfssl__wolftpm/include" EXCLUDE_FROM_ALL)
+ # So we'll error out and let the user decide how to proceed:
+ message(WARNING "\nFound wolfTPM components in\n"
+ "./managed_components/wolfssl__wolftpm\n"
+ "and\n"
+ "./components/wolftpm\n"
+ "in project directory: \n"
+ "${CMAKE_HOME_DIRECTORY}")
+ message(FATAL_ERROR "\nPlease use either the ESP Registry Managed Component or the wolfTPM component directory but not both.\n"
+ "If removing the ./managed_components/wolfssl__wolftpm directory, remember to also remove "
+ "or rename the idf_component.yml file typically found in ./main/")
+else()
+ message(STATUS "No conflicting wolfTPM components found.")
+endif()
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+
+project(wolfTPM_test)
diff --git a/IDE/Espressif/README.md b/IDE/Espressif/README.md
new file mode 100644
index 00000000..fffe3841
--- /dev/null
+++ b/IDE/Espressif/README.md
@@ -0,0 +1,31 @@
+# wolfTPM for Espressif
+
+Initial minimum memory requirements: 35KB Stack. See `sdkconfig.defaults`.
+
+Current memory assigned: 50960
+
+## Pin assignments
+
+**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` .
+
+| | SDA | SCL |
+| ---------------- | -------------- | -------------- |
+| ESP I2C Master | I2C_MASTER_SDA | I2C_MASTER_SCL |
+| TPM2 Device | SDA | SCL |
+
+For the actual default value of `I2C_MASTER_SDA` and `I2C_MASTER_SCL` see `Example Configuration` in `menuconfig`.
+
+**Note:** There's no need to add an external pull-up resistors for SDA/SCL pin, because the driver will enable the internal pull-up resistors.
+
+## Troubleshooting
+
+If problems are encountered with the I2C module:
+
+- Beware that printing to the UART during an I2C transaction may affect timing and cause errors.
+- Ensure the TPM module has been reset after flash updated.
+- Check wiring. `SCL` to `SCL`, `SDA` to `SDA`. Probably best to ensure GND is connected. Vcc is 3.3v only.
+- Ensure the proper pins are connected on the ESP32. SCL default is `GPIO 19`; SDA default is `GPIO 18`.
+- Test with only a single I2C device before testing concurrent with other I2C boards.
+- When using multiple I2C boards, check for appropriate pullups. See data sheet.
+- Reset TPM device again. Press button on TPM SLB9673 eval board or set TPM pin 17 as appropriate.
+-
\ No newline at end of file
diff --git a/IDE/Espressif/VisualGDB/wolfssl_IDF_v5.2_ESP32.vgdbproj b/IDE/Espressif/VisualGDB/wolfssl_IDF_v5.2_ESP32.vgdbproj
new file mode 100644
index 00000000..b22445e3
--- /dev/null
+++ b/IDE/Espressif/VisualGDB/wolfssl_IDF_v5.2_ESP32.vgdbproj
@@ -0,0 +1,269 @@
+
+
+
+
+
+ Unknown
+
+ true
+
+ 35e5525f-318a-466e-a8c7-36548547d801
+ true
+ true
+ SourceDirs
+
+
+
+
+
+ com.visualgdb.xtensa-esp32-elf
+
+ 13.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.2
+ esp-idf/v5.2
+ ESPIDF
+
+ COM19
+ false
+ false
+ ESP32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+ COM19
+
+ 115200
+ 8
+ None
+ One
+ None
+
+
+ 0
+ false
+ true
+ 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 19000" -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
+ Auto
+ 0
+ false
+ false
+ true
+ false
+ false
+
+ _estack
+ 0
+ false
+
+ true
+
+
\ No newline at end of file
diff --git a/IDE/Espressif/components/wolfssl/CMakeLists.txt b/IDE/Espressif/components/wolfssl/CMakeLists.txt
new file mode 100644
index 00000000..314aa7e4
--- /dev/null
+++ b/IDE/Espressif/components/wolfssl/CMakeLists.txt
@@ -0,0 +1,711 @@
+#
+# Copyright (C) 2006-2024 wolfSSL Inc.
+#
+# This file is part of wolfTPM.
+#
+# wolfTPM 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.
+#
+# wolfTPM 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
+#
+# Version 5.6.6.1 template update
+#
+# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html
+#
+
+cmake_minimum_required(VERSION 3.16)
+
+set(VERBOSE_COMPONENT_MESSAGES 1)
+
+# The scope of this CMAKE_C_FLAGS is just this component:
+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
+
+# Optionally set your source to wolfSSL in your project CMakeLists.txt like this:
+# set(WOLFSSL_ROOT "c:/test/my_wolfssl" )
+
+if ( "${WOLFSSL_ROOT}" STREQUAL "")
+ set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" )
+endif()
+# Optional compiler definitions to help with system name detection (typically printed by app diagnostics)
+if(VERBOSE_COMPONENT_MESSAGES)
+ 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()
+endif() # End optional WOLFSSL_CMAKE_SYSTEM_NAME
+
+message(STATUS "CONFIG_TARGET_PLATFORM = ${CONFIG_TARGET_PLATFORM}")
+
+# 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()
+
+
+# Don't include lwip requirement for benchmark and test apps.
+if( ("${CMAKE_PROJECT_NAME}" STREQUAL "wolfssl_benchmark") OR ("${CMAKE_PROJECT_NAME}" STREQUAL "wolfssl_test") )
+ message(STATUS "Not including lwip for ${CMAKE_PROJECT_NAME}")
+else()
+ # benchmark and test do not need wifi, everything else probably does:
+ set(COMPONENT_REQUIRES lwip) # we typically don't need lwip directly in wolfssl component
+endif()
+
+# 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}")
+
+if( "$ENV{IDF_PATH}" STREQUAL "" )
+ message(FATAL_ERROR "IDF_PATH Environment variable not set!")
+else()
+ string(REPLACE "\\" "/" THIS_IDF_PATH "$ENV{IDF_PATH}")
+endif()
+
+# 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:
+
+# function: IS_WOLFSSL_SOURCE
+# parameter: DIRECTORY_PARAMETER - the directory to test
+# output: RESULT = contains contents of DIRECTORY_PARAMETER for wolfssl directory, otherwise blank.
+function(IS_WOLFSSL_SOURCE DIRECTORY_PARAMETER RESULT)
+ if (EXISTS "${DIRECTORY_PARAMETER}/wolfcrypt/src")
+ set(${RESULT} "${DIRECTORY_PARAMETER}" PARENT_SCOPE)
+ else()
+ set(${RESULT} "" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# *********************************************************************************************
+# function: FIND_WOLFSSL_DIRECTORY
+# parameter: OUTPUT_FOUND_WOLFSSL_DIRECTORY contains root of source code, otherwise blank
+#
+# Example usage:
+# FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT)
+# *********************************************************************************************
+function(FIND_WOLFSSL_DIRECTORY OUTPUT_FOUND_WOLFSSL_DIRECTORY)
+ message(STATUS "Starting FIND_WOLFSSL_DIRECTORY: ${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}")
+
+ if ( "${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}" STREQUAL "" )
+ set(CURRENT_SEARCH_DIR "$ENV{WOLFSSL_ROOT}")
+ if( "${CURRENT_SEARCH_DIR}" STREQUAL "" )
+ message(STATUS "The WOLFSSL_ROOT environment variable is not set. Searching...")
+ else()
+ get_filename_component(CURRENT_SEARCH_DIR "$ENV{WOLFSSL_ROOT}" ABSOLUTE)
+ IS_WOLFSSL_SOURCE("${CURRENT_SEARCH_DIR}" FOUND_WOLFSSL)
+ if( FOUND_WOLFSSL )
+ 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()
+ else()
+ get_filename_component(CURRENT_SEARCH_DIR "${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}" ABSOLUTE)
+ IS_WOLFSSL_SOURCE("${CURRENT_SEARCH_DIR}" FOUND_WOLFSSL)
+ if( FOUND_WOLFSSL )
+ message(STATUS "Found WOLFSSL_ROOT via prior specification.")
+ else()
+ message(FATAL_ERROR "WOLFSSL_ROOT Variable defined, but path not found: ${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}")
+ endif()
+ endif()
+
+
+ # we'll start in the CMAKE_CURRENT_SOURCE_DIR, typically [something]/projectname/components/wolfssl
+ message(STATUS "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
+ get_filename_component(CURRENT_SEARCH_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
+ message(STATUS "CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ string(LENGTH ${CURRENT_SEARCH_DIR} CURRENT_SEARCH_DIR_LENGTH)
+
+ # loop through all the parents, looking for wolfssl
+ while(NOT CURRENT_SEARCH_DIR STREQUAL "/" AND NOT CURRENT_SEARCH_DIR STREQUAL "" )
+ string(LENGTH ${CURRENT_SEARCH_DIR} CURRENT_SEARCH_DIR_LENGTH)
+ # wolfSSL may simply be in a parent directory, such as for local examples in wolfssl repo
+ IS_WOLFSSL_SOURCE("${CURRENT_SEARCH_DIR}" FOUND_WOLFSSL)
+ if( FOUND_WOLFSSL )
+ message(STATUS "Found wolfssl in CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ set(${OUTPUT_FOUND_WOLFSSL_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+
+ # Maintain CURRENT_SEARCH_DIR, but check various suffixes with CURRENT_SEARCH_DIR_ALT
+ if( THIS_USER )
+ # Check for "wolfssl-[username]" subdirectory as we recurse up the directory tree
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolfssl-${THIS_USER})
+ message(STATUS "Looking in ${CURRENT_SEARCH_DIR_ALT}")
+
+ IS_WOLFSSL_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFSSL )
+ if ( FOUND_WOLFSSL )
+ message(STATUS "Found wolfssl in user-suffix CURRENT_SEARCH_DIR_ALT = ${CURRENT_SEARCH_DIR_ALT}")
+ set(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR_ALT}")
+ set(${OUTPUT_FOUND_WOLFSSL_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+
+ if ( FOUND_WOLFSSL )
+ # if we already found the source, skip attempt of "wolfssl-master"
+ else()
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolfssl-master)
+ message(STATUS "Looking in ${CURRENT_SEARCH_DIR_ALT}")
+
+ IS_WOLFSSL_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFSSL )
+ if ( FOUND_WOLFSSL )
+ message(STATUS "Found wolfssl in master-suffix CURRENT_SEARCH_DIR_ALT = ${CURRENT_SEARCH_DIR_ALT}")
+ set(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR_ALT}")
+ set(${OUTPUT_FOUND_WOLFSSL_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+
+ if ( FOUND_WOLFSSL )
+ # if we already found the source, skip attempt of "wolfssl"
+ else()
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolfssl)
+ message(STATUS "Looking in ${CURRENT_SEARCH_DIR_ALT}")
+
+ IS_WOLFSSL_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFSSL )
+ if ( FOUND_WOLFSSL )
+ message(STATUS "Found wolfssl in CURRENT_SEARCH_DIR_ALT = ${CURRENT_SEARCH_DIR_ALT}")
+ set(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR_ALT}")
+ set(${OUTPUT_FOUND_WOLFSSL_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+
+ # Next check for no user suffix "wolfssl" subdirectory as we recurse up the directory tree
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolfssl)
+ # if(EXISTS ${CURRENT_SEARCH_DIR} AND IS_DIRECTORY ${CURRENT_SEARCH_DIR} AND EXISTS "${CURRENT_SEARCH_DIR}/wolfcrypt/src")
+ IS_WOLFSSL_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFSSL )
+ if ( FOUND_WOLFSSL )
+ message(STATUS "Found wolfssl in CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ set(${OUTPUT_FOUND_WOLFSSL_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+
+ # Move up one directory level
+ set(PRIOR_SEARCH_DIR "${CURRENT_SEARCH_DIR}")
+ get_filename_component(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR}" DIRECTORY)
+ message(STATUS "Next CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ if( "${PRIOR_SEARCH_DIR}" STREQUAL "${CURRENT_SEARCH_DIR}" )
+ # When the parent is current directory, cannot go any further. We didn't find wolfssl.
+ # When the search directory is empty, we'll give up.
+ set(CURRENT_SEARCH_DIR "")
+ endif()
+ endwhile()
+
+ # If not found, set the output variable to empty before exiting
+ set(${OUTPUT_FOUND_WOLFSSL_DIRECTORY} "" PARENT_SCOPE)
+endfunction()
+
+
+# Example usage:
+#
+# Simply find the WOLFSSL_DIRECTORY by searching parent directories:
+# FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT)
+#
+
+if(CMAKE_BUILD_EARLY_EXPANSION)
+ message(STATUS "wolfssl component CMAKE_BUILD_EARLY_EXPANSION:")
+ idf_component_register(
+ REQUIRES "${COMPONENT_REQUIRES}"
+ PRIV_REQUIRES # esp_hw_support
+ "${THIS_INCLUDE_TIMER}"
+ "${THIS_INCLUDE_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 "************************************************************************************************")
+
+ if ( "${CONFIG_TARGET_PLATFORM}" STREQUAL "esp8266")
+ # There's no esp_timer, no driver components for the ESP8266
+ set(THIS_INCLUDE_TIMER "")
+ set(THIS_INCLUDE_DRIVER "")
+ else()
+ set(THIS_INCLUDE_TIMER "esp_timer")
+ set(THIS_INCLUDE_DRIVER "driver")
+ endif()
+
+ # search for wolfSSL
+ if(WOLFSSL_ROOT)
+ IS_WOLFSSL_SOURCE("${WOLFSSL_ROOT}" FOUND_WOLFSSL)
+ if(FOUND_WOLFSSL)
+ message(STATUS "Found WOLFSSL_ROOT via CMake specification.")
+ else()
+ # WOLFSSL_ROOT Path specified in CMakeLists.txt is not a valid path
+ message(FATAL_ERROR "WOLFSSL_ROOT CMake Variable defined, but path not found: ${WOLFSSL_ROOT}\n"
+ "Try correcting WOLFSSL_ROOT in your project CMakeFile.txt or setting environment variable.")
+ # Abort CMake after fatal error.
+ endif()
+ else()
+ message(STATUS "Searching for wolfSL source code...")
+ FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT)
+ endif()
+
+
+ if(WOLFSSL_ROOT)
+ message(STATUS "Confirmed wolfssl directory at: ${WOLFSSL_ROOT}")
+ else()
+ message(STATUS "Failed: wolfssl directory not found.")
+ # Abort. We need wolfssl _somewhere_.
+ message(FATAL_ERROR "Could not find wolfssl in any parent directory named wolfssl-${THIS_USER}, wolfssl-master, or wolfssl.\n"
+ "Try setting WOLFSSL_ROOT environment variable, cmake variable in project, copy source, or use managed components.")
+ # Abort CMake after fatal error.
+ endif()
+
+ set(INCLUDE_PATH ${WOLFSSL_ROOT})
+
+ set(WOLFSSL_EXTRA_PROJECT_DIR "${WOLFSSL_ROOT}/src/")
+
+ # During regression tests, optionally copy source locally and use: set(USE_LOCAL_TEST_BENCH 1)
+ set(USE_LOCAL_TEST_BENCH 0)
+ if(NOT USE_LOCAL_TEST_BENCH)
+ if( "${CMAKE_PROJECT_NAME}" STREQUAL "hello-world" )
+ message(STATUS "Include ${WOLFSSL_ROOT}/wolfcrypt/benchmark")
+ set(WOLFSSL_EXTRA_PROJECT_DIR "${WOLFSSL_ROOT}/wolfcrypt/benchmark")
+ endif()
+
+ if( "${CMAKE_PROJECT_NAME}" STREQUAL "wolfssl_benchmark" )
+ message(STATUS "Include ${WOLFSSL_ROOT}/wolfcrypt/benchmark")
+ set(WOLFSSL_EXTRA_PROJECT_DIR "${WOLFSSL_ROOT}/wolfcrypt/benchmark")
+ endif()
+
+ if( "${CMAKE_PROJECT_NAME}" STREQUAL "wolfssl_test" )
+ message(STATUS "Include ${WOLFSSL_ROOT}/wolfcrypt/test")
+ set(WOLFSSL_EXTRA_PROJECT_DIR "${WOLFSSL_ROOT}/wolfcrypt/test")
+ endif()
+ endif()
+
+ set(COMPONENT_SRCDIRS "\"${WOLFSSL_ROOT}/src/\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/port/atmel\""
+ "\"${WOLFSSL_EXTRA_PROJECT_DIR}\""
+ ) # COMPONENT_SRCDIRS
+
+ message(STATUS "This COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+
+ # wolfSSL user_settings.h is in the local project.
+ set(WOLFSSL_PROJECT_DIR "${CMAKE_HOME_DIRECTORY}/components/wolfssl")
+
+ string(REPLACE "/" "//" STR_WOLFSSL_PROJECT_DIR "${WOLFSSL_PROJECT_DIR}")
+ add_definitions(-DWOLFSSL_USER_SETTINGS_DIR="${STR_WOLFSSL_PROJECT_DIR}//include//user_settings.h")
+
+ # 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 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(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+
+ message(FATAL_ERROR "Please use wolfSSL in either local project or Espressif components, but not both.")
+ # Abort CMake after fatal error.
+
+ # 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 )")
+ # Abort CMake after fatal error.
+ 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(STATUS "******************************************************************************")
+ message(STATUS "******************************************************************************")
+ message(STATUS "Found stray wolfSSL config.h in ${WOLFSSL_ROOT}/include/config.h" )
+ message(STATUS " Please move it to ${WOLFSSL_PROJECT_DIR}/include/config.h" )
+ message(STATUS "******************************************************************************")
+ message(STATUS "******************************************************************************")
+ 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()
+
+ # wolfSSL-specific include directories
+ set(COMPONENT_ADD_INCLUDEDIRS
+ "./include" # this is the location of local project wolfssl user_settings.h
+ "\"${WOLFSSL_ROOT}/\""
+ "\"${WOLFSSL_ROOT}/wolfssl/\""
+ "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt/\""
+ "\"${WOLFSSL_ROOT}/wolfssl/wolfcrypt/port/Espressif\""
+ "\"${RTOS_IDF_PATH}/\""
+ )
+
+ # Optionally include cryptoauthlib if present
+ 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/\"")
+
+
+ # Some files are known to be included elsewhere, or not used for Espressif
+ 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_bn.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c
+ "\"${WOLFSSL_ROOT}/src/ssl_crypto.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\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_arm32.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_arm64.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_armthumb.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_c32.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_c64.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_cortexm.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_x86_64.c\""
+ "\"${WOLFSSL_ROOT}/wolfcrypt/src/sp_sm2_x86_64_asm.S\""
+ "\"${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
+ "${THIS_INCLUDE_TIMER}"
+ "${THIS_INCLUDE_DRIVER}" # this will typically only be needed for wolfSSL benchmark
+ )
+
+ # Some optional diagnostics. Verbose ones are truncated.
+ if (VERBOSE_COMPONENT_MESSAGES)
+ get_cmake_property(_variableNames VARIABLES)
+ list (SORT _variableNames)
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES BEGIN")
+ message(STATUS "")
+ foreach (_variableName ${_variableNames})
+ if ( ("${_variableName}" STREQUAL "bootloader_binary_files")
+ OR ("${_variableName}" STREQUAL "Component paths")
+ OR ("${_variableName}" STREQUAL "component_targets")
+ OR ("${_variableName}" STREQUAL "__COMPONENT_TARGETS")
+ OR ("${_variableName}" STREQUAL "CONFIGS_LIST")
+ OR ("${_variableName}" STREQUAL "__CONFIG_VARIABLES")
+ OR ("${_variableName}" STREQUAL "val")
+ OR ("${_variableName}" MATCHES "^__idf_")
+ )
+ # Truncate the displayed value:
+ string(SUBSTRING "${${_variableName}}" 0 70 truncatedValue)
+ message(STATUS "${_variableName} = ${truncatedValue} ... (truncated)")
+ else()
+ message(STATUS "${_variableName}=${${_variableName}}")
+ endif()
+ 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}")
+
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_WOLFSSL_ROOT "${WOLFSSL_ROOT}" "${TMP_RES}")
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssl component config complete!")
+ message(STATUS "************************************************************************************************")
+endif()
diff --git a/IDE/Espressif/components/wolfssl/include/user_settings.h b/IDE/Espressif/components/wolfssl/include/user_settings.h
new file mode 100644
index 00000000..a8852990
--- /dev/null
+++ b/IDE/Espressif/components/wolfssl/include/user_settings.h
@@ -0,0 +1,706 @@
+/* user_settings.h
+ *
+ * Copyright (C) 2006-2024 wolfSSL Inc.
+ *
+ * This file is part of wolfTPM.
+ *
+ * wolfTPM 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.
+ *
+ * wolfTPM 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
+ */
+
+/* This user_settings.h is for Espressif ESP-IDF
+ *
+ * Standardized wolfSSL Espressif ESP32 + ESP8266 user_settings.h V5.7.0-1
+ *
+ * Do not include any wolfssl headers here.
+ */
+
+/* The Espressif project config file. See also sdkconfig.defaults */
+#include "sdkconfig.h"
+
+/* The Espressif sdkconfig will have chipset info.
+**
+** Some possible values:
+**
+** CONFIG_IDF_TARGET_ESP32
+** CONFIG_IDF_TARGET_ESP32S2
+** CONFIG_IDF_TARGET_ESP32S3
+** CONFIG_IDF_TARGET_ESP32C3
+** CONFIG_IDF_TARGET_ESP32C6
+*/
+
+#undef WOLFSSL_ESPIDF
+#define WOLFSSL_ESPIDF
+
+/* We don't use WiFi, so don't compile in the esp-sdk-lib WiFi helpers: */
+/* #define USE_WOLFSSL_ESP_SDK_WIFI */
+
+/* Experimental Kyber */
+#if 0
+ /* Kyber typically needs a minimum 10K stack */
+ #define WOLFSSL_EXPERIMENTAL_SETTINGS
+ #define WOLFSSL_HAVE_KYBER
+ #define WOLFSSL_WC_KYBER
+ #define WOLFSSL_SHA3
+#endif
+
+/*
+ * ONE of these Espressif chip families will be detected from sdkconfig:
+ *
+ * WOLFSSL_ESP32
+ * WOLFSSL_ESP8266
+ */
+#undef WOLFSSL_ESPWROOM32SE
+#undef WOLFSSL_ESP8266
+#undef WOLFSSL_ESP32
+/* See below for chipset detection from sdkconfig.h */
+
+/* when you want to use SINGLE THREAD. Note Default ESP-IDF is FreeRTOS */
+/* #define SINGLE_THREADED */
+
+/* SMALL_SESSION_CACHE saves a lot of RAM for ClientCache and SessionCache.
+ * Memory requirement is about 5KB, otherwise 20K is needed when not specified.
+ * If extra small footprint is needed, try MICRO_SESSION_CACHE (< 1K)
+ * When really desperate or no TLS used, try NO_SESSION_CACHE. */
+#define NO_SESSION_CACHE
+
+/* Small Stack uses more heap. */
+#define WOLFSSL_SMALL_STACK
+
+/* Full debugging turned off, but show malloc failure detail */
+/* #define DEBUG_WOLFSSL */
+#define DEBUG_WOLFSSL_MALLOC
+
+/* See test.c that sets cert buffers; we'll set them here: */
+#define USE_CERT_BUFFERS_256
+#define USE_CERT_BUFFERS_2048
+
+/* RSA_LOW_MEM: Half as much memory but twice as slow. */
+#define RSA_LOW_MEM
+
+
+
+
+/* optionally turn off SHA512/224 SHA512/256 */
+/* #define WOLFSSL_NOSHA512_224 */
+/* #define WOLFSSL_NOSHA512_256 */
+
+/* when you want to use SINGLE THREAD. Note Default ESP-IDF is FreeRTOS */
+/* #define SINGLE_THREADED */
+
+/* When you don't want to use the old SHA */
+/* #define NO_SHA */
+/* #define NO_OLD_TLS */
+
+#define BENCH_EMBEDDED
+
+/* 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
+
+#define NO_FILESYSTEM
+
+#define NO_OLD_TLS
+
+#define HAVE_AESGCM
+
+/* Optional RIPEMD: RACE Integrity Primitives Evaluation Message Digest */
+/* #define WOLFSSL_RIPEMD */
+
+/* when you want to use SHA224 */
+#define WOLFSSL_SHA224
+
+/* when you want to use SHA384 */
+#define WOLFSSL_SHA384
+
+/* when you want to use SHA512 */
+#define WOLFSSL_SHA512
+
+/* when you want to use SHA3 */
+#define WOLFSSL_SHA3
+
+ /* ED25519 requires SHA512 */
+#define HAVE_ED25519
+
+/* Some features not enabled for ESP8266: */
+#if defined(CONFIG_IDF_TARGET_ESP8266) || \
+ defined(CONFIG_IDF_TARGET_ESP32C2)
+ /* TODO determine low memory configuration for ECC. */
+#else
+ #define HAVE_ECC
+ #define HAVE_CURVE25519
+ #define CURVE25519_SMALL
+#endif
+
+#define HAVE_ED25519
+
+/* Optional OPENSSL compatibility */
+#define OPENSSL_EXTRA
+
+/* #Optional HAVE_PKCS7 */
+/* #define HAVE_PKCS7 */
+
+#if defined(HAVE_PKCS7)
+ /* HAVE_PKCS7 may enable HAVE_PBKDF2 see settings.h */
+ #define NO_PBKDF2
+
+ #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
+
+/* WC_NO_CACHE_RESISTANT: slower but more secure */
+/* #define WC_NO_CACHE_RESISTANT */
+
+/* TFM_TIMING_RESISTANT: slower but more secure */
+/* #define TFM_TIMING_RESISTANT */
+
+/* #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 0x349F00
+
+/* hash limit for test.c */
+#define HASH_SIZE_LIMIT
+
+/* USE_FAST_MATH is default */
+#define USE_FAST_MATH
+
+/***** Use SP_MATH *****/
+/* #undef USE_FAST_MATH */
+/* #define SP_MATH */
+/* #define WOLFSSL_SP_MATH_ALL */
+/* #define WOLFSSL_SP_RISCV32 */
+
+/***** Use Integer Heap Math *****/
+/* #undef USE_FAST_MATH */
+/* #define USE_INTEGER_HEAP_MATH */
+
+
+#define WOLFSSL_SMALL_STACK
+
+
+#define HAVE_VERSION_EXTENDED_INFO
+/* #define HAVE_WC_INTROSPECTION */
+
+#define HAVE_SESSION_TICKET
+
+/* #define HAVE_HASHDRBG */
+
+#define WOLFSSL_KEY_GEN
+#define WOLFSSL_CERT_REQ
+#define WOLFSSL_CERT_GEN
+#define WOLFSSL_CERT_EXT
+#define WOLFSSL_SYS_CA_CERTS
+
+
+#define WOLFSSL_CERT_TEXT
+
+#define WOLFSSL_ASN_TEMPLATE
+
+/*
+#undef WOLFSSL_KEY_GEN
+#undef WOLFSSL_CERT_REQ
+#undef WOLFSSL_CERT_GEN
+#undef WOLFSSL_CERT_EXT
+#undef WOLFSSL_SYS_CA_CERTS
+*/
+
+/* command-line options
+--enable-keygen
+--enable-certgen
+--enable-certreq
+--enable-certext
+--enable-asn-template
+*/
+
+/* Chipset detection from sdkconfig.h
+ * Default is HW enabled unless turned off.
+ * Uncomment lines to force SW instead of HW acceleration */
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ #define WOLFSSL_ESP32
+ /* Alternatively, if there's an ECC Secure Element present: */
+ /* #define WOLFSSL_ESPWROOM32SE */
+
+ /* wolfSSL HW Acceleration supported on ESP32. Uncomment to disable: */
+ /* #define NO_ESP32_CRYPT */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_AES */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
+
+ /* These are defined automatically in esp32-crypt.h, here for clarity: */
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224 /* no SHA224 HW on ESP32 */
+
+ #undef ESP_RSA_MULM_BITS
+ #define ESP_RSA_MULM_BITS 16 /* TODO add compile-time warning */
+ /***** END CONFIG_IDF_TARGET_ESP32 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP32S2)
+ #define WOLFSSL_ESP32
+ /* wolfSSL HW Acceleration supported on ESP32-S2. Uncomment to disable: */
+ /* #define NO_ESP32_CRYPT */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
+ /* Note: There's no AES192 HW on the ESP32-S2; falls back to SW */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_AES */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
+ /***** END CONFIG_IDF_TARGET_ESP32S2 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP32S3)
+ #define WOLFSSL_ESP32
+ /* wolfSSL HW Acceleration supported on ESP32-S3. Uncomment to disable: */
+ /* #define NO_ESP32_CRYPT */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
+ /* Note: There's no AES192 HW on the ESP32-S3; falls back to SW */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_AES */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
+ /***** END CONFIG_IDF_TARGET_ESP32S3 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP32C2) || \
+ defined(CONFIG_IDF_TARGET_ESP8684)
+ #define WOLFSSL_ESP32
+ /* ESP8684 is essentially ESP32-C2 chip + flash embedded together in a
+ * single QFN 4x4 mm package. Out of released documentation, Technical
+ * Reference Manual as well as ESP-IDF Programming Guide is applicable
+ * to both ESP32-C2 and ESP8684.
+ *
+ * See: https://www.esp32.com/viewtopic.php?f=5&t=27926#:~:text=ESP8684%20is%20essentially%20ESP32%2DC2,both%20ESP32%2DC2%20and%20ESP8684. */
+
+ /* wolfSSL HW Acceleration supported on ESP32-C2. Uncomment to disable: */
+ /* #define NO_ESP32_CRYPT */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_HASH */ /* to disable all SHA HW */
+
+ /* These are defined automatically in esp32-crypt.h, here for clarity */
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384 /* no SHA384 HW on C2 */
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512 /* no SHA512 HW on C2 */
+
+ /* There's no AES or RSA/Math accelerator on the ESP32-C2
+ * Auto defined with NO_WOLFSSL_ESP32_CRYPT_RSA_PRI, for clarity: */
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
+ /***** END CONFIG_IDF_TARGET_ESP32C2 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP32C3)
+ #define WOLFSSL_ESP32
+ /* wolfSSL HW Acceleration supported on ESP32-C3. Uncomment to disable: */
+
+ /* #define NO_ESP32_CRYPT */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_HASH */ /* to disable all SHA HW */
+
+ /* These are defined automatically in esp32-crypt.h, here for clarity: */
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384 /* no SHA384 HW on C6 */
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512 /* no SHA512 HW on C6 */
+
+ /* #define NO_WOLFSSL_ESP32_CRYPT_AES */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
+ /***** END CONFIG_IDF_TARGET_ESP32C3 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP32C6)
+ #define WOLFSSL_ESP32
+ /* wolfSSL HW Acceleration supported on ESP32-C6. Uncomment to disable: */
+
+ /* #define NO_ESP32_CRYPT */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_HASH */
+ /* These are defined automatically in esp32-crypt.h, here for clarity: */
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384 /* no SHA384 HW on C6 */
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512 /* no SHA512 HW on C6 */
+
+ /* #define NO_WOLFSSL_ESP32_CRYPT_AES */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
+ /* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
+ /***** END CONFIG_IDF_TARGET_ESP32C6 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP32H2)
+ #define WOLFSSL_ESP32
+ /* wolfSSL Hardware Acceleration not yet implemented */
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+ /***** END CONFIG_IDF_TARGET_ESP32H2 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP8266)
+ #define WOLFSSL_ESP8266
+
+ /* There's no hardware encryption on the ESP8266 */
+ /* Consider using the ESP32-C2/C3/C6
+ * See https://www.espressif.com/en/products/socs/esp32-c2 */
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+ /***** END CONFIG_IDF_TARGET_ESP266 *****/
+
+#elif defined(CONFIG_IDF_TARGET_ESP8684)
+ /* There's no Hardware Acceleration available on ESP8684 */
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+ /***** END CONFIG_IDF_TARGET_ESP8684 *****/
+
+#else
+ /* Anything else encountered, disable HW accleration */
+ #warning "Unexpected CONFIG_IDF_TARGET_NN value"
+ #define NO_ESP32_CRYPT
+ #define NO_WOLFSSL_ESP32_CRYPT_HASH
+ #define NO_WOLFSSL_ESP32_CRYPT_AES
+ #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
+#endif /* CONFIG_IDF_TARGET Check */
+
+/* RSA primitive specific definition, listed AFTER the Chipset detection */
+#if defined(WOLFSSL_ESP32) || defined(WOLFSSL_ESPWROOM32SE)
+ /* Consider USE_FAST_MATH and SMALL_STACK */
+
+ #ifndef NO_RSA
+ #define ESP32_USE_RSA_PRIMITIVE
+
+ #if defined(CONFIG_IDF_TARGET_ESP32)
+ #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE
+ #if CONFIG_ESP_MAIN_TASK_STACK_SIZE < 10500
+ #warning "RSA may be difficult with less than 10KB Stack "/
+ #endif
+ #endif
+
+ /* NOTE HW unreliable for small values! */
+ /* threshold for performance adjustment for HW primitive use */
+ /* X bits of G^X mod P greater than */
+ #undef ESP_RSA_EXPT_XBITS
+ #define ESP_RSA_EXPT_XBITS 32
+
+ /* X and Y of X * Y mod P greater than */
+ #undef ESP_RSA_MULM_BITS
+ #define ESP_RSA_MULM_BITS 16
+ #endif
+ #endif
+#endif
+
+/* Debug options:
+See wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h for details on debug options
+
+#define ESP_VERIFY_MEMBLOCK
+#define DEBUG_WOLFSSL
+#define DEBUG_WOLFSSL_VERBOSE
+#define DEBUG_WOLFSSL_SHA_MUTEX
+#define WOLFSSL_ESP32_CRYPT_DEBUG
+#define WOLFSSL_ESP32_CRYPT_HASH_SHA224_DEBUG
+#define NO_RECOVER_SOFTWARE_CALC
+#define WOLFSSL_TEST_STRAY 1
+#define USE_ESP_DPORT_ACCESS_READ_BUFFER
+#define WOLFSSL_ESP32_HW_LOCK_DEBUG
+#define WOLFSSL_DEBUG_ESP_RSA_MULM_BITS
+#define ESP_DISABLE_HW_TASK_LOCK
+
+See wolfcrypt/benchmark/benchmark.c for debug and other settings:
+
+Turn on benchmark timing debugging (CPU Cycles, RTOS ticks, etc)
+#define DEBUG_WOLFSSL_BENCHMARK_TIMING
+
+Turn on timer debugging (used when CPU cycles not available)
+#define WOLFSSL_BENCHMARK_TIMER_DEBUG
+*/
+
+/* Pause in a loop rather than exit. */
+#define WOLFSSL_ESPIDF_ERROR_PAUSE
+
+#define WOLFSSL_HW_METRICS
+
+/* for test.c */
+/* #define HASH_SIZE_LIMIT */
+
+/* Optionally turn off HW math checks */
+/* #define NO_HW_MATH_TEST */
+
+/* Optionally include alternate HW test library: alt_hw_test.h */
+/* When enabling, the ./components/wolfssl/CMakeLists.txt file
+ * will need the name of the library in the idf_component_register
+ * for the PRIV_REQUIRES list. */
+/* #define INCLUDE_ALT_HW_TEST */
+
+/* optionally turn off individual math HW acceleration features */
+
+/* Turn off Large Number ESP32 HW Multiplication:
+** [Z = X * Y] in esp_mp_mul() */
+/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
+
+/* Turn off Large Number ESP32 HW Modular Exponentiation:
+** [Z = X^Y mod M] in esp_mp_exptmod() */
+/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
+
+/* Turn off Large Number ESP32 HW Modular Multiplication
+** [Z = X * Y mod M] in esp_mp_mulmod() */
+/* #define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
+
+
+/* used by benchmark: */
+#define WOLFSSL_PUBLIC_MP
+
+/* when turning on ECC508 / ECC608 support
+#define WOLFSSL_ESPWROOM32SE
+#define HAVE_PK_CALLBACKS
+#define WOLFSSL_ATECC508A
+#define ATCA_WOLFSSL
+*/
+
+/***************************** Certificate Macros *****************************
+ *
+ * The section below defines macros used in typically all of the wolfSSL
+ * examples such as the client and server for certs stored in header files.
+ *
+ * There are various certificate examples in this header file:
+ * https://github.com/wolfSSL/wolfssl/blob/master/wolfssl/certs_test.h
+ *
+ * To use the sets of macros below, define *one* of these:
+ *
+ * USE_CERT_BUFFERS_1024 - ECC 1024 bit encoded ASN1
+ * USE_CERT_BUFFERS_2048 - RSA 2048 bit encoded ASN1
+ * WOLFSSL_SM[2,3,4] - SM Ciphers
+ *
+ * For example: define USE_CERT_BUFFERS_2048 to use CA Certs used in this
+ * wolfSSL function for the `ca_cert_der_2048` buffer, size and types:
+ *
+ * ret = wolfSSL_CTX_load_verify_buffer(ctx,
+ * CTX_CA_CERT,
+ * CTX_CA_CERT_SIZE,
+ * CTX_CA_CERT_TYPE);
+ *
+ * See https://www.wolfssl.com/documentation/manuals/wolfssl/group__CertsKeys.html#function-wolfssl_ctx_load_verify_buffer
+ *
+ * In this case the CTX_CA_CERT will be defined as `ca_cert_der_2048` as
+ * defined here: https://github.com/wolfSSL/wolfssl/blob/master/wolfssl/certs_test.h
+ *
+ * The CTX_CA_CERT_SIZE and CTX_CA_CERT_TYPE are similarly used to reference
+ * array size and cert type respectively.
+ *
+ * Similarly for loading the private client key:
+ *
+ * ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
+ * CTX_CLIENT_KEY,
+ * CTX_CLIENT_KEY_SIZE,
+ * CTX_CLIENT_KEY_TYPE);
+ *
+ * see https://www.wolfssl.com/documentation/manuals/wolfssl/group__CertsKeys.html#function-wolfssl_ctx_use_privatekey_buffer
+ *
+ * Similarly, the other macros are for server certificates and keys:
+ * `CTX_SERVER_CERT` and `CTX_SERVER_KEY` are available.
+ *
+ * The certificate and key names are typically `static const unsigned char`
+ * arrays. The [NAME]_size are typically `sizeof([array name])`, and the types
+ * are the known wolfSSL encoding type integers (e.g. WOLFSSL_FILETYPE_PEM).
+ *
+ * See `SSL_FILETYPE_[name]` in
+ * https://github.com/wolfSSL/wolfssl/blob/master/wolfssl/ssl.h
+ *
+ * See Abstract Syntax Notation One (ASN.1) in:
+ * https://github.com/wolfSSL/wolfssl/blob/master/wolfssl/wolfcrypt/asn.h
+ *
+ * Optional SM4 Ciphers:
+ *
+ * Although the SM ciphers are shown here, the `certs_test_sm.h` may not yet
+ * be available. See:
+ * https://github.com/wolfSSL/wolfssl/pull/6825
+ * https://github.com/wolfSSL/wolfsm
+ *
+ * Uncomment these 3 macros to enable the SM Ciphers and use the macros below.
+ */
+
+/*
+#define WOLFSSL_SM2
+#define WOLFSSL_SM3
+#define WOLFSSL_SM4
+*/
+
+/* Conditional macros used in wolfSSL TLS client and server examples */
+#if defined(WOLFSSL_SM2) || defined(WOLFSSL_SM3) || defined(WOLFSSL_SM4)
+ #include
+ #define CTX_CA_CERT root_sm2
+ #define CTX_CA_CERT_SIZE sizeof_root_sm2
+ #define CTX_CA_CERT_TYPE WOLFSSL_FILETYPE_PEM
+ #define CTX_SERVER_CERT server_sm2
+ #define CTX_SERVER_CERT_SIZE sizeof_server_sm2
+ #define CTX_SERVER_CERT_TYPE WOLFSSL_FILETYPE_PEM
+ #define CTX_SERVER_KEY server_sm2_priv
+ #define CTX_SERVER_KEY_SIZE sizeof_server_sm2_priv
+ #define CTX_SERVER_KEY_TYPE WOLFSSL_FILETYPE_PEM
+
+ #undef WOLFSSL_BASE16
+ #define WOLFSSL_BASE16
+#else
+ #if defined(USE_CERT_BUFFERS_2048)
+ /* Be sure to include in app when using example certs: */
+ /* #include */
+ #define CTX_CA_CERT ca_cert_der_2048
+ #define CTX_CA_CERT_SIZE sizeof_ca_cert_der_2048
+ #define CTX_CA_CERT_TYPE WOLFSSL_FILETYPE_ASN1
+
+ #define CTX_SERVER_CERT server_cert_der_2048
+ #define CTX_SERVER_CERT_SIZE sizeof_server_cert_der_2048
+ #define CTX_SERVER_CERT_TYPE WOLFSSL_FILETYPE_ASN1
+ #define CTX_SERVER_KEY server_key_der_2048
+ #define CTX_SERVER_KEY_SIZE sizeof_server_key_der_2048
+ #define CTX_SERVER_KEY_TYPE WOLFSSL_FILETYPE_ASN1
+
+ #define CTX_CLIENT_CERT client_cert_der_2048
+ #define CTX_CLIENT_CERT_SIZE sizeof_client_cert_der_2048
+ #define CTX_CLIENT_CERT_TYPE WOLFSSL_FILETYPE_ASN1
+ #define CTX_CLIENT_KEY client_key_der_2048
+ #define CTX_CLIENT_KEY_SIZE sizeof_client_key_der_2048
+ #define CTX_CLIENT_KEY_TYPE WOLFSSL_FILETYPE_ASN1
+
+ #elif defined(USE_CERT_BUFFERS_1024)
+ /* Be sure to include in app when using example certs: */
+ /* #include */
+ #define CTX_CA_CERT ca_cert_der_1024
+ #define CTX_CA_CERT_SIZE sizeof_ca_cert_der_1024
+ #define CTX_CA_CERT_TYPE WOLFSSL_FILETYPE_ASN1
+
+ #define CTX_CLIENT_CERT client_cert_der_1024
+ #define CTX_CLIENT_CERT_SIZE sizeof_client_cert_der_1024
+ #define CTX_CLIENT_CERT_TYPE WOLFSSL_FILETYPE_ASN1
+ #define CTX_CLIENT_KEY client_key_der_1024
+ #define CTX_CLIENT_KEY_SIZE sizeof_client_key_der_1024
+ #define CTX_CLIENT_KEY_TYPE WOLFSSL_FILETYPE_ASN1
+
+ #define CTX_SERVER_CERT server_cert_der_1024
+ #define CTX_SERVER_CERT_SIZE sizeof_server_cert_der_1024
+ #define CTX_SERVER_CERT_TYPE WOLFSSL_FILETYPE_ASN1
+ #define CTX_SERVER_KEY server_key_der_1024
+ #define CTX_SERVER_KEY_SIZE sizeof_server_key_der_1024
+ #define CTX_SERVER_KEY_TYPE WOLFSSL_FILETYPE_ASN1
+ #else
+ /* Optionally define custom cert arrays, sizes, and types here */
+ #error "Must define USE_CERT_BUFFERS_2048 or USE_CERT_BUFFERS_1024"
+ #endif
+#endif /* Conditional key and cert constant names */
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* */
+/* wolfTPM */
+/* */
+/*****************************************************************************/
+/*****************************************************************************/
+
+/* How many main app test loop interations? */
+#define WOLFTPM_MAIN_TEST_ITERATIONS 100
+
+/* WOLFTPM_ADV_IO allows callback code in tpm_io_espressif.c */
+#define WOLFTPM_ADV_IO
+
+/* Choices are I2C or SPI*/
+/* WOLFTPM_I2C or not; when not defined, assumes SPI. */
+#define WOLFTPM_I2C
+
+/* Enable the wolfTPM example HAL in tpm_io.h */
+#define WOLFTPM_EXAMPLE_HAL
+
+/* Include the respective hal/tmp_io_NNN file, in our case: tpm_io_espressif */
+#define WOLFTPM_INCLUDE_IO_FILE
+
+/* The default TPM_TIMEOUT_TRIES is 1,000,000 but can be overridden.
+ * A value of 10000 is much more appropriate for the ESP32: */
+#define TPM_TIMEOUT_TRIES 10000
+
+/* If not defined here, TPM_I2C_TRIES is set to a default value of 10 */
+/* #define TPM_I2C_TRIES 10 */
+
+/* If not defined here, I2C_MASTER_FREQ_HZ is 100000
+ * Do not exceed a value of 400000 */
+/* #define I2C_MASTER_FREQ_HZ 100000 */
+
+/* Examples may have a main() function, we'll have oour own: */
+#define NO_MAIN_DRIVER
+
+/* I2C GPIO settings are defined in idf.py menuconfig
+ *
+ * CONFIG_I2C_MASTER_SCL (default SCL GPIO pin is 19)
+ * CONFIG_I2C_MASTER_SDA (default SDA GPIO pin is 18)
+ */
+
+/* The default I2C_MASTER_NUM is 0 but can be overridden: */
+/* #define I2C_MASTER_NUM 0 */
+
+/* I2C_MASTER_FREQ_HZ notes:
+ *
+ * Although the Infineon supports higher speeds, the ESP32 does not.
+ *
+ * ESP32 supports both I2C Standard-mode (Sm) and Fast-mode (Fm) which
+ * can go up to 100KHz and 400KHz respectively.
+ *
+ * Do not set this value higher than 400000.
+ *
+ * This is the value assigned to ESP32 i2c_config_t: master.clk_speed */
+#define I2C_MASTER_FREQ_HZ 100000
+
+/* Beware that delays in sending data to UART may affect I2C timing and
+ * cause errors. Debug with caution. Debug options available: */
+/* #define WOLFTPM_DEBUG_IO */
+
+/* Optionally disable printf */
+/* #define WOLFSSL_NOPRINTF */
+
+#ifdef WOLFSSL_ESPIDF
+ #include
+ #define ESP_LOG_TAG "tpm2"
+ #ifndef WOLFSSL_NOPRINTF
+ #define XPRINTF(...) ESP_LOGI("tpm", __VA_ARGS__)
+ #else
+ #define printf(...) {}
+ #endif
+#else
+ #include
+#endif
diff --git a/IDE/Espressif/components/wolftpm/CMakeLists.txt b/IDE/Espressif/components/wolftpm/CMakeLists.txt
new file mode 100644
index 00000000..a677a18e
--- /dev/null
+++ b/IDE/Espressif/components/wolftpm/CMakeLists.txt
@@ -0,0 +1,601 @@
+# wolfTPM cmake for Espressif component
+#
+# Copyright (C) 2006-2024 wolfSSL Inc.
+#
+# This file is part of wolfTPM.
+#
+# wolfTPM 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.
+#
+# wolfTPM 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
+#
+# Version 5.6.6.1 template update
+#
+# See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html
+#
+
+cmake_minimum_required(VERSION 3.16)
+
+set(VERBOSE_COMPONENT_MESSAGES 1)
+
+# The scope of this CMAKE_C_FLAGS is just this component:
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS -DWOLFTPM_USER_SETTINGS")
+
+set(CMAKE_CURRENT_SOURCE_DIR ".")
+set(COMPONENT_REQUIRES wolfssl driver) # "driver" includes the I2C API
+
+# Optionally set your source to wolfTPM in your project CMakeLists.txt like this:
+# set(WOLFTPM_ROOT "c:/test/my_wolftpm" )
+
+if ( "${WOLFTPM_ROOT}" STREQUAL "")
+ set(WOLFTPM_ROOT "$ENV{WOLFTPM_ROOT}" )
+endif()
+# Optional compiler definitions to help with system name detection (typically printed by app diagnostics)
+if(VERBOSE_COMPONENT_MESSAGES)
+ 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()
+endif() # End optional WOLFSSL_CMAKE_SYSTEM_NAME
+
+message(STATUS "CONFIG_TARGET_PLATFORM = ${CONFIG_TARGET_PLATFORM}")
+
+# Check that there are no conflicting wolfTPM components
+# The ESP Registry Component will be in ./managed_components/wolftpm__wolftpm
+# The local component wolfTPM directory will be in ./components/wolftpm
+if( EXISTS "${CMAKE_HOME_DIRECTORY}/managed_components/wolftpm__wolftpm" AND EXISTS "${CMAKE_HOME_DIRECTORY}/components/wolftpm" )
+ # 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/wolftpm__wolftpm" EXCLUDE_FROM_ALL)
+ # add_subdirectory("${CMAKE_HOME_DIRECTORY}/managed_components/wolftpm__wolftpm/include" EXCLUDE_FROM_ALL)
+ # So we'll error out and let the user decide how to proceed:
+ message(WARNING "\nFound wolfTPM components in\n"
+ "./managed_components/wolftpm__wolftpm\n"
+ "and\n"
+ "./components/wolftpm\n"
+ "in project directory: \n"
+ "${CMAKE_HOME_DIRECTORY}")
+ message(FATAL_ERROR "\nPlease use either the ESP Registry Managed Component or the wolfTPM component directory but not both.\n"
+ "If removing the ./managed_components/wolftpm__wolftpm directory, remember to also remove "
+ "or rename the idf_component.yml file typically found in ./main/")
+else()
+ message(STATUS "No conflicting wolfTPM components found.")
+endif()
+
+
+# Don't include lwip requirement for benchmark and test apps.
+# if( ("${CMAKE_PROJECT_NAME}" STREQUAL "wolfssl_benchmark") OR ("${CMAKE_PROJECT_NAME}" STREQUAL "wolfssl_test") )
+# message(STATUS "Not including lwip for ${CMAKE_PROJECT_NAME}")
+# else()
+# # benchmark and test do not need wifi, everything else probably does:
+# set(COMPONENT_REQUIRES lwip) # we typically don't need lwip directly in wolfssl component
+# endif()
+
+# find the user name to search for possible "wolftpm-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}")
+
+if( "$ENV{IDF_PATH}" STREQUAL "" )
+ message(FATAL_ERROR "IDF_PATH Environment variable not set!")
+else()
+ string(REPLACE "\\" "/" THIS_IDF_PATH "$ENV{IDF_PATH}")
+endif()
+
+# COMPONENT_NAME = wolftpm
+# 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 wolftpm in top-level project CMakelists.txt:
+# set(WOLFTPM_ROOT "C:/some path/with/spaces")
+# set(WOLFTPM_ROOT "c:/workspace/wolftpm-[username]")
+# set(WOLFTPM_ROOT "/mnt/c/some path/with/spaces")
+# or use this logic to assign value from Environment Variable WOLFTPM_ROOT,
+# or assume this is an example 7 subdirectories below:
+
+# We are typically in [root]/IDE/Espressif/components/wolftpm
+# The root of wolfTPM is 4 directories up from here:
+
+# function: IS_WOLFTPM_SOURCE
+# parameter: DIRECTORY_PARAMETER - the directory to test
+# output: RESULT = contains contents of DIRECTORY_PARAMETER for wolftpm directory, otherwise blank.
+function(IS_WOLFTPM_SOURCE DIRECTORY_PARAMETER RESULT)
+ if (EXISTS "${DIRECTORY_PARAMETER}/wolftpm/tpm2.h")
+ set(${RESULT} "${DIRECTORY_PARAMETER}" PARENT_SCOPE)
+ else()
+ set(${RESULT} "" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# *********************************************************************************************
+# function: FIND_WOLFTPM_DIRECTORY
+# parameter: OUTPUT_FOUND_WOLFTPM_DIRECTORY contains root of source code, otherwise blank
+#
+# Example usage:
+# FIND_WOLFTPM_DIRECTORY(WOLFTPM_ROOT)
+# *********************************************************************************************
+function(FIND_WOLFTPM_DIRECTORY OUTPUT_FOUND_WOLFTPM_DIRECTORY)
+ message(STATUS "Starting FIND_WOLFTPM_DIRECTORY: ${${OUTPUT_FOUND_WOLFTPM_DIRECTORY}}")
+
+ if ( "${${OUTPUT_FOUND_WOLFTPM_DIRECTORY}}" STREQUAL "" )
+ set(CURRENT_SEARCH_DIR "$ENV{WOLFTPM_ROOT}")
+ if( "${CURRENT_SEARCH_DIR}" STREQUAL "" )
+ message(STATUS "The WOLFTPM_ROOT environment variable is not set. Searching...")
+ else()
+ get_filename_component(CURRENT_SEARCH_DIR "$ENV{WOLFTPM_ROOT}" ABSOLUTE)
+ IS_WOLFTPM_SOURCE("${CURRENT_SEARCH_DIR}" FOUND_WOLFTPM)
+ if( FOUND_WOLFTPM )
+ message(STATUS "Found WOLFTPM_ROOT via Environment Variable:")
+ else()
+ message(FATAL_ERROR "WOLFTPM_ROOT Environment Variable defined, but path not found:")
+ message(STATUS "$ENV{WOLFTPM_ROOT}")
+ endif()
+ endif()
+ else()
+ get_filename_component(CURRENT_SEARCH_DIR "${${OUTPUT_FOUND_WOLFTPM_DIRECTORY}}" ABSOLUTE)
+ IS_WOLFTPM_SOURCE("${CURRENT_SEARCH_DIR}" FOUND_WOLFTPM)
+ if( FOUND_WOLFTPM )
+ message(STATUS "Found WOLFTPM_ROOT via prior specification.")
+ else()
+ message(FATAL_ERROR "WOLFTPM_ROOT Variable defined, but path not found: ${${OUTPUT_FOUND_WOLFTPM_DIRECTORY}}")
+ endif()
+ endif()
+
+
+ # we'll start in the CMAKE_CURRENT_SOURCE_DIR, typically [something]/projectname/components/wolftpm
+ message(STATUS "CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")
+ get_filename_component(CURRENT_SEARCH_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
+ message(STATUS "CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ string(LENGTH ${CURRENT_SEARCH_DIR} CURRENT_SEARCH_DIR_LENGTH)
+
+ # loop through all the parents, looking for wolftpm
+ while(NOT CURRENT_SEARCH_DIR STREQUAL "/" AND NOT CURRENT_SEARCH_DIR STREQUAL "" )
+ string(LENGTH ${CURRENT_SEARCH_DIR} CURRENT_SEARCH_DIR_LENGTH)
+ # wolftpm may simply be in a parent directory, such as for local examples in wolftpm repo
+ IS_WOLFTPM_SOURCE("${CURRENT_SEARCH_DIR}" FOUND_WOLFTPM)
+ if( FOUND_WOLFTPM )
+ message(STATUS "Found wolftpm in CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ set(${OUTPUT_FOUND_WOLFTPM_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+
+ # Maintain CURRENT_SEARCH_DIR, but check various suffixes with CURRENT_SEARCH_DIR_ALT
+ if( THIS_USER )
+ # Check for "wolftpm-[username]" subdirectory as we recurse up the directory tree
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolftpm-${THIS_USER})
+ message(STATUS "Looking in ${CURRENT_SEARCH_DIR_ALT}")
+
+ IS_WOLFTPM_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFTPM )
+ if ( FOUND_WOLFTPM )
+ message(STATUS "Found wolftpm in user-suffix CURRENT_SEARCH_DIR_ALT = ${CURRENT_SEARCH_DIR_ALT}")
+ set(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR_ALT}")
+ set(${OUTPUT_FOUND_WOLFTPM_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+
+ if ( FOUND_WOLFTPM )
+ # if we already found the source, skip attempt of "wolftpm-master"
+ else()
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolftpm-master)
+ message(STATUS "Looking in ${CURRENT_SEARCH_DIR_ALT}")
+
+ IS_WOLFTPM_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFTPM )
+ if ( FOUND_WOLFTPM )
+ message(STATUS "Found wolftpm in master-suffix CURRENT_SEARCH_DIR_ALT = ${CURRENT_SEARCH_DIR_ALT}")
+ set(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR_ALT}")
+ set(${OUTPUT_FOUND_WOLFTPM_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+
+ if ( FOUND_WOLFTPM )
+ # if we already found the source, skip attempt of "wolftpm"
+ else()
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolftpm)
+ message(STATUS "Looking in ${CURRENT_SEARCH_DIR_ALT}")
+
+ IS_WOLFTPM_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFTPM )
+ if ( FOUND_WOLFTPM )
+ message(STATUS "Found wolftpm in CURRENT_SEARCH_DIR_ALT = ${CURRENT_SEARCH_DIR_ALT}")
+ set(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR_ALT}")
+ set(${OUTPUT_FOUND_WOLFTPM_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+
+ # Next check for no user suffix "wolftpm" subdirectory as we recurse up the directory tree
+ set(CURRENT_SEARCH_DIR_ALT ${CURRENT_SEARCH_DIR}/wolftpm)
+ # if(EXISTS ${CURRENT_SEARCH_DIR} AND IS_DIRECTORY ${CURRENT_SEARCH_DIR} AND EXISTS "${CURRENT_SEARCH_DIR}/wolfcrypt/src")
+ IS_WOLFTPM_SOURCE("${CURRENT_SEARCH_DIR_ALT}" FOUND_WOLFTPM )
+ if ( FOUND_WOLFTPM )
+ message(STATUS "Found wolftpm in CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ set(${OUTPUT_FOUND_WOLFTPM_DIRECTORY} ${CURRENT_SEARCH_DIR} PARENT_SCOPE)
+ return()
+ endif()
+
+ # Move up one directory level
+ set(PRIOR_SEARCH_DIR "${CURRENT_SEARCH_DIR}")
+ get_filename_component(CURRENT_SEARCH_DIR "${CURRENT_SEARCH_DIR}" DIRECTORY)
+ message(STATUS "Next CURRENT_SEARCH_DIR = ${CURRENT_SEARCH_DIR}")
+ if( "${PRIOR_SEARCH_DIR}" STREQUAL "${CURRENT_SEARCH_DIR}" )
+ # When the parent is current directory, cannot go any further. We didn't find wolftpm.
+ # When the search directory is empty, we'll give up.
+ set(CURRENT_SEARCH_DIR "")
+ endif()
+ endwhile()
+
+ # If not found, set the output variable to empty before exiting
+ set(${OUTPUT_FOUND_WOLFTPM_DIRECTORY} "" PARENT_SCOPE)
+endfunction()
+
+
+# Example usage:
+#
+# Simply find the WOLFTPM_DIRECTORY by searching parent directories:
+# FIND_WOLFTPM_DIRECTORY(WOLFTPM_ROOT)
+#
+
+if(CMAKE_BUILD_EARLY_EXPANSION)
+ message(STATUS "wolftpm component CMAKE_BUILD_EARLY_EXPANSION:")
+ idf_component_register(
+ REQUIRES "${COMPONENT_REQUIRES}"
+ PRIV_REQUIRES # esp_hw_support
+ )
+
+else()
+ # not CMAKE_BUILD_EARLY_EXPANSION
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolftpm component config:")
+ message(STATUS "************************************************************************************************")
+
+# if ( "${CONFIG_TARGET_PLATFORM}" STREQUAL "esp8266")
+# # There's no esp_timer, no driver components for the ESP8266
+# set(THIS_INCLUDE_TIMER "")
+# set(THIS_INCLUDE_DRIVER "")
+# else()
+# set(THIS_INCLUDE_TIMER "esp_timer")
+# set(THIS_INCLUDE_DRIVER "driver")
+# endif()
+
+ # search for wolfTPM
+ if(WOLFTPM_ROOT)
+ IS_WOLFTPM_SOURCE("${WOLFTPM_ROOT}" FOUND_WOLFTPM)
+ if(FOUND_WOLFTPM)
+ message(STATUS "Found WOLFTPM_ROOT via CMake specification.")
+ else()
+ # WOLFTPM_ROOT Path specified in CMakeLists.txt is not a valid path
+ message(FATAL_ERROR "WOLFTPM_ROOT CMake Variable defined, but path not found: ${WOLFTPM_ROOT}\n"
+ "Try correcting WOLFTPM_ROOT in your project CMakeFile.txt or setting environment variable.")
+ # Abort CMake after fatal error.
+ endif()
+ else()
+ message(STATUS "Searching for wolfTPM source code...")
+ FIND_WOLFTPM_DIRECTORY(WOLFTPM_ROOT)
+ endif()
+
+
+ if(WOLFTPM_ROOT)
+ message(STATUS "Confirmed wolftpm directory at: ${WOLFTPM_ROOT}")
+ else()
+ message(STATUS "Failed: wolftpm directory not found.")
+ # Abort. We need wolftpm _somewhere_.
+ message(FATAL_ERROR "Could not find wolftpm in any parent directory named wolftpm-${THIS_USER}, wolftpm-master, or wolftpm.\n"
+ "Try setting WOLFTPM_ROOT environment variable, cmake variable in project, copy source, or use managed components.")
+ # Abort CMake after fatal error.
+ endif()
+
+ set(INCLUDE_PATH ${WOLFTPM_ROOT})
+
+ set(COMPONENT_SRCDIRS "\"${WOLFTPM_ROOT}/src/\""
+ "\"${WOLFTPM_ROOT}/hal/\""
+ "\"${COMPONENT_DIR}/include/\""
+ ) # COMPONENT_SRCDIRS
+
+ message(STATUS "This COMPONENT_SRCDIRS = ${COMPONENT_SRCDIRS}")
+
+ # wolfTPM user_settings.h is in the local project in the wolfssl component.
+
+ set(WOLFTPM_PROJECT_DIR "${CMAKE_HOME_DIRECTORY}/components/wolftpm")
+ string(REPLACE "/" "//" STR_WOLFTPM_PROJECT_DIR "${WOLFTPM_PROJECT_DIR}")
+
+ # Espressif may take several passes through this makefile. Check to see if we found IDF
+ string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "" WOLFTPM_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 wolfssl and/or wolfssh components.
+ #
+ if( EXISTS "${WOLFTPM_PROJECT_DIR}" AND EXISTS "$ENV{IDF_PATH}/components/wolftpm/" )
+ #
+ # wolfTPM 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/wolftpm in both local project and IDF_PATH")
+ message(STATUS "")
+ message(STATUS "To proceed: ")
+ message(STATUS "")
+ message(STATUS "Remove either the local project component: ${WOLFTPM_PROJECT_DIR} ")
+ message(STATUS "or the Espressif shared component installed at: $ENV{IDF_PATH}/components/wolfssl/ ")
+ message(STATUS "")
+ message(STATUS "")
+ message(STATUS "**************************************************************************************")
+ message(STATUS "")
+
+ message(FATAL_ERROR "Please use wolfTPM in either local project or Espressif components, but not both.")
+ # Abort CMake after fatal error.
+
+ # 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/wolftpm/" )
+ #
+ # wolfTPM found in ESP-IDF components and is assumed to be already configured in user_settings.h via setup.
+ #
+ message(STATUS "")
+ message(STATUS "Using components/wolftpm in IDF_PATH = $ENV{IDF_PATH}")
+ message(STATUS "")
+ else()
+ #
+ # wolfTPM is not an ESP-IDF component.
+ # We need to now determine if it is local and if so if it is part of the wolfTPM repo,
+ # or if wolfTPM is simply installed as a local component.
+ #
+
+ if( EXISTS "${WOLFTPM_PROJECT_DIR}" )
+ #
+ # wolfTPM found in local project.
+ #
+ if( EXISTS "${WOLFTPM_PROJECT_DIR}/src/" )
+ message(STATUS "")
+ message(STATUS "Using installed project ./components/wolftpm in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+ #
+ # Note we already checked above and confirmed there's not another wolfTPM 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 wolfTPM not installed in local project
+ #
+ # This is the developer repo mode. wolfTPM will be assumed to be not installed to ESP-IDF nor local project
+ # In this configuration, we are likely running a wolfTPM example found directly in the repo.
+ #
+ message(STATUS "")
+ message(STATUS "Using developer repo ./components/wolftpm in CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}")
+ message(STATUS "")
+
+ endif()
+
+ else()
+ # we did not find a ./components/wolfssl/include/ directory from this pass of cmake.
+ if($WOLFTPM_FOUND_IDF)
+ message(STATUS "")
+ message(STATUS "WARNING: wolfTPM not found.")
+ message(STATUS "")
+ else()
+ # probably needs to be re-parsed by Espressif
+ message(STATUS "wolfTPM found IDF. Project Source:${PROJECT_SOURCE_DIR}")
+ endif() # else we have not found ESP-IDF yet
+ endif() # else not a local wolfTPM component
+
+ endif() #else not an ESP-IDF component
+ endif() # else not local copy and EDP-IDF wolfTPM
+
+
+ # 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 "\\" "/" WOLFTPM_ROOT ${WOLFTPM_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()
+
+ # wolftpm-specific include directories
+ set(COMPONENT_ADD_INCLUDEDIRS
+ "."
+ "./include"
+ "\"${WOLFTPM_ROOT}\""
+ "\"${COMPONENT_DIR}/include\""
+ )
+
+# If any files are known to be included elsewhere, or not used for Espressif
+# set(COMPONENT_SRCEXCLUDE
+# )
+
+ 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}"
+ )
+
+ # Some optional diagnostics. Verbose ones are truncated.
+ if (VERBOSE_COMPONENT_MESSAGES)
+ get_cmake_property(_variableNames VARIABLES)
+ list (SORT _variableNames)
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES BEGIN")
+ message(STATUS "")
+ foreach (_variableName ${_variableNames})
+ if ( ("${_variableName}" STREQUAL "bootloader_binary_files")
+ OR ("${_variableName}" STREQUAL "Component paths")
+ OR ("${_variableName}" STREQUAL "component_targets")
+ OR ("${_variableName}" STREQUAL "__COMPONENT_TARGETS")
+ OR ("${_variableName}" STREQUAL "CONFIGS_LIST")
+ OR ("${_variableName}" STREQUAL "__CONFIG_VARIABLES")
+ OR ("${_variableName}" STREQUAL "val")
+ OR ("${_variableName}" MATCHES "^__idf_")
+ )
+ # Truncate the displayed value:
+ string(SUBSTRING "${${_variableName}}" 0 70 truncatedValue)
+ message(STATUS "${_variableName} = ${truncatedValue} ... (truncated)")
+ else()
+ message(STATUS "${_variableName}=${${_variableName}}")
+ endif()
+ endforeach()
+ message(STATUS "")
+ message(STATUS "ALL VARIABLES END")
+ message(STATUS "")
+ endif()
+
+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 "${WOLFTPM_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 ${WOLFTPM_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 ${WOLFTPM_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 ${WOLFTPM_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 ${WOLFTPM_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 ${WOLFTPM_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}")
+
+ LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_VERSION_WOLFTPM_ROOT "${WOLFTPM_ROOT}" "${TMP_RES}")
+
+ message(STATUS "************************************************************************************************")
+ message(STATUS "wolfssl component config complete!")
+ message(STATUS "************************************************************************************************")
+endif()
diff --git a/IDE/Espressif/components/wolftpm/include/README.md b/IDE/Espressif/components/wolftpm/include/README.md
new file mode 100644
index 00000000..c84a0138
--- /dev/null
+++ b/IDE/Espressif/components/wolftpm/include/README.md
@@ -0,0 +1,4 @@
+# wolfTPM include
+
+Please see the wolfSSL user_settings.h for wolfTPM configuration settings.
+
diff --git a/IDE/Espressif/include.am b/IDE/Espressif/include.am
new file mode 100644
index 00000000..ce89cb1d
--- /dev/null
+++ b/IDE/Espressif/include.am
@@ -0,0 +1,27 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+#
+# Don't list any config.h files here
+
+EXTRA_DIST+= IDE/Espressif/CMakeLists.txt
+EXTRA_DIST+= IDE/Espressif/README.md
+EXTRA_DIST+= IDE/Espressif/partitions_singleapp_large.csv
+EXTRA_DIST+= IDE/Espressif/sdkconfig.defaults
+
+# wolfSSL source code is not included here and must be available in separate directory.
+EXTRA_DIST+= IDE/Espressif/components/wolfssl/CMakeLists.txt
+EXTRA_DIST+= IDE/Espressif/components/wolfssl/include/user_settings.h
+
+# the wolfTPM source code used will typically be the parent of the IDE directory.
+EXTRA_DIST+= IDE/Espressif/components/wolftpm/CMakeLists.txt
+EXTRA_DIST+= IDE/Espressif/components/wolftpm/include/README.md
+
+# The example application.
+EXTRA_DIST+= IDE/Espressif/main/CMakeLists.txt
+EXTRA_DIST+= IDE/Espressif/main/Kconfig.projbuild
+EXTRA_DIST+= IDE/Espressif/main/main.c
+EXTRA_DIST+= IDE/Espressif/main/include/main.h
+
+# VisualGDB Project Files. See also https://github.com/wolfSSL/wolfssl/tree/master/IDE/Espressif/ESP-IDF/examples/template/VisualGDB
+EXTRA_DIST+= IDE/Espressif/VisualGDB/wolfssl_IDF_v5.2_ESP32.vgdbproj
diff --git a/IDE/Espressif/main/CMakeLists.txt b/IDE/Espressif/main/CMakeLists.txt
new file mode 100644
index 00000000..75ab4ca0
--- /dev/null
+++ b/IDE/Espressif/main/CMakeLists.txt
@@ -0,0 +1,105 @@
+# wolfSSL Espressif Example Project/main CMakeLists.txt
+# v1.0
+#
+# wolfssl template
+#
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS -DWOLFTPM_USER_SETTINGS")
+
+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()
+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"
+ "../../../examples/native/native_test.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/main/Kconfig.projbuild b/IDE/Espressif/main/Kconfig.projbuild
new file mode 100644
index 00000000..6e8476a0
--- /dev/null
+++ b/IDE/Espressif/main/Kconfig.projbuild
@@ -0,0 +1,21 @@
+menu "Example Configuration"
+
+ orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
+
+ config I2C_MASTER_SCL
+ int "SCL GPIO Num"
+ range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
+ default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
+ default 2
+ help
+ GPIO number for I2C Master clock line.
+
+ config I2C_MASTER_SDA
+ int "SDA GPIO Num"
+ range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
+ default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
+ default 1
+ help
+ GPIO number for I2C Master data line.
+
+endmenu
diff --git a/IDE/Espressif/main/include/main.h b/IDE/Espressif/main/include/main.h
new file mode 100644
index 00000000..76a22ac8
--- /dev/null
+++ b/IDE/Espressif/main/include/main.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * Copyright (C) 2006-2024 wolfSSL Inc.
+ *
+ * This file is part of wolfTPM.
+ *
+ * wolfTPM 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.
+ *
+ * wolfTPM 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_
+
+#endif
diff --git a/IDE/Espressif/main/main.c b/IDE/Espressif/main/main.c
new file mode 100644
index 00000000..c7cf4877
--- /dev/null
+++ b/IDE/Espressif/main/main.c
@@ -0,0 +1,102 @@
+/* wolftpm test main.c
+ *
+ * This file is part of wolfTPM.
+ *
+ * wolfTPM 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.
+ *
+ * wolfTPM 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
+ */
+
+/* Espressif */
+#include
+
+/* wolfSSL */
+/* Always include wolfcrypt/settings.h before any other wolfSSL file. */
+/* Reminder: settings.h pulls in user_settings.h; don't include it here. */
+#ifdef WOLFSSL_USER_SETTINGS
+ #include
+ #ifndef WOLFSSL_ESPIDF
+ #warning "Problem with wolfSSL user_settings."
+ #warning "Check components/wolfssl/include"
+ #endif
+ #include
+#else
+ /* Define WOLFSSL_USER_SETTINGS project wide for settings.h to include */
+ /* wolfSSL user settings in ./components/wolfssl/include/user_settings.h */
+ #error "Missing WOLFSSL_USER_SETTINGS in CMakeLists or Makefile:\
+ CFLAGS +=-DWOLFSSL_USER_SETTINGS"
+#endif
+
+/* wolfTPM */
+#ifdef WOLFTPM_USER_SETTINGS
+ /* See wolfSSL user_settings.h for wolfTPM configuration */
+#else
+ #include
+#endif
+#include
+
+/* project */
+#include
+#include "main.h"
+
+#ifndef WOLFTPM_MAIN_TEST_ITERATIONS
+ #define WOLFTPM_MAIN_TEST_ITERATIONS 1
+#endif
+
+static const char* const TAG = "wolfTPM main";
+
+void app_main(void)
+{
+ char mydata[1024];
+ int tests = WOLFTPM_MAIN_TEST_ITERATIONS;
+ esp_err_t ret = 0;
+
+#ifdef LIBWOLFTPM_VERSION_STRING
+ ESP_LOGI(TAG, "Hello wolfTPM version %s!", LIBWOLFTPM_VERSION_STRING);
+#else
+ ESP_LOGI(TAG, "Hello wolfTPM!");
+#endif
+
+#ifdef HAVE_VERSION_EXTENDED_INFO
+ ret = esp_ShowExtendedSystemInfo();
+#endif
+
+ do {
+ ret += TPM2_Native_TestArgs(mydata, 0, NULL);
+ if (tests > 1) {
+ ESP_LOGW(TAG, "*************************************************");
+ ESP_LOGW(TAG, "\n\n Proceeding to Test #%d of %d\n\n",
+ WOLFTPM_MAIN_TEST_ITERATIONS - tests + 2,
+ WOLFTPM_MAIN_TEST_ITERATIONS);
+ ESP_LOGW(TAG, "*************************************************");
+ ESP_LOGI(TAG, "Waiting to start next test iteration...\n\n");
+ vTaskDelay(5550);
+ }
+ } while (ret == 0 && (--tests > 0));
+
+#ifdef WOLFSSL_ESPIDF_VERBOSE_EXIT_MESSAGE
+ if (ret == 0) {
+ ESP_LOGI(TAG, WOLFSSL_ESPIDF_VERBOSE_EXIT_MESSAGE("Success!", ret));
+ }
+ else {
+ ESP_LOGE(TAG, WOLFSSL_ESPIDF_VERBOSE_EXIT_MESSAGE("Failed!", ret));
+ }
+#elif defined(WOLFSSL_ESPIDF_EXIT_MESSAGE)
+ ESP_LOGI(TAG, WOLFSSL_ESPIDF_EXIT_MESSAGE);
+#else
+ ESP_LOGI(TAG, "\n\nDone!"
+ "If running from idf.py monitor, press twice: Ctrl+]\n\n"
+ "WOLFSSL_COMPLETE\n" /* exit keyword for wolfssl_monitor.py */
+ );
+#endif
+}
diff --git a/IDE/Espressif/partitions_singleapp_large.csv b/IDE/Espressif/partitions_singleapp_large.csv
new file mode 100644
index 00000000..0b2fcd1a
--- /dev/null
+++ b/IDE/Espressif/partitions_singleapp_large.csv
@@ -0,0 +1,31 @@
+# to view: idf.py partition-table
+#
+# ESP-IDF Partition Table
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 24K,
+phy_init,data, phy, 0xf000, 4K,
+factory, app, factory, 0x10000, 1500K,
+
+
+# For other settings, see:
+# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html#creating-custom-tables
+#
+# Here is the summary printed for the "Single factory app, no OTA" configuration:
+#
+# # ESP-IDF Partition Table
+# # Name, Type, SubType, Offset, Size, Flags
+# nvs, data, nvs, 0x9000, 0x6000,
+# phy_init, data, phy, 0xf000, 0x1000,
+# factory, app, factory, 0x10000, 1M,
+#
+#
+# Here is the summary printed for the "Factory app, two OTA definitions" configuration:
+#
+# # ESP-IDF Partition Table
+# # Name, Type, SubType, Offset, Size, Flags
+# nvs, data, nvs, 0x9000, 0x4000,
+# otadata, data, ota, 0xd000, 0x2000,
+# phy_init, data, phy, 0xf000, 0x1000,
+# factory, app, factory, 0x10000, 1M,
+# ota_0, app, ota_0, 0x110000, 1M,
+# ota_1, app, ota_1, 0x210000, 1M,
diff --git a/IDE/Espressif/sdkconfig.defaults b/IDE/Espressif/sdkconfig.defaults
new file mode 100644
index 00000000..27a444c2
--- /dev/null
+++ b/IDE/Espressif/sdkconfig.defaults
@@ -0,0 +1,35 @@
+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=35840
+
+# Legacy stack size for older ESP-IDF versions
+CONFIG_MAIN_TASK_STACK_SIZE=35840
+
+#
+# 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
+
+#
+# Partition Table
+#
+# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
+CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
+# CONFIG_PARTITION_TABLE_TWO_OTA is not set
+# CONFIG_PARTITION_TABLE_CUSTOM is not set
+CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
+CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp_large.csv"
+CONFIG_PARTITION_TABLE_OFFSET=0x8000
+CONFIG_PARTITION_TABLE_MD5=y
+# end of Partition Table
diff --git a/IDE/include.am b/IDE/include.am
index f1ffefb6..3342b5b2 100644
--- a/IDE/include.am
+++ b/IDE/include.am
@@ -7,3 +7,4 @@ include IDE/OPENSTM32/include.am
include IDE/IAR-EWARM/include.am
include IDE/QNX/include.am
include IDE/VisualStudio/include.am
+include IDE/Espressif/include.am
diff --git a/examples/native/native_test.c b/examples/native/native_test.c
index 3602439e..04296053 100644
--- a/examples/native/native_test.c
+++ b/examples/native/native_test.c
@@ -769,7 +769,8 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
rc = TPM2_CreateLoaded(&cmdIn.createLoaded, &cmdOut.createLoaded);
if (rc == TPM_RC_SUCCESS) {
printf("TPM2_CreateLoaded: handle 0x%x pub %d, priv %d\n",
- cmdOut.createLoaded.objectHandle, cmdOut.createLoaded.outPublic.size,
+ (unsigned int)cmdOut.createLoaded.objectHandle,
+ cmdOut.createLoaded.outPublic.size,
cmdOut.createLoaded.outPrivate.size);
cmdIn.flushCtx.flushHandle = cmdOut.createLoaded.objectHandle;
TPM2_FlushContext(&cmdIn.flushCtx);
diff --git a/hal/include.am b/hal/include.am
index d198192a..eed3ed9a 100644
--- a/hal/include.am
+++ b/hal/include.am
@@ -6,6 +6,7 @@ src_libwolftpm_la_SOURCES += \
hal/tpm_io.c \
hal/tpm_io_atmel.c \
hal/tpm_io_barebox.c \
+ hal/tpm_io_espressif.c \
hal/tpm_io_linux.c \
hal/tpm_io_infineon.c \
hal/tpm_io_mmio.c \
diff --git a/hal/tpm_io.c b/hal/tpm_io.c
index c47ce879..8944805d 100644
--- a/hal/tpm_io.c
+++ b/hal/tpm_io.c
@@ -69,6 +69,8 @@
#include "hal/tpm_io_infineon.c"
#elif defined(WOLFTPM_MICROCHIP_HARMONY)
#include "hal/tpm_io_microchip.c"
+#elif defined(WOLFSSL_ESPIDF)
+#include "hal/tpm_io_espressif.c"
#endif
#if !defined(WOLFTPM_I2C) && !defined(WOLFTPM_MMIO)
@@ -144,6 +146,8 @@ int TPM2_IoCb(TPM2_CTX* ctx, INT32 isRead, UINT32 addr,
ret = TPM2_IoCb_STCubeMX_I2C(ctx, isRead, addr, buf, size, userCtx);
#elif defined(CY_USING_HAL)
ret = TPM2_IoCb_Infineon_I2C(ctx, isRead, addr, buf, size, userCtx);
+ #elif defined(WOLFSSL_ESPIDF)
+ ret = TPM2_IoCb_Espressif_I2C(ctx, isRead, addr, buf, size, userCtx);
#else
/* TODO: Add your platform here for HW I2C interface */
printf("Add your platform here for HW I2C interface\n");
@@ -205,7 +209,7 @@ int TPM2_IoCb(TPM2_CTX* ctx, const BYTE* txBuf, BYTE* rxBuf,
#endif
#ifdef WOLFTPM_DEBUG_IO
- printf("TPM2_IoCb: Ret %d, Sz %d\n", ret, xferSz);
+ printf("TPM2_IoCb: ret %d, Sz %d\n", ret, xferSz);
TPM2_PrintBin(txBuf, xferSz);
TPM2_PrintBin(rxBuf, xferSz);
#endif
diff --git a/hal/tpm_io.h b/hal/tpm_io.h
index eabb1b37..7d82de2d 100644
--- a/hal/tpm_io.h
+++ b/hal/tpm_io.h
@@ -85,6 +85,9 @@ WOLFTPM_LOCAL int TPM2_IoCb_STCubeMX_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
#elif defined(CY_USING_HAL)
WOLFTPM_LOCAL int TPM2_IoCb_Infineon_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
byte* buf, word16 size, void* userCtx);
+#elif defined(WOLFSSL_ESPIDF)
+WOLFTPM_LOCAL int TPM2_IoCb_Espressif_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
+ byte* buf, word16 size, void* userCtx);
#endif /* __linux__ */
#else /* SPI */
diff --git a/hal/tpm_io_espressif.c b/hal/tpm_io_espressif.c
new file mode 100644
index 00000000..8a003a45
--- /dev/null
+++ b/hal/tpm_io_espressif.c
@@ -0,0 +1,460 @@
+/* tpm_io_espressif.c
+ *
+ * Copyright (C) 2006-2024 wolfSSL Inc.
+ *
+ * This file is part of wolfTPM.
+ *
+ * wolfTPM 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.
+ *
+ * wolfTPM 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
+ */
+
+/* This example shows IO interfaces for Microchip micro-controllers using
+ * MPLAB X and Harmony
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include
+#endif
+
+#include
+#include
+#include "tpm_io.h"
+
+/*****************************************************************************/
+/* --- BEGIN IO Callback Logic -- */
+/*****************************************************************************/
+
+/* Included via tpm_io.c if WOLFTPM_INCLUDE_IO_FILE is defined */
+#ifdef WOLFTPM_INCLUDE_IO_FILE
+
+#ifdef WOLFSSL_ESPIDF
+
+/* Espressif */
+#include "sdkconfig.h"
+
+#define TAG "TPM_IO"
+
+#ifdef WOLFTPM_I2C
+
+#define I2C_READ_WAIT_TICKS (I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)
+#define I2C_WRITE_WAIT_TICKS (I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)
+
+/* To use I2C in wolfTPM, be sure the component cmake COMPONENT_REQUIRES
+ * variable includes "driver" (without quotes) for idf_component_register().
+ *
+ * See: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/i2c.html */
+#if ESP_IDF_VERSION_MAJOR >= 5 && ESP_IDF_VERSION_MINOR > 0
+ /* TODO we are forcing legacy mode, even though using v5.2 */
+ #define WOLFSSL_USE_LEGACY_I2C 1
+#else
+ #define WOLFSSL_USE_LEGACY_I2C 1
+#endif
+
+#if WOLFSSL_USE_LEGACY_I2C
+ /* Legacy Espressif I2C libraries
+ *
+ * "The legacy driver can't coexist with the new driver. Include i2c.h to
+ * use the legacy driver or the other two headers to use the new driver.
+ * Please keep in mind that the legacy driver is now deprecated and
+ * will be removed in future." */
+ #include
+#else
+ #include
+ #include
+#endif
+
+#ifndef CONFIG_SOC_I2C_SUPPORTED
+ #error "It appears I2C is not supported. Please check sdkconfig."
+#endif
+
+/* GPIO number used for I2C master clock */
+#ifdef CONFIG_I2C_MASTER_SCL
+ /* Yellow wire Clock */
+ #define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL
+#else
+ /* There should have been a Kconfig.projbuild file in the ./main
+ * directory to set I2C parameters in the sdkconfig project file. */
+ #error "Could not find CONFIG_I2C_MASTER_SCL definition."
+#endif
+
+/* GPIO number used for I2C master data */
+#ifdef CONFIG_I2C_MASTER_SDA
+ /* Orange wire */
+ #define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA
+#else
+ /* There should have been a Kconfig.projbuild file in the ./main
+ * directory to set I2C parameters in the sdkconfig project file. */
+ #error "Could not find CONFIG_I2C_MASTER_SDA definition."
+#endif
+
+/* I2C master i2c port number,
+ * the number of i2c peripheral interfaces available will depend on the chip */
+#ifndef I2C_MASTER_NUM
+ #define I2C_MASTER_NUM 0
+#endif
+
+/* I2C master clock frequency
+ * Typically, an I2C slave device has a 7-bit address or 10-bit address.
+ * ESP32 supports both I2C Standard-mode (Sm) and Fast-mode (Fm) which
+ * can go up to 100KHz and 400KHz respectively.
+ *
+ * The clock frequency of SCL in master mode
+ * should not be larger than 400 KHz. */
+#ifndef I2C_MASTER_FREQ_HZ
+ #define I2C_MASTER_FREQ_HZ 100000
+#endif
+
+/* I2C master doesn't need buffer, so disabled: */
+#define I2C_MASTER_TX_BUF_DISABLE 0
+
+/* I2C master doesn't need buffer, so disabled: */
+#define I2C_MASTER_RX_BUF_DISABLE 0
+
+/* Wait timeout, in milliseconds. Note: -1 means wait forever. */
+#ifndef I2C_MASTER_TIMEOUT_MS
+ #define I2C_MASTER_TIMEOUT_MS 25000
+#endif
+
+/* Infineon 9673 I2C at 0x2e */
+#define TPM2_INFINEON_9673_ADDR 0x2e
+
+/* I2C test sensor is an LM75 temperature sensor at 0x48 */
+#define LM75_SENSOR_ADDR 0x48
+
+#define DELETE_I2C_ON_ERROR 0
+
+/* Number of milliseconds to wait between write and read,
+ * used in esp_tpm_register_read() */
+#define WRITE_TO_READ_GUARD_TIME 2
+
+/* Number of milliseconds to wait after read.
+ * used in esp_tpm_register_read() */
+#define POST_READ_GUARD_TIME 2
+
+/* Number of milliseconds to wait after standard write.
+ * (see also write-then-read in esp_tpm_register_read, above) */
+#define POST_WRITE_GUARD_TIME 2
+
+/* Number of milliseconds to wait after read failure. */
+#define READ_RETRY_DELAY_TIME 2
+
+/* Number of milliseconds to wait after write failure. */
+#define WRITE_RETRY_DELAY_TIME 2
+
+/* Observed to have a value of 180 in i2c.c, rounded up for safety */
+#define I2C_TRANS_BUF_MINIMUM_SIZE 255
+
+#if 0
+ #define TPM2_I2C_ADDR LM75_SENSOR_ADDR
+#else
+ #define TPM2_I2C_ADDR TPM2_INFINEON_9673_ADDR
+#endif
+
+#ifndef TPM_I2C_TRIES
+ #define TPM_I2C_TRIES 10
+#endif
+
+static int _is_initialized_i2c = FALSE;
+
+#ifdef DEBUG_WOLFSSL_VERBOSE
+static esp_err_t show_binary(byte* theVar, size_t dataSz) {
+ char hex_buffer[(dataSz * 2) + 2];
+ word32 i;
+
+ ESP_LOGI(TAG, "*********************************************************");
+ for (i = 0; i < dataSz; i++) {
+ snprintf(&hex_buffer[i * 2], 3, "%02X", (unsigned char)theVar[i]);
+ }
+ ESP_LOGI("TAG", "%s", hex_buffer);
+ ESP_LOGI(TAG, "*********************************************************");
+ return ESP_OK;
+}
+#endif
+
+/* ESP-IDF I2C Master Initialization. Returns ESP result code. */
+static esp_err_t esp_i2c_master_init(void)
+{
+#if WOLFSSL_USE_LEGACY_I2C
+ i2c_config_t conf = { 0 };
+ int i2c_master_port = I2C_MASTER_NUM;
+ esp_err_t ret = ESP_OK;
+
+ /* I2C port number, can be I2C_NUM_0 ~ (I2C_NUM_MAX-1). */
+ if (I2C_MASTER_NUM >= I2C_NUM_MAX) {
+ ESP_LOGW(TAG, "Warning: I2C_MASTER_NUM value %d exceeds (I2C_NUM_MAX-1)"
+ " %d ", I2C_MASTER_NUM, I2C_NUM_MAX);
+ }
+ ESP_LOGI(TAG, "esp_i2c_master_init");
+ ESP_LOGI(TAG, "I2C_MASTER_FREQ_HZ = %d", (int)I2C_MASTER_FREQ_HZ);
+ ESP_LOGI(TAG, "I2C_READ_WAIT_TICKS = %d", (int)I2C_READ_WAIT_TICKS);
+ ESP_LOGI(TAG, "I2C_WRITE_WAIT_TICKS = %d", (int)I2C_WRITE_WAIT_TICKS);
+ ESP_LOGI(TAG, "I2C_MASTER_TIMEOUT_MS = %d", (int)I2C_MASTER_TIMEOUT_MS);
+ ESP_LOGI(TAG, "I2C_MASTER_NUM = %d", (int)I2C_MASTER_NUM);
+ ESP_LOGI(TAG, "I2C_MASTER_SCL_IO = %d", (int)I2C_MASTER_SCL_IO);
+ ESP_LOGI(TAG, "I2C_MASTER_SDA_IO = %d", (int)I2C_MASTER_SDA_IO);
+
+ conf.mode = I2C_MODE_MASTER;
+ conf.sda_io_num = I2C_MASTER_SDA_IO;
+ conf.scl_io_num = I2C_MASTER_SCL_IO;
+ conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
+ conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
+ conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
+
+ ret = i2c_param_config(i2c_master_port, &conf);
+#else
+ esp_err_t ret = ESP_FAIL;
+ ESP_LOGE(TAG, "TODO Need to implement non-legacy ESP-IDF I2C library");
+#endif
+
+ if (ret == ESP_OK) {
+ ret = i2c_driver_install(i2c_master_port, conf.mode,
+ I2C_MASTER_RX_BUF_DISABLE,
+ I2C_MASTER_TX_BUF_DISABLE, 0);
+ }
+
+ if (ret == ESP_OK) {
+ ESP_LOGI(TAG, "i2c driver install success");
+ _is_initialized_i2c = TRUE;
+ }
+ else {
+ ESP_LOGE(TAG, "Failed to initialize i2c. Error code: %d", ret);
+ }
+
+ return ret;
+}
+
+static esp_err_t i2c_master_delete(void)
+{
+ ESP_LOGI(TAG, "i2c_master_delete");
+ ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM));
+ _is_initialized_i2c = FALSE;
+ return ESP_OK;
+}
+
+/* Espressif HAL I2C */
+static esp_err_t esp_tpm_register_read(uint32_t reg, uint8_t *data, size_t len)
+{
+ int ret;
+ int timeout = TPM_I2C_TRIES;
+ int loops = 0;
+ byte buf[1];
+
+ /* TIS layer should never provide a buffer larger than this,
+ * but double check for good coding practice */
+ if (len > MAX_SPI_FRAMESIZE) {
+ return BAD_FUNC_ARG;
+ }
+
+ buf[0] = (reg & 0xFF); /* convert to simple 8-bit address for I2C */
+
+ /* The I2C takes about 80us to wake up and will NAK until it is ready */
+ do {
+ /* Write address to read from - retry until ack */
+ ret = i2c_master_write_to_device(I2C_MASTER_NUM, TPM2_I2C_ADDR,
+ buf, sizeof(buf),
+ I2C_WRITE_WAIT_TICKS);
+
+ if (ret != ESP_OK) {
+ XSLEEP_MS(WRITE_RETRY_DELAY_TIME);
+ }
+ } while (ret != ESP_OK && --timeout > 0);
+
+ /* For read we always need this guard time.
+ * (success wake or real read) */
+ XSLEEP_MS(WRITE_TO_READ_GUARD_TIME); /* guard time - should be min 250us */
+
+ if (ret == ESP_OK) {
+ timeout = TPM_I2C_TRIES;
+ do {
+ loops++;
+ ret = i2c_master_read_from_device(I2C_MASTER_NUM, TPM2_I2C_ADDR,
+ data, len,
+ I2C_READ_WAIT_TICKS);
+ if (ret != ESP_OK) {
+ /* If we're not immediately successful, this may be a
+ * long-running transaction. Thus wait an increasingly
+ * longer amount of time for each retry. */
+ XSLEEP_MS(READ_RETRY_DELAY_TIME + (loops * 4));
+ }
+ } while ((ret != ESP_OK) && (--timeout > 0));
+ }
+ XSLEEP_MS(POST_READ_GUARD_TIME); /* guard time - should be 250us */
+
+ if (ret == ESP_OK) {
+#ifdef DEBUG_WOLFSSL_VERBOSE
+ ESP_LOGI(TAG, "Success! i2c_master_read_from_device. loops = %d",
+ loops);
+ show_binary(data, len);
+#endif
+ }
+ else {
+ if (ret == ESP_ERR_TIMEOUT) {
+ ESP_LOGE(TAG, "ERROR: esp_tpm_register_read ESP_ERR_TIMEOUT");
+ }
+ else {
+ ESP_LOGE(TAG, "ERROR: tpm_register_read error = %d", ret);
+ }
+ if (DELETE_I2C_ON_ERROR) {
+ i2c_master_delete();
+ }
+ }
+ return ret;
+}
+
+/* TPM Interface Write. Returns ESP-IDF result code (not TPM) */
+static esp_err_t esp_tpm_register_write(uint32_t reg,
+ uint8_t* data, size_t len)
+{
+ byte buf[MAX_SPI_FRAMESIZE + 1];
+ int timeout = TPM_I2C_TRIES;
+ int result = ESP_FAIL;
+
+ /* TIS layer should never provide a buffer larger than this,
+ * but double check for good coding practice */
+ if (len > MAX_SPI_FRAMESIZE) {
+ return BAD_FUNC_ARG;
+ }
+
+ /* Build packet with TPM register and data */
+ buf[0] = (reg & 0xFF); /* convert to simple 8-bit address for I2C */
+ XMEMCPY(buf + 1, data, len);
+
+#ifdef DEBUG_WOLFSSL_VERBOSE
+ ESP_LOGI(TAG, "TPM will write %d bytes:", len);
+ show_binary(data, len);
+#endif
+
+ /* The I2C takes about 80us to wake up and will NAK until it is ready */
+ do {
+ result = i2c_master_write_to_device(I2C_MASTER_NUM, TPM2_I2C_ADDR,
+ buf, len + 1,
+ I2C_WRITE_WAIT_TICKS);
+ if (result != ESP_OK) {
+ XSLEEP_MS(WRITE_RETRY_DELAY_TIME);
+ }
+ } while (result != ESP_OK && --timeout > 0);
+ XSLEEP_MS(POST_WRITE_GUARD_TIME); /* guard time - should be 250us */
+
+ if (result == ESP_OK) {
+ ESP_LOGV(TAG, "Success! tpm_register_write wrote %d bytes after "
+ "%d attempts", len, (TPM_I2C_TRIES - timeout));
+ }
+ else {
+ ESP_LOGE(TAG, "ERROR: tpm_register_write failed with code = %d after "
+ "%d attempts", result, (TPM_I2C_TRIES - timeout));
+ if (DELETE_I2C_ON_ERROR) {
+ i2c_master_delete();
+ }
+ }
+
+ return result;
+}
+
+/* TPM Interface Read. Returns TPM result code (not ESP) */
+static int tpm_ifx_i2c_read(void* userCtx, word32 reg, byte* data, int len)
+{
+ int ret;
+ ret = esp_tpm_register_read(reg, data, len); /* returns ESP error code */
+
+ if (ret == ESP_OK) {
+ ESP_LOGV(TAG, "Read device 0x%x success.\n", TPM2_I2C_ADDR);
+ ret = TPM_RC_SUCCESS;
+ }
+ else {
+ ESP_LOGE(TAG, "Read device 0x%x fail. Error = %d\n",
+ TPM2_I2C_ADDR, ret);
+ ret = TPM_RC_FAILURE;
+ }
+ return ret;
+}
+
+/* TPM Interface Write. Returns TPM result code (not ESP) */
+static int tpm_ifx_i2c_write(void* userCtx, word32 reg, byte* data, int len)
+{
+ int ret;
+ ret = esp_tpm_register_write(reg, data, len); /* returns ESP error code */
+
+ if (ret == ESP_OK) {
+ /* WARNING: an ESP_LOG message here may at times interfere with the
+ * write-then-read timing, causing errors. Enable with caution: */
+
+ /* ESP_LOGI(TAG, "Write device 0x%x success 0x%x len = %d\n",
+ TPM2_I2C_ADDR, (word32)data, len); */
+ ret = TPM_RC_SUCCESS;
+ }
+ else {
+ ESP_LOGE(TAG, "Write device 0x%x fail. Error = %d\n",
+ TPM2_I2C_ADDR, ret);
+ ret = TPM_RC_FAILURE;
+ }
+ return ret;
+}
+
+int TPM2_IoCb_Espressif_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
+ byte* buf, word16 size, void* userCtx)
+{
+ int ret = TPM_RC_FAILURE;
+
+ if (userCtx == NULL) {
+ ESP_LOGE(TAG, "userCtx cannot be null");
+ }
+ else {
+ if (_is_initialized_i2c) {
+ ESP_LOGV(TAG, "I2C already initialized");
+ ret = ESP_OK;
+ }
+ else {
+ ret = esp_i2c_master_init(); /* ESP return code, not TPM */
+ }
+
+ if (ret == ESP_OK) {
+ if (isRead) {
+ ret = tpm_ifx_i2c_read(userCtx, addr, buf, size);
+ }
+ else {
+ ret = tpm_ifx_i2c_write(userCtx, addr, buf, size);
+ }
+ }
+ else {
+ ESP_LOGE(TAG, "I2C Failed to initialize. Error: %d", ret);
+ ret = TPM_RC_FAILURE;
+ }
+ }
+ (void)ctx;
+ return ret;
+} /* TPM2_IoCb_Espressif_I2C */
+
+/* end WOLFTPM_I2C */
+
+#else /* If not I2C, it must be SPI */
+ /* TODO implement SPI */
+
+ #ifndef TPM2_SPI_HZ
+ /* Use the max speed by default
+ * See tpm2_types.h for chip specific max values */
+ #define TPM2_SPI_HZ TPM2_SPI_MAX_HZ
+ #endif
+ #ifdef WOLFTPM_CHECK_WAIT_STATE
+ #error SPI check wait state logic not supported
+ #endif
+
+ #error TPM2 SPI support on this platform not supported yet
+#endif
+
+#endif /* WOLFSSL_ESPIDF */
+#endif /* WOLFTPM_INCLUDE_IO_FILE */
+
+/******************************************************************************/
+/* --- END IO Callback Logic -- */
+/******************************************************************************/
diff --git a/wolftpm/tpm2_types.h b/wolftpm/tpm2_types.h
index 64d7f36c..0b7f771a 100644
--- a/wolftpm/tpm2_types.h
+++ b/wolftpm/tpm2_types.h
@@ -452,6 +452,8 @@ typedef int64_t INT64;
#ifdef WIN32
#include
#define XSLEEP_MS(ms) Sleep(ms)
+ #elif defined(FREERTOS)
+ #define XSLEEP_MS(ms) vTaskDelay(ms)
#elif defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
#include
#define XSLEEP_MS(ms) ({ \