From fb19d7a0e1f31421a8ae75796de93d6105046b01 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Fri, 10 May 2024 14:16:39 -0700 Subject: [PATCH 1/3] Initial Infineon I2C TPM support for Espressif ESP32 --- IDE/Espressif/CMakeLists.txt | 96 +++ IDE/Espressif/README.md | 31 + .../VisualGDB/wolfssl_IDF_v5.2_ESP32.vgdbproj | 269 +++++++ .../components/wolfssl/CMakeLists.txt | 711 ++++++++++++++++++ .../wolfssl/include/user_settings.h | 693 +++++++++++++++++ .../components/wolftpm/CMakeLists.txt | 601 +++++++++++++++ .../components/wolftpm/include/README.md | 4 + IDE/Espressif/include.am | 27 + IDE/Espressif/main/CMakeLists.txt | 105 +++ IDE/Espressif/main/Kconfig.projbuild | 21 + IDE/Espressif/main/include/main.h | 25 + IDE/Espressif/main/main.c | 102 +++ IDE/Espressif/partitions_singleapp_large.csv | 31 + IDE/Espressif/sdkconfig.defaults | 35 + IDE/include.am | 1 + examples/native/native_test.c | 3 +- hal/include.am | 1 + hal/tpm_io.c | 4 +- hal/tpm_io.h | 3 + hal/tpm_io_espressif.c | 446 +++++++++++ wolftpm/tpm2_types.h | 2 + 21 files changed, 3209 insertions(+), 2 deletions(-) create mode 100644 IDE/Espressif/CMakeLists.txt create mode 100644 IDE/Espressif/README.md create mode 100644 IDE/Espressif/VisualGDB/wolfssl_IDF_v5.2_ESP32.vgdbproj create mode 100644 IDE/Espressif/components/wolfssl/CMakeLists.txt create mode 100644 IDE/Espressif/components/wolfssl/include/user_settings.h create mode 100644 IDE/Espressif/components/wolftpm/CMakeLists.txt create mode 100644 IDE/Espressif/components/wolftpm/include/README.md create mode 100644 IDE/Espressif/include.am create mode 100644 IDE/Espressif/main/CMakeLists.txt create mode 100644 IDE/Espressif/main/Kconfig.projbuild create mode 100644 IDE/Espressif/main/include/main.h create mode 100644 IDE/Espressif/main/main.c create mode 100644 IDE/Espressif/partitions_singleapp_large.csv create mode 100644 IDE/Espressif/sdkconfig.defaults create mode 100644 hal/tpm_io_espressif.c 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..e45536f0 --- /dev/null +++ b/IDE/Espressif/components/wolfssl/include/user_settings.h @@ -0,0 +1,693 @@ +/* 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 */ +/* TPM_I2C_TRIES 10 */ + +/* Examples may have a main() function, we'll have oour own: */ +#define NO_MAIN_DRIVER + +/* 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..2f0b3e2d 100644 --- a/hal/tpm_io.c +++ b/hal/tpm_io.c @@ -144,6 +144,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 +207,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..697f76fe --- /dev/null +++ b/hal/tpm_io_espressif.c @@ -0,0 +1,446 @@ +/* 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 + +/* 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 */ +#define I2C_MASTER_NUM 0 + +/* 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; + + 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); + + 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..15078d00 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(WOLFSSL_ESPIDF) + #define XSLEEP_MS(ms) vTaskDelay(ms) #elif defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L #include #define XSLEEP_MS(ms) ({ \ From 4f3b57a6e2505da69449514d2ce3bc69076b2550 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Mon, 13 May 2024 11:43:33 -0700 Subject: [PATCH 2/3] flexibility for I2C_MASTER_NUM, add settings comments --- .../wolfssl/include/user_settings.h | 15 +++++++++++++- hal/tpm_io.c | 2 ++ hal/tpm_io_espressif.c | 20 ++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/IDE/Espressif/components/wolfssl/include/user_settings.h b/IDE/Espressif/components/wolfssl/include/user_settings.h index e45536f0..a8852990 100644 --- a/IDE/Espressif/components/wolfssl/include/user_settings.h +++ b/IDE/Espressif/components/wolfssl/include/user_settings.h @@ -656,11 +656,24 @@ Turn on timer debugging (used when CPU cycles not available) #define TPM_TIMEOUT_TRIES 10000 /* If not defined here, TPM_I2C_TRIES is set to a default value of 10 */ -/* TPM_I2C_TRIES 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. diff --git a/hal/tpm_io.c b/hal/tpm_io.c index 2f0b3e2d..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) diff --git a/hal/tpm_io_espressif.c b/hal/tpm_io_espressif.c index 697f76fe..8a003a45 100644 --- a/hal/tpm_io_espressif.c +++ b/hal/tpm_io_espressif.c @@ -74,10 +74,14 @@ #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 + #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. */ @@ -87,7 +91,7 @@ /* GPIO number used for I2C master data */ #ifdef CONFIG_I2C_MASTER_SDA /* Orange wire */ - #define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA + #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. */ @@ -96,7 +100,9 @@ /* I2C master i2c port number, * the number of i2c peripheral interfaces available will depend on the chip */ -#define I2C_MASTER_NUM 0 +#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. @@ -184,11 +190,19 @@ static esp_err_t esp_i2c_master_init(void) 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; From 5aff694c3f19efdfc77ec28213bd45bf7bee5777 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Mon, 13 May 2024 13:05:21 -0700 Subject: [PATCH 3/3] XSLEEP_MS is vTaskDelay for all FREERTOS, not just ESPIDF --- wolftpm/tpm2_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolftpm/tpm2_types.h b/wolftpm/tpm2_types.h index 15078d00..0b7f771a 100644 --- a/wolftpm/tpm2_types.h +++ b/wolftpm/tpm2_types.h @@ -452,7 +452,7 @@ typedef int64_t INT64; #ifdef WIN32 #include #define XSLEEP_MS(ms) Sleep(ms) - #elif defined(WOLFSSL_ESPIDF) + #elif defined(FREERTOS) #define XSLEEP_MS(ms) vTaskDelay(ms) #elif defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L #include