diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index c1b4cf403..0db3c7da6 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -96,6 +96,7 @@ CONFIG_ESP_WOLFSSL_NO_HW_RSA_PRI CONFIG_ESP_WOLFSSL_NO_HW_RSA_PRI_EXPTMOD CONFIG_ESP_WOLFSSL_NO_HW_RSA_PRI_MP_MUL CONFIG_ESP_WOLFSSL_NO_HW_RSA_PRI_MULMOD +CONFIG_ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING CONFIG_FREERTOS_HZ CONFIG_FREERTOS_UNICORE CONFIG_IDF_TARGET @@ -286,6 +287,7 @@ IOTSAFE_NO_GETDATA IOTSAFE_SIG_8BIT_LENGTH KCAPI_USE_XMALLOC K_SERIES +LIBWOLFSSL_CMAKE_OUTPUT LIBWOLFSSL_VERSION_GIT_BRANCH LIBWOLFSSL_VERSION_GIT_HASH LIBWOLFSSL_VERSION_GIT_HASH_DATE @@ -415,6 +417,7 @@ NO_WOLFSSL_SHA256_INTERLEAVE NO_WOLFSSL_SHA512_INTERLEAVE NO_WOLFSSL_SKIP_TRAILING_PAD NO_WOLFSSL_SMALL_STACK_STATIC +NO_WOLFSSL_USE_ASM_CERT NO_WOLFSSL_XILINX_TAG_MALLOC NRF52 NRF52_SERIES @@ -456,6 +459,7 @@ SHOW_CERTS SHOW_GEN SHOW_SIZES SHOW_SSID_AND_PASSWORD +SHOW_WOLFSSL_BUNDLE_ERROR SIM_SCGC3_RNGA_MASK SIM_SCGC5_PORTC_MASK SIM_SCGC5_PORTD_MASK diff --git a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt index cc7ef0d47..b4a2b74c1 100644 --- a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt @@ -19,23 +19,62 @@ # # cmake for wolfssl Espressif projects # -# Version 5.7.2 Espressif ESP-IDF integration +# Version 5.8.0 Espressif ESP-IDF + PlatformIO integration (2) # # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html # message(STATUS "Begin wolfssl ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") cmake_minimum_required(VERSION 3.16) +# The scope of this CMAKE_C_FLAGS is just this component: +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWOLFSSL_USER_SETTINGS") + +set(CMAKE_CURRENT_SOURCE_DIR ".") + +# Optionally set your source to wolfSSL in your project CMakeLists.txt like this: +# set(WOLFSSL_ROOT "c:/workspace/my_wolfssl" ) + +if ( "${WOLFSSL_ROOT}" STREQUAL "") + set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" ) +endif() + set(VERBOSE_COMPONENT_MESSAGES 1) # Optional requires include: # set(THIS_ESP_TLS "esp-tls") set(THIS_ESP_TLS "") +# LIBWOLFSSL_CMAKE_OUTPUT can be printed at runtime +set(LIBWOLFSSL_CMAKE_OUTPUT "") + + +if(CMAKE_BUILD_EARLY_EXPANSION) + message(STATUS "Skipping libwolfssl_output.h update during CMAKE_BUILD_EARLY_EXPANSION") +else() + # Initialize a new libwolfssl_output.h in the cmake build directory. + if( EXISTS "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + # The next WRITE replaces a file. + # This is here to remove any ambiguity on file removal & generation. + file(REMOVE "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + endif() + + file(WRITE "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "/* libwolfssl_output.h generated by wolfssl component */\n" + "#ifndef _LIBWOLFSSL_OUTPUT_H_\n" + "\n" + "#define _LIBWOLFSSL_OUTPUT_H_\n\n") +endif() + +# Append messages with: +# LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n"message" "0") +# See function: APPEND_LIBWOLFSSL_CMAKE_OUTPUT + # function: IS_ESP_IDF_COMPONENT # output: RESULT = 1 (true) if this component is located in the ESP-IDF components # otherwise 0 (false) -function( IS_ESP_IDF_COMPONENT RESULT ) +function( IS_ESP_IDF_COMPONENT + RESULT) # NOTE: Component location is based on the location of the CMakeList.txt # and *not* the location of the wolfSSL source code. (which may be anywhere) @@ -55,6 +94,96 @@ function( IS_ESP_IDF_COMPONENT RESULT ) endif() endfunction() +# +# LIBWOLFSSL_SAVE_INFO(VAR_OUTPUT THIS_VAR VAR_RESULT) +# +# Save the THIS_VAR as a string in a macro called VAR_OUTPUT +# +# VAR_OUTPUT: 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_OUTPUT 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_OUTPUT + if(${IS_VALID_VALUE}) + + if(0) + # Optional debug + message(STATUS "Looking for LF in ${THIS_VAR}") + endif() + + # Check if the text to print in THIS_VAR is multi-line + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + list(LENGTH LINES LINE_COUNT) + + # Save var to "libwolfssl_output.h" header if multi-line, otherwise a simple compile def + if(LINE_COUNT GREATER 1) + message(STATUS "Setting HAVE_LIBWOLFSSL_OUTPUT_HEADER=1 for ${VAR_OUTPUT}") + add_compile_definitions(HAVE_LIBWOLFSSL_OUTPUT_HEADER=1) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#undef ${VAR_OUTPUT}\n") + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#define ${VAR_OUTPUT} \\\n") + + # Split into lines + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + foreach(LINE IN LISTS LINES) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\"${LINE}\\n\" \\\n") + endforeach() + + # Final empty line to close the macro + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\n") + + message(STATUS "COMPONENT_LIB=${COMPONENT_LIB}") + target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_BINARY_DIR}") + else() + message(STATUS "No HAS_LIBWOLFSSL_OUTPUT_HEADER") + # We should not have any, but just to be sure: + # 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_OUTPUT} ${VAR_VALUE} PARENT_SCOPE) + + # but we're only using it here in this function + set(${VAR_OUTPUT} ${VAR_VALUE}) + + # we'll print what we found to the console + message(STATUS "Found ${VAR_OUTPUT}=${VAR_VALUE}") + + # the interesting part is defining the VAR_OUTPUT name a value to use in the app + add_compile_definitions(${VAR_OUTPUT}=\"${VAR_VALUE}\") + + endif() + 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_OUTPUT} "Unknown") + endif() + + +endfunction() # LIBWOLFSSL_SAVE_INFO + +# +# APPEND_LIBWOLFSSL_CMAKE_OUTPUT(THIS_MESSAGE OUTPUT_VALUE) +# +# Append the text in THIS_MESSAGE to LIBWOLFSSL_CMAKE_OUTPUT. +# String is available at runtime in app +# + +function( APPEND_LIBWOLFSSL_CMAKE_OUTPUT + THIS_MESSAGE ) + # Normally, we'd simply print a message: + message(STATUS "${THIS_MESSAGE}") + + # But here we'll pass the entire LIBWOLFSSL_CMAKE_OUTPUT as a string definition to the app + set(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n${THIS_MESSAGE}" PARENT_SCOPE) + + # We don't call LIBWOLFSSL_SAVE_INFO here as it would add duplicate definitions + # See single instance at the end of this file. +endfunction() + # Determine if this cmake file is located in the ESP-IDF component directory or not, # and if so, if it is being ignored (allowing the use of a local project one, instead). IS_ESP_IDF_COMPONENT( IS_WOLSSL_ESP_IDF_COMPONENT ) @@ -77,20 +206,6 @@ else() message(STATUS "Cleaned wolfssl path: ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") endif() -# The scope of this CMAKE_C_FLAGS is just this component: -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_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() - if( "$ENV{IDF_PATH}" STREQUAL "" ) message(FATAL_ERROR "IDF_PATH Environment variable not set!") else() @@ -185,7 +300,9 @@ endif() # Check environment variable name EVARPARAM as [name] # If defined, and has a value of EVARVALUE as [value], # then assign a compiler definition "-D[name]=[value]" -function(ENVIRONMENT_VAR_TO_MACRO EVARPARAM EVARVALUE) +function( ENVIRONMENT_VAR_TO_MACRO + EVARPARAM # Environment variable parameter name + EVARVALUE) # Environment variable value # If the EVARPARAM environment variable name is set to EVARVALUE, # set the compiler flag definition to enable CSV output. if ( "$ENV{${EVARPARAM}}" STREQUAL "${EVARVALUE}") @@ -217,7 +334,8 @@ endfunction() # 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 +function( IS_WOLFSSL_SOURCE + DIRECTORY_PARAMETER RESULT ) if (EXISTS "${DIRECTORY_PARAMETER}/wolfcrypt/src") set(${RESULT} "${DIRECTORY_PARAMETER}" PARENT_SCOPE) @@ -233,7 +351,8 @@ endfunction() # Example usage: # FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT) # ********************************************************************************************* -function(FIND_WOLFSSL_DIRECTORY OUTPUT_FOUND_WOLFSSL_DIRECTORY) +function( FIND_WOLFSSL_DIRECTORY + OUTPUT_FOUND_WOLFSSL_DIRECTORY) message(STATUS "Starting FIND_WOLFSSL_DIRECTORY: ${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}") if ( "${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}" STREQUAL "" ) @@ -673,9 +792,9 @@ else() # 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") - if(WOLFSSL_ROOT) - string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) - endif() + if(WOLFSSL_ROOT) + string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) + endif() if(IS_DIRECTORY "${RTOS_IDF_PATH}") message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}") @@ -789,16 +908,35 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE AND NOT CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE AND NOT ("${CONFIG_TARGET_PLATFORM}" STREQUAL "esp8266") ) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("wolfSSL Certificate Bundles Enabled") + if (CMAKE_BUILD_EARLY_EXPANSION) - message(ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") + message(FATAL_ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") endif() # reminder: we need a value for wolfSSL root first! if( "${WOLFSSL_ROOT}" STREQUAL "" ) - message(ERROR "Certificate bundles need a value for WOLFSSL_ROOT") + message(FATAL_ERROR "Certificate bundles need a value for WOLFSSL_ROOT") endif() + + # Cert bundle in wolfSSL source unless otherwise specified later set(WOLFSSL_ESP_CRT_BUNDLE_DIR ${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif/esp_crt_bundle) message(STATUS "WOLFSSL_ESP_CRT_BUNDLE_DIR=${WOLFSSL_ESP_CRT_BUNDLE_DIR}") - if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + + if(DEFINED ENV{PLATFORMIO_PROJECT_DIR}) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO") + set(IS_PLATFORMIO 1) + else() + # Some environments may not have environment variable, so double check if we are in .pio + if("${CMAKE_BINARY_DIR}" MATCHES "/\\.pio/") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO via CMAKE_BINARY_DIR") + set(IS_PLATFORMIO 1) + else() + set(IS_PLATFORMIO 0) + endif() + endif() + + if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}" OR IS_PLATFORMIO) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Special processing for wolfSSL Certificate Bundles") set(bundle_name "x509_crt_bundle_wolfssl") # For now the certs are in the same directory @@ -824,9 +962,9 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE get_filename_component(custom_bundle_path ${CONFIG_WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}") list(APPEND crt_paths ${custom_bundle_path}) - message(STATUS "Using a custom wolfSSL bundle path: ${custom_bundle_path}") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Using a custom wolfSSL bundle path: ${custom_bundle_path}") else() - message(STATUS "Not using a custom wolfSSL bundle path.") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Not using a custom wolfSSL bundle path") endif() list(APPEND args --input ${crt_paths} -q) @@ -843,25 +981,107 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE message(STATUS "args ${args}") message(STATUS "cert_bundle ${cert_bundle}") - # Generate bundle according to config - # File is generated at build time, not cmake load - add_custom_command(OUTPUT ${crt_bundle} - COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} - DEPENDS ${custom_bundle_path} - VERBATIM) + if (IS_PLATFORMIO) + # PlatformIO cannot generate a Certificate Bundle at build time + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("PlatformIO is using a predefined bundle rather than generating one") - if(EXISTS "${crt_bundle}") - message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + if ( "${WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "n") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Alternate Certificate Bundle Path and Name not enabled, assuming [project]/certs/x509_crt_bundle_wolfssl") + # Reminder this CMakeLists.txt should be in [project]/components/wolfssl, so ./certs is two directories up + set(crt_bundle_option "../../certs/x509_crt_bundle_wolfssl") + else() + string(SUBSTRING "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" 0 2 CERT_PATH_FIRST_TWO) + if(CERT_PATH_FIRST_TWO STREQUAL "./" OR CERT_PATH_FIRST_TWO STREQUAL ".\\") + set(IS_CERT_BUNDLE_RELATIVE_PATH 1) + message(STATUS "Alternate Cert Path is relative to project.") + else() + set(IS_CERT_BUNDLE_RELATIVE_PATH 0) + message(STATUS "Alternate Cert Path is not relative to project.") + endif() + + # The cert bundle is not a standard cert, so we con't add to the crt_paths. + # Still, we may have an alternate location, particulatly needed for PlatformIO: + if(IS_CERT_BUNDLE_RELATIVE_PATH) + message(STATUS "CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME = ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Relative alternate_bundle_path: ${alternate_bundle_path}") + + SET(crt_bundle_option "${CMAKE_SOURCE_DIR}/${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + else() + message(STATUS "alternate_bundle_path: ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Not using an alternate wolfSSL bundle file.") + SET(crt_bundle_option "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + endif() + endif() + + # Clean the path, removing any extra "./" etc. + # Number of spaces in message strings is to align path value outputs + message(STATUS "This crt_bundle_option value: ${crt_bundle_option}") + if(${CMAKE_VERSION} VERSION_LESS "3.19") + message("WARNING: CMake version is ${CMAKE_VERSION} ? file(REAL_PATH ...) is not supported. Falling back to manual path normalization.") + # optional fallback logic here + get_filename_component(crt_bundle_file_component "${crt_bundle_option}" ABSOLUTE) + message(STATUS "Interim crt_bundle_file_component: ${crt_bundle_file_component}") + file(TO_CMAKE_PATH "${crt_bundle_file_component}" crt_bundle) + message(STATUS "TO_CMAKE_PATH crt_bundle result: ${crt_bundle}") + # set(crt_bundle "C:/workspace/pio_wolfssl-upstream-test-wolfssl_cert_bundle/esp32-c6/certs/x509_crt_bundle_wolfssl") + else() + file(REAL_PATH "${crt_bundle_option}" crt_bundle) + endif() + + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Certificate Bundle: ${crt_bundle}") + message(STATUS "This cleaned crt_bundle value: ${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + message(STATUS "Reminder: platformio.ini will need this value set for board_build.embed_files =") + message(STATUS "${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + + # e.g. SET(crt_bundle "C:/workspace/pio_wolfssl/esp32-c6/certs/x509_crt_bundle_wolfssl") + # + + # Normally x509_crt_bundle_wolfssl built by python script called from cmake. + # See https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/src/port/Espressif/esp_crt_bundle/gen_crt_bundle.py + # Reminder ESP-IDF scripts are NOT called from CMake for PlatformIO builds. + # + # The easiest way to generate the default file is to build with ESP-IDF and copy the files to [project]/main + # + # for example: + # build\VisualGDB\Debug\x509_crt_bundle_wolfssl.s + # build\VisualGDB\Debug\esp-idf\wolfssl\x509_crt_bundle_wolfssl + # + message(STATUS "Confirming cert bundle exists...") + if(EXISTS "${crt_bundle}") + # Number of spaces is to align path value outputs + message(STATUS "Bundle file found for PlatformIO: ${crt_bundle}") + else() + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("ERROR: Failed to find bundle file found for PlatformIO: ${crt_bundle}") + message(STATUS "Check for entry in platformio.ini: board_build.embed_files = certs/x509_crt_bundle_wolfssl ") + message(FATAL_ERROR "WOLFSSL_CERTIFICATE_BUNDLE is enabled for PlatformIO, but predefined file not found: ${crt_bundle}") + endif() else() - message(STATUS "Bundle file expected during next build: ${crt_bundle}") + # APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Generate bundle: ${GENERATE_CERT_BUNDLEPY} ${args}") + # Not PlatformIO + # Generate bundle according to config + # File is generated at build time, not cmake load + add_custom_command(OUTPUT ${crt_bundle} + COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} + DEPENDS ${custom_bundle_path} + VERBATIM) + + if(EXISTS "${crt_bundle}") + message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + else() + message(STATUS "Bundle file expected during next build: ${crt_bundle}") + endif() + + # Reminder the file is generated at build time, not cmake load time. + message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") endif() - # Reminder the file is generated at build time, not cmake load time. - message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") + add_custom_target(custom_wolfssl_bundle DEPENDS ${crt_bundle}) - add_custom_target(custom_wolfssl_bundle DEPENDS ${cert_bundle}) - - # the wolfSSL crtificate bundle is baked into wolfSSL + # the wolfSSL certificate bundle is baked into wolfSSL add_dependencies(${COMPONENT_LIB} custom_wolfssl_bundle) # COMPONENT_LIB may vary: __idf_wolfssl, __idf_esp_wolfssl, etc @@ -871,7 +1091,12 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${crt_bundle}") else() - message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + if(IS_PLATFORMIO) + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but cannot be generated in PlatformmIO") + else() + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + endif() + message(FATAL_ERROR "not detected") endif() endif() @@ -930,42 +1155,6 @@ 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_compile_definitions(${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 - execute_process( COMMAND ${git_cmd} "rev-parse" "--is-inside-work-tree" OUTPUT_VARIABLE IS_GIT_REPO @@ -1049,6 +1238,14 @@ else() message(STATUS "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") endif() +# A single instance of potentially multiple cmake messages to send to app: +message(STATUS "LIBWOLFSSL_CMAKE_OUTPUT: ${LIBWOLFSSL_CMAKE_OUTPUT}") +LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}" "0") + +file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "\n" + "#endif\n" ) + message(STATUS "************************************************************************************************") message(STATUS "wolfSSL component config complete!") message(STATUS "************************************************************************************************") diff --git a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/Kconfig b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/Kconfig index 9a7fcaa07..ee8dc7f1a 100644 --- a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/Kconfig +++ b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/Kconfig @@ -274,10 +274,28 @@ menu "wolfSSL" bool "Do not use the default certificate bundle" endchoice + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE + depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + default n + bool "Use alternate certificate bundle" + help + Typically only used for PlatformIO which cannot generate a certificate bundle at build time. + Enable this option to specify a fixed wolfSSL certificate file path and file name. + + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME + depends on WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + string "Default certificate bundle alternate path and name" + default "./certs/x509_crt_bundle_wolfssl" + help + Name of the default certificate bundle directory. Typically used only with PlatformIO. + Reminder PlatformIO cannot generate a bundle from cmake python script call. Relative + paths are with respect to root of this project. + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL default n bool "Add custom certificates to the default bundle" + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH depends on WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL string "Custom certificate bundle path" @@ -430,6 +448,12 @@ menu "wolfSSL" help Enable debugging messages for wolfSSL. See user_settings.h for additional debug options. + config ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING + bool "Suppress build-time warnings for main stack size" + default n + help + Useful only when wolfSSL is running in main task. See FreeRTOS stack size for custom tasks. + config ESP_WOLFSSL_TEST_LOOP bool "Run test apps in a loop until failure" default y diff --git a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/include/user_settings.h b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/include/user_settings.h index 488182ed6..80f89fffe 100644 --- a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/include/user_settings.h +++ b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/include/user_settings.h @@ -853,13 +853,18 @@ #ifndef NO_RSA #define ESP32_USE_RSA_PRIMITIVE - #if defined(CONFIG_IDF_TARGET_ESP32) - #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + /* See idf.py menuconfig for stack warning settings */ + #if !defined(CONFIG_ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING) #if CONFIG_ESP_MAIN_TASK_STACK_SIZE < 10500 - #warning "RSA may be difficult with less than 10KB Stack "/ + #warning "RSA may be difficult with less than 10KB Stack" #endif + #else + /* Implement your own stack warning here */ #endif + #endif + #if defined(CONFIG_IDF_TARGET_ESP32) /* NOTE HW unreliable for small values! */ /* threshold for performance adjustment for HW primitive use */ /* X bits of G^X mod P greater than */ diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt index cc7ef0d47..b4a2b74c1 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt @@ -19,23 +19,62 @@ # # cmake for wolfssl Espressif projects # -# Version 5.7.2 Espressif ESP-IDF integration +# Version 5.8.0 Espressif ESP-IDF + PlatformIO integration (2) # # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html # message(STATUS "Begin wolfssl ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") cmake_minimum_required(VERSION 3.16) +# The scope of this CMAKE_C_FLAGS is just this component: +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWOLFSSL_USER_SETTINGS") + +set(CMAKE_CURRENT_SOURCE_DIR ".") + +# Optionally set your source to wolfSSL in your project CMakeLists.txt like this: +# set(WOLFSSL_ROOT "c:/workspace/my_wolfssl" ) + +if ( "${WOLFSSL_ROOT}" STREQUAL "") + set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" ) +endif() + set(VERBOSE_COMPONENT_MESSAGES 1) # Optional requires include: # set(THIS_ESP_TLS "esp-tls") set(THIS_ESP_TLS "") +# LIBWOLFSSL_CMAKE_OUTPUT can be printed at runtime +set(LIBWOLFSSL_CMAKE_OUTPUT "") + + +if(CMAKE_BUILD_EARLY_EXPANSION) + message(STATUS "Skipping libwolfssl_output.h update during CMAKE_BUILD_EARLY_EXPANSION") +else() + # Initialize a new libwolfssl_output.h in the cmake build directory. + if( EXISTS "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + # The next WRITE replaces a file. + # This is here to remove any ambiguity on file removal & generation. + file(REMOVE "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + endif() + + file(WRITE "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "/* libwolfssl_output.h generated by wolfssl component */\n" + "#ifndef _LIBWOLFSSL_OUTPUT_H_\n" + "\n" + "#define _LIBWOLFSSL_OUTPUT_H_\n\n") +endif() + +# Append messages with: +# LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n"message" "0") +# See function: APPEND_LIBWOLFSSL_CMAKE_OUTPUT + # function: IS_ESP_IDF_COMPONENT # output: RESULT = 1 (true) if this component is located in the ESP-IDF components # otherwise 0 (false) -function( IS_ESP_IDF_COMPONENT RESULT ) +function( IS_ESP_IDF_COMPONENT + RESULT) # NOTE: Component location is based on the location of the CMakeList.txt # and *not* the location of the wolfSSL source code. (which may be anywhere) @@ -55,6 +94,96 @@ function( IS_ESP_IDF_COMPONENT RESULT ) endif() endfunction() +# +# LIBWOLFSSL_SAVE_INFO(VAR_OUTPUT THIS_VAR VAR_RESULT) +# +# Save the THIS_VAR as a string in a macro called VAR_OUTPUT +# +# VAR_OUTPUT: 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_OUTPUT 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_OUTPUT + if(${IS_VALID_VALUE}) + + if(0) + # Optional debug + message(STATUS "Looking for LF in ${THIS_VAR}") + endif() + + # Check if the text to print in THIS_VAR is multi-line + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + list(LENGTH LINES LINE_COUNT) + + # Save var to "libwolfssl_output.h" header if multi-line, otherwise a simple compile def + if(LINE_COUNT GREATER 1) + message(STATUS "Setting HAVE_LIBWOLFSSL_OUTPUT_HEADER=1 for ${VAR_OUTPUT}") + add_compile_definitions(HAVE_LIBWOLFSSL_OUTPUT_HEADER=1) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#undef ${VAR_OUTPUT}\n") + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#define ${VAR_OUTPUT} \\\n") + + # Split into lines + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + foreach(LINE IN LISTS LINES) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\"${LINE}\\n\" \\\n") + endforeach() + + # Final empty line to close the macro + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\n") + + message(STATUS "COMPONENT_LIB=${COMPONENT_LIB}") + target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_BINARY_DIR}") + else() + message(STATUS "No HAS_LIBWOLFSSL_OUTPUT_HEADER") + # We should not have any, but just to be sure: + # 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_OUTPUT} ${VAR_VALUE} PARENT_SCOPE) + + # but we're only using it here in this function + set(${VAR_OUTPUT} ${VAR_VALUE}) + + # we'll print what we found to the console + message(STATUS "Found ${VAR_OUTPUT}=${VAR_VALUE}") + + # the interesting part is defining the VAR_OUTPUT name a value to use in the app + add_compile_definitions(${VAR_OUTPUT}=\"${VAR_VALUE}\") + + endif() + 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_OUTPUT} "Unknown") + endif() + + +endfunction() # LIBWOLFSSL_SAVE_INFO + +# +# APPEND_LIBWOLFSSL_CMAKE_OUTPUT(THIS_MESSAGE OUTPUT_VALUE) +# +# Append the text in THIS_MESSAGE to LIBWOLFSSL_CMAKE_OUTPUT. +# String is available at runtime in app +# + +function( APPEND_LIBWOLFSSL_CMAKE_OUTPUT + THIS_MESSAGE ) + # Normally, we'd simply print a message: + message(STATUS "${THIS_MESSAGE}") + + # But here we'll pass the entire LIBWOLFSSL_CMAKE_OUTPUT as a string definition to the app + set(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n${THIS_MESSAGE}" PARENT_SCOPE) + + # We don't call LIBWOLFSSL_SAVE_INFO here as it would add duplicate definitions + # See single instance at the end of this file. +endfunction() + # Determine if this cmake file is located in the ESP-IDF component directory or not, # and if so, if it is being ignored (allowing the use of a local project one, instead). IS_ESP_IDF_COMPONENT( IS_WOLSSL_ESP_IDF_COMPONENT ) @@ -77,20 +206,6 @@ else() message(STATUS "Cleaned wolfssl path: ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") endif() -# The scope of this CMAKE_C_FLAGS is just this component: -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_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() - if( "$ENV{IDF_PATH}" STREQUAL "" ) message(FATAL_ERROR "IDF_PATH Environment variable not set!") else() @@ -185,7 +300,9 @@ endif() # Check environment variable name EVARPARAM as [name] # If defined, and has a value of EVARVALUE as [value], # then assign a compiler definition "-D[name]=[value]" -function(ENVIRONMENT_VAR_TO_MACRO EVARPARAM EVARVALUE) +function( ENVIRONMENT_VAR_TO_MACRO + EVARPARAM # Environment variable parameter name + EVARVALUE) # Environment variable value # If the EVARPARAM environment variable name is set to EVARVALUE, # set the compiler flag definition to enable CSV output. if ( "$ENV{${EVARPARAM}}" STREQUAL "${EVARVALUE}") @@ -217,7 +334,8 @@ endfunction() # 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 +function( IS_WOLFSSL_SOURCE + DIRECTORY_PARAMETER RESULT ) if (EXISTS "${DIRECTORY_PARAMETER}/wolfcrypt/src") set(${RESULT} "${DIRECTORY_PARAMETER}" PARENT_SCOPE) @@ -233,7 +351,8 @@ endfunction() # Example usage: # FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT) # ********************************************************************************************* -function(FIND_WOLFSSL_DIRECTORY OUTPUT_FOUND_WOLFSSL_DIRECTORY) +function( FIND_WOLFSSL_DIRECTORY + OUTPUT_FOUND_WOLFSSL_DIRECTORY) message(STATUS "Starting FIND_WOLFSSL_DIRECTORY: ${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}") if ( "${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}" STREQUAL "" ) @@ -673,9 +792,9 @@ else() # 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") - if(WOLFSSL_ROOT) - string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) - endif() + if(WOLFSSL_ROOT) + string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) + endif() if(IS_DIRECTORY "${RTOS_IDF_PATH}") message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}") @@ -789,16 +908,35 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE AND NOT CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE AND NOT ("${CONFIG_TARGET_PLATFORM}" STREQUAL "esp8266") ) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("wolfSSL Certificate Bundles Enabled") + if (CMAKE_BUILD_EARLY_EXPANSION) - message(ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") + message(FATAL_ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") endif() # reminder: we need a value for wolfSSL root first! if( "${WOLFSSL_ROOT}" STREQUAL "" ) - message(ERROR "Certificate bundles need a value for WOLFSSL_ROOT") + message(FATAL_ERROR "Certificate bundles need a value for WOLFSSL_ROOT") endif() + + # Cert bundle in wolfSSL source unless otherwise specified later set(WOLFSSL_ESP_CRT_BUNDLE_DIR ${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif/esp_crt_bundle) message(STATUS "WOLFSSL_ESP_CRT_BUNDLE_DIR=${WOLFSSL_ESP_CRT_BUNDLE_DIR}") - if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + + if(DEFINED ENV{PLATFORMIO_PROJECT_DIR}) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO") + set(IS_PLATFORMIO 1) + else() + # Some environments may not have environment variable, so double check if we are in .pio + if("${CMAKE_BINARY_DIR}" MATCHES "/\\.pio/") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO via CMAKE_BINARY_DIR") + set(IS_PLATFORMIO 1) + else() + set(IS_PLATFORMIO 0) + endif() + endif() + + if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}" OR IS_PLATFORMIO) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Special processing for wolfSSL Certificate Bundles") set(bundle_name "x509_crt_bundle_wolfssl") # For now the certs are in the same directory @@ -824,9 +962,9 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE get_filename_component(custom_bundle_path ${CONFIG_WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}") list(APPEND crt_paths ${custom_bundle_path}) - message(STATUS "Using a custom wolfSSL bundle path: ${custom_bundle_path}") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Using a custom wolfSSL bundle path: ${custom_bundle_path}") else() - message(STATUS "Not using a custom wolfSSL bundle path.") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Not using a custom wolfSSL bundle path") endif() list(APPEND args --input ${crt_paths} -q) @@ -843,25 +981,107 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE message(STATUS "args ${args}") message(STATUS "cert_bundle ${cert_bundle}") - # Generate bundle according to config - # File is generated at build time, not cmake load - add_custom_command(OUTPUT ${crt_bundle} - COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} - DEPENDS ${custom_bundle_path} - VERBATIM) + if (IS_PLATFORMIO) + # PlatformIO cannot generate a Certificate Bundle at build time + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("PlatformIO is using a predefined bundle rather than generating one") - if(EXISTS "${crt_bundle}") - message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + if ( "${WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "n") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Alternate Certificate Bundle Path and Name not enabled, assuming [project]/certs/x509_crt_bundle_wolfssl") + # Reminder this CMakeLists.txt should be in [project]/components/wolfssl, so ./certs is two directories up + set(crt_bundle_option "../../certs/x509_crt_bundle_wolfssl") + else() + string(SUBSTRING "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" 0 2 CERT_PATH_FIRST_TWO) + if(CERT_PATH_FIRST_TWO STREQUAL "./" OR CERT_PATH_FIRST_TWO STREQUAL ".\\") + set(IS_CERT_BUNDLE_RELATIVE_PATH 1) + message(STATUS "Alternate Cert Path is relative to project.") + else() + set(IS_CERT_BUNDLE_RELATIVE_PATH 0) + message(STATUS "Alternate Cert Path is not relative to project.") + endif() + + # The cert bundle is not a standard cert, so we con't add to the crt_paths. + # Still, we may have an alternate location, particulatly needed for PlatformIO: + if(IS_CERT_BUNDLE_RELATIVE_PATH) + message(STATUS "CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME = ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Relative alternate_bundle_path: ${alternate_bundle_path}") + + SET(crt_bundle_option "${CMAKE_SOURCE_DIR}/${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + else() + message(STATUS "alternate_bundle_path: ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Not using an alternate wolfSSL bundle file.") + SET(crt_bundle_option "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + endif() + endif() + + # Clean the path, removing any extra "./" etc. + # Number of spaces in message strings is to align path value outputs + message(STATUS "This crt_bundle_option value: ${crt_bundle_option}") + if(${CMAKE_VERSION} VERSION_LESS "3.19") + message("WARNING: CMake version is ${CMAKE_VERSION} ? file(REAL_PATH ...) is not supported. Falling back to manual path normalization.") + # optional fallback logic here + get_filename_component(crt_bundle_file_component "${crt_bundle_option}" ABSOLUTE) + message(STATUS "Interim crt_bundle_file_component: ${crt_bundle_file_component}") + file(TO_CMAKE_PATH "${crt_bundle_file_component}" crt_bundle) + message(STATUS "TO_CMAKE_PATH crt_bundle result: ${crt_bundle}") + # set(crt_bundle "C:/workspace/pio_wolfssl-upstream-test-wolfssl_cert_bundle/esp32-c6/certs/x509_crt_bundle_wolfssl") + else() + file(REAL_PATH "${crt_bundle_option}" crt_bundle) + endif() + + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Certificate Bundle: ${crt_bundle}") + message(STATUS "This cleaned crt_bundle value: ${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + message(STATUS "Reminder: platformio.ini will need this value set for board_build.embed_files =") + message(STATUS "${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + + # e.g. SET(crt_bundle "C:/workspace/pio_wolfssl/esp32-c6/certs/x509_crt_bundle_wolfssl") + # + + # Normally x509_crt_bundle_wolfssl built by python script called from cmake. + # See https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/src/port/Espressif/esp_crt_bundle/gen_crt_bundle.py + # Reminder ESP-IDF scripts are NOT called from CMake for PlatformIO builds. + # + # The easiest way to generate the default file is to build with ESP-IDF and copy the files to [project]/main + # + # for example: + # build\VisualGDB\Debug\x509_crt_bundle_wolfssl.s + # build\VisualGDB\Debug\esp-idf\wolfssl\x509_crt_bundle_wolfssl + # + message(STATUS "Confirming cert bundle exists...") + if(EXISTS "${crt_bundle}") + # Number of spaces is to align path value outputs + message(STATUS "Bundle file found for PlatformIO: ${crt_bundle}") + else() + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("ERROR: Failed to find bundle file found for PlatformIO: ${crt_bundle}") + message(STATUS "Check for entry in platformio.ini: board_build.embed_files = certs/x509_crt_bundle_wolfssl ") + message(FATAL_ERROR "WOLFSSL_CERTIFICATE_BUNDLE is enabled for PlatformIO, but predefined file not found: ${crt_bundle}") + endif() else() - message(STATUS "Bundle file expected during next build: ${crt_bundle}") + # APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Generate bundle: ${GENERATE_CERT_BUNDLEPY} ${args}") + # Not PlatformIO + # Generate bundle according to config + # File is generated at build time, not cmake load + add_custom_command(OUTPUT ${crt_bundle} + COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} + DEPENDS ${custom_bundle_path} + VERBATIM) + + if(EXISTS "${crt_bundle}") + message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + else() + message(STATUS "Bundle file expected during next build: ${crt_bundle}") + endif() + + # Reminder the file is generated at build time, not cmake load time. + message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") endif() - # Reminder the file is generated at build time, not cmake load time. - message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") + add_custom_target(custom_wolfssl_bundle DEPENDS ${crt_bundle}) - add_custom_target(custom_wolfssl_bundle DEPENDS ${cert_bundle}) - - # the wolfSSL crtificate bundle is baked into wolfSSL + # the wolfSSL certificate bundle is baked into wolfSSL add_dependencies(${COMPONENT_LIB} custom_wolfssl_bundle) # COMPONENT_LIB may vary: __idf_wolfssl, __idf_esp_wolfssl, etc @@ -871,7 +1091,12 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${crt_bundle}") else() - message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + if(IS_PLATFORMIO) + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but cannot be generated in PlatformmIO") + else() + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + endif() + message(FATAL_ERROR "not detected") endif() endif() @@ -930,42 +1155,6 @@ 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_compile_definitions(${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 - execute_process( COMMAND ${git_cmd} "rev-parse" "--is-inside-work-tree" OUTPUT_VARIABLE IS_GIT_REPO @@ -1049,6 +1238,14 @@ else() message(STATUS "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") endif() +# A single instance of potentially multiple cmake messages to send to app: +message(STATUS "LIBWOLFSSL_CMAKE_OUTPUT: ${LIBWOLFSSL_CMAKE_OUTPUT}") +LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}" "0") + +file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "\n" + "#endif\n" ) + message(STATUS "************************************************************************************************") message(STATUS "wolfSSL component config complete!") message(STATUS "************************************************************************************************") diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/Kconfig b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/Kconfig index 9a7fcaa07..ee8dc7f1a 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/Kconfig +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/Kconfig @@ -274,10 +274,28 @@ menu "wolfSSL" bool "Do not use the default certificate bundle" endchoice + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE + depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + default n + bool "Use alternate certificate bundle" + help + Typically only used for PlatformIO which cannot generate a certificate bundle at build time. + Enable this option to specify a fixed wolfSSL certificate file path and file name. + + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME + depends on WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + string "Default certificate bundle alternate path and name" + default "./certs/x509_crt_bundle_wolfssl" + help + Name of the default certificate bundle directory. Typically used only with PlatformIO. + Reminder PlatformIO cannot generate a bundle from cmake python script call. Relative + paths are with respect to root of this project. + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL default n bool "Add custom certificates to the default bundle" + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH depends on WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL string "Custom certificate bundle path" @@ -430,6 +448,12 @@ menu "wolfSSL" help Enable debugging messages for wolfSSL. See user_settings.h for additional debug options. + config ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING + bool "Suppress build-time warnings for main stack size" + default n + help + Useful only when wolfSSL is running in main task. See FreeRTOS stack size for custom tasks. + config ESP_WOLFSSL_TEST_LOOP bool "Run test apps in a loop until failure" default y diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/include/user_settings.h b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/include/user_settings.h index 488182ed6..80f89fffe 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/include/user_settings.h +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/include/user_settings.h @@ -853,13 +853,18 @@ #ifndef NO_RSA #define ESP32_USE_RSA_PRIMITIVE - #if defined(CONFIG_IDF_TARGET_ESP32) - #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + /* See idf.py menuconfig for stack warning settings */ + #if !defined(CONFIG_ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING) #if CONFIG_ESP_MAIN_TASK_STACK_SIZE < 10500 - #warning "RSA may be difficult with less than 10KB Stack "/ + #warning "RSA may be difficult with less than 10KB Stack" #endif + #else + /* Implement your own stack warning here */ #endif + #endif + #if defined(CONFIG_IDF_TARGET_ESP32) /* NOTE HW unreliable for small values! */ /* threshold for performance adjustment for HW primitive use */ /* X bits of G^X mod P greater than */ diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt index cc7ef0d47..b4a2b74c1 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt @@ -19,23 +19,62 @@ # # cmake for wolfssl Espressif projects # -# Version 5.7.2 Espressif ESP-IDF integration +# Version 5.8.0 Espressif ESP-IDF + PlatformIO integration (2) # # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html # message(STATUS "Begin wolfssl ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") cmake_minimum_required(VERSION 3.16) +# The scope of this CMAKE_C_FLAGS is just this component: +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWOLFSSL_USER_SETTINGS") + +set(CMAKE_CURRENT_SOURCE_DIR ".") + +# Optionally set your source to wolfSSL in your project CMakeLists.txt like this: +# set(WOLFSSL_ROOT "c:/workspace/my_wolfssl" ) + +if ( "${WOLFSSL_ROOT}" STREQUAL "") + set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" ) +endif() + set(VERBOSE_COMPONENT_MESSAGES 1) # Optional requires include: # set(THIS_ESP_TLS "esp-tls") set(THIS_ESP_TLS "") +# LIBWOLFSSL_CMAKE_OUTPUT can be printed at runtime +set(LIBWOLFSSL_CMAKE_OUTPUT "") + + +if(CMAKE_BUILD_EARLY_EXPANSION) + message(STATUS "Skipping libwolfssl_output.h update during CMAKE_BUILD_EARLY_EXPANSION") +else() + # Initialize a new libwolfssl_output.h in the cmake build directory. + if( EXISTS "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + # The next WRITE replaces a file. + # This is here to remove any ambiguity on file removal & generation. + file(REMOVE "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + endif() + + file(WRITE "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "/* libwolfssl_output.h generated by wolfssl component */\n" + "#ifndef _LIBWOLFSSL_OUTPUT_H_\n" + "\n" + "#define _LIBWOLFSSL_OUTPUT_H_\n\n") +endif() + +# Append messages with: +# LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n"message" "0") +# See function: APPEND_LIBWOLFSSL_CMAKE_OUTPUT + # function: IS_ESP_IDF_COMPONENT # output: RESULT = 1 (true) if this component is located in the ESP-IDF components # otherwise 0 (false) -function( IS_ESP_IDF_COMPONENT RESULT ) +function( IS_ESP_IDF_COMPONENT + RESULT) # NOTE: Component location is based on the location of the CMakeList.txt # and *not* the location of the wolfSSL source code. (which may be anywhere) @@ -55,6 +94,96 @@ function( IS_ESP_IDF_COMPONENT RESULT ) endif() endfunction() +# +# LIBWOLFSSL_SAVE_INFO(VAR_OUTPUT THIS_VAR VAR_RESULT) +# +# Save the THIS_VAR as a string in a macro called VAR_OUTPUT +# +# VAR_OUTPUT: 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_OUTPUT 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_OUTPUT + if(${IS_VALID_VALUE}) + + if(0) + # Optional debug + message(STATUS "Looking for LF in ${THIS_VAR}") + endif() + + # Check if the text to print in THIS_VAR is multi-line + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + list(LENGTH LINES LINE_COUNT) + + # Save var to "libwolfssl_output.h" header if multi-line, otherwise a simple compile def + if(LINE_COUNT GREATER 1) + message(STATUS "Setting HAVE_LIBWOLFSSL_OUTPUT_HEADER=1 for ${VAR_OUTPUT}") + add_compile_definitions(HAVE_LIBWOLFSSL_OUTPUT_HEADER=1) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#undef ${VAR_OUTPUT}\n") + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#define ${VAR_OUTPUT} \\\n") + + # Split into lines + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + foreach(LINE IN LISTS LINES) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\"${LINE}\\n\" \\\n") + endforeach() + + # Final empty line to close the macro + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\n") + + message(STATUS "COMPONENT_LIB=${COMPONENT_LIB}") + target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_BINARY_DIR}") + else() + message(STATUS "No HAS_LIBWOLFSSL_OUTPUT_HEADER") + # We should not have any, but just to be sure: + # 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_OUTPUT} ${VAR_VALUE} PARENT_SCOPE) + + # but we're only using it here in this function + set(${VAR_OUTPUT} ${VAR_VALUE}) + + # we'll print what we found to the console + message(STATUS "Found ${VAR_OUTPUT}=${VAR_VALUE}") + + # the interesting part is defining the VAR_OUTPUT name a value to use in the app + add_compile_definitions(${VAR_OUTPUT}=\"${VAR_VALUE}\") + + endif() + 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_OUTPUT} "Unknown") + endif() + + +endfunction() # LIBWOLFSSL_SAVE_INFO + +# +# APPEND_LIBWOLFSSL_CMAKE_OUTPUT(THIS_MESSAGE OUTPUT_VALUE) +# +# Append the text in THIS_MESSAGE to LIBWOLFSSL_CMAKE_OUTPUT. +# String is available at runtime in app +# + +function( APPEND_LIBWOLFSSL_CMAKE_OUTPUT + THIS_MESSAGE ) + # Normally, we'd simply print a message: + message(STATUS "${THIS_MESSAGE}") + + # But here we'll pass the entire LIBWOLFSSL_CMAKE_OUTPUT as a string definition to the app + set(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n${THIS_MESSAGE}" PARENT_SCOPE) + + # We don't call LIBWOLFSSL_SAVE_INFO here as it would add duplicate definitions + # See single instance at the end of this file. +endfunction() + # Determine if this cmake file is located in the ESP-IDF component directory or not, # and if so, if it is being ignored (allowing the use of a local project one, instead). IS_ESP_IDF_COMPONENT( IS_WOLSSL_ESP_IDF_COMPONENT ) @@ -77,20 +206,6 @@ else() message(STATUS "Cleaned wolfssl path: ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") endif() -# The scope of this CMAKE_C_FLAGS is just this component: -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_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() - if( "$ENV{IDF_PATH}" STREQUAL "" ) message(FATAL_ERROR "IDF_PATH Environment variable not set!") else() @@ -185,7 +300,9 @@ endif() # Check environment variable name EVARPARAM as [name] # If defined, and has a value of EVARVALUE as [value], # then assign a compiler definition "-D[name]=[value]" -function(ENVIRONMENT_VAR_TO_MACRO EVARPARAM EVARVALUE) +function( ENVIRONMENT_VAR_TO_MACRO + EVARPARAM # Environment variable parameter name + EVARVALUE) # Environment variable value # If the EVARPARAM environment variable name is set to EVARVALUE, # set the compiler flag definition to enable CSV output. if ( "$ENV{${EVARPARAM}}" STREQUAL "${EVARVALUE}") @@ -217,7 +334,8 @@ endfunction() # 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 +function( IS_WOLFSSL_SOURCE + DIRECTORY_PARAMETER RESULT ) if (EXISTS "${DIRECTORY_PARAMETER}/wolfcrypt/src") set(${RESULT} "${DIRECTORY_PARAMETER}" PARENT_SCOPE) @@ -233,7 +351,8 @@ endfunction() # Example usage: # FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT) # ********************************************************************************************* -function(FIND_WOLFSSL_DIRECTORY OUTPUT_FOUND_WOLFSSL_DIRECTORY) +function( FIND_WOLFSSL_DIRECTORY + OUTPUT_FOUND_WOLFSSL_DIRECTORY) message(STATUS "Starting FIND_WOLFSSL_DIRECTORY: ${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}") if ( "${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}" STREQUAL "" ) @@ -673,9 +792,9 @@ else() # 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") - if(WOLFSSL_ROOT) - string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) - endif() + if(WOLFSSL_ROOT) + string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) + endif() if(IS_DIRECTORY "${RTOS_IDF_PATH}") message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}") @@ -789,16 +908,35 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE AND NOT CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE AND NOT ("${CONFIG_TARGET_PLATFORM}" STREQUAL "esp8266") ) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("wolfSSL Certificate Bundles Enabled") + if (CMAKE_BUILD_EARLY_EXPANSION) - message(ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") + message(FATAL_ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") endif() # reminder: we need a value for wolfSSL root first! if( "${WOLFSSL_ROOT}" STREQUAL "" ) - message(ERROR "Certificate bundles need a value for WOLFSSL_ROOT") + message(FATAL_ERROR "Certificate bundles need a value for WOLFSSL_ROOT") endif() + + # Cert bundle in wolfSSL source unless otherwise specified later set(WOLFSSL_ESP_CRT_BUNDLE_DIR ${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif/esp_crt_bundle) message(STATUS "WOLFSSL_ESP_CRT_BUNDLE_DIR=${WOLFSSL_ESP_CRT_BUNDLE_DIR}") - if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + + if(DEFINED ENV{PLATFORMIO_PROJECT_DIR}) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO") + set(IS_PLATFORMIO 1) + else() + # Some environments may not have environment variable, so double check if we are in .pio + if("${CMAKE_BINARY_DIR}" MATCHES "/\\.pio/") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO via CMAKE_BINARY_DIR") + set(IS_PLATFORMIO 1) + else() + set(IS_PLATFORMIO 0) + endif() + endif() + + if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}" OR IS_PLATFORMIO) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Special processing for wolfSSL Certificate Bundles") set(bundle_name "x509_crt_bundle_wolfssl") # For now the certs are in the same directory @@ -824,9 +962,9 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE get_filename_component(custom_bundle_path ${CONFIG_WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}") list(APPEND crt_paths ${custom_bundle_path}) - message(STATUS "Using a custom wolfSSL bundle path: ${custom_bundle_path}") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Using a custom wolfSSL bundle path: ${custom_bundle_path}") else() - message(STATUS "Not using a custom wolfSSL bundle path.") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Not using a custom wolfSSL bundle path") endif() list(APPEND args --input ${crt_paths} -q) @@ -843,25 +981,107 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE message(STATUS "args ${args}") message(STATUS "cert_bundle ${cert_bundle}") - # Generate bundle according to config - # File is generated at build time, not cmake load - add_custom_command(OUTPUT ${crt_bundle} - COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} - DEPENDS ${custom_bundle_path} - VERBATIM) + if (IS_PLATFORMIO) + # PlatformIO cannot generate a Certificate Bundle at build time + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("PlatformIO is using a predefined bundle rather than generating one") - if(EXISTS "${crt_bundle}") - message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + if ( "${WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "n") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Alternate Certificate Bundle Path and Name not enabled, assuming [project]/certs/x509_crt_bundle_wolfssl") + # Reminder this CMakeLists.txt should be in [project]/components/wolfssl, so ./certs is two directories up + set(crt_bundle_option "../../certs/x509_crt_bundle_wolfssl") + else() + string(SUBSTRING "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" 0 2 CERT_PATH_FIRST_TWO) + if(CERT_PATH_FIRST_TWO STREQUAL "./" OR CERT_PATH_FIRST_TWO STREQUAL ".\\") + set(IS_CERT_BUNDLE_RELATIVE_PATH 1) + message(STATUS "Alternate Cert Path is relative to project.") + else() + set(IS_CERT_BUNDLE_RELATIVE_PATH 0) + message(STATUS "Alternate Cert Path is not relative to project.") + endif() + + # The cert bundle is not a standard cert, so we con't add to the crt_paths. + # Still, we may have an alternate location, particulatly needed for PlatformIO: + if(IS_CERT_BUNDLE_RELATIVE_PATH) + message(STATUS "CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME = ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Relative alternate_bundle_path: ${alternate_bundle_path}") + + SET(crt_bundle_option "${CMAKE_SOURCE_DIR}/${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + else() + message(STATUS "alternate_bundle_path: ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Not using an alternate wolfSSL bundle file.") + SET(crt_bundle_option "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + endif() + endif() + + # Clean the path, removing any extra "./" etc. + # Number of spaces in message strings is to align path value outputs + message(STATUS "This crt_bundle_option value: ${crt_bundle_option}") + if(${CMAKE_VERSION} VERSION_LESS "3.19") + message("WARNING: CMake version is ${CMAKE_VERSION} ? file(REAL_PATH ...) is not supported. Falling back to manual path normalization.") + # optional fallback logic here + get_filename_component(crt_bundle_file_component "${crt_bundle_option}" ABSOLUTE) + message(STATUS "Interim crt_bundle_file_component: ${crt_bundle_file_component}") + file(TO_CMAKE_PATH "${crt_bundle_file_component}" crt_bundle) + message(STATUS "TO_CMAKE_PATH crt_bundle result: ${crt_bundle}") + # set(crt_bundle "C:/workspace/pio_wolfssl-upstream-test-wolfssl_cert_bundle/esp32-c6/certs/x509_crt_bundle_wolfssl") + else() + file(REAL_PATH "${crt_bundle_option}" crt_bundle) + endif() + + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Certificate Bundle: ${crt_bundle}") + message(STATUS "This cleaned crt_bundle value: ${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + message(STATUS "Reminder: platformio.ini will need this value set for board_build.embed_files =") + message(STATUS "${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + + # e.g. SET(crt_bundle "C:/workspace/pio_wolfssl/esp32-c6/certs/x509_crt_bundle_wolfssl") + # + + # Normally x509_crt_bundle_wolfssl built by python script called from cmake. + # See https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/src/port/Espressif/esp_crt_bundle/gen_crt_bundle.py + # Reminder ESP-IDF scripts are NOT called from CMake for PlatformIO builds. + # + # The easiest way to generate the default file is to build with ESP-IDF and copy the files to [project]/main + # + # for example: + # build\VisualGDB\Debug\x509_crt_bundle_wolfssl.s + # build\VisualGDB\Debug\esp-idf\wolfssl\x509_crt_bundle_wolfssl + # + message(STATUS "Confirming cert bundle exists...") + if(EXISTS "${crt_bundle}") + # Number of spaces is to align path value outputs + message(STATUS "Bundle file found for PlatformIO: ${crt_bundle}") + else() + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("ERROR: Failed to find bundle file found for PlatformIO: ${crt_bundle}") + message(STATUS "Check for entry in platformio.ini: board_build.embed_files = certs/x509_crt_bundle_wolfssl ") + message(FATAL_ERROR "WOLFSSL_CERTIFICATE_BUNDLE is enabled for PlatformIO, but predefined file not found: ${crt_bundle}") + endif() else() - message(STATUS "Bundle file expected during next build: ${crt_bundle}") + # APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Generate bundle: ${GENERATE_CERT_BUNDLEPY} ${args}") + # Not PlatformIO + # Generate bundle according to config + # File is generated at build time, not cmake load + add_custom_command(OUTPUT ${crt_bundle} + COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} + DEPENDS ${custom_bundle_path} + VERBATIM) + + if(EXISTS "${crt_bundle}") + message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + else() + message(STATUS "Bundle file expected during next build: ${crt_bundle}") + endif() + + # Reminder the file is generated at build time, not cmake load time. + message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") endif() - # Reminder the file is generated at build time, not cmake load time. - message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") + add_custom_target(custom_wolfssl_bundle DEPENDS ${crt_bundle}) - add_custom_target(custom_wolfssl_bundle DEPENDS ${cert_bundle}) - - # the wolfSSL crtificate bundle is baked into wolfSSL + # the wolfSSL certificate bundle is baked into wolfSSL add_dependencies(${COMPONENT_LIB} custom_wolfssl_bundle) # COMPONENT_LIB may vary: __idf_wolfssl, __idf_esp_wolfssl, etc @@ -871,7 +1091,12 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${crt_bundle}") else() - message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + if(IS_PLATFORMIO) + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but cannot be generated in PlatformmIO") + else() + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + endif() + message(FATAL_ERROR "not detected") endif() endif() @@ -930,42 +1155,6 @@ 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_compile_definitions(${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 - execute_process( COMMAND ${git_cmd} "rev-parse" "--is-inside-work-tree" OUTPUT_VARIABLE IS_GIT_REPO @@ -1049,6 +1238,14 @@ else() message(STATUS "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") endif() +# A single instance of potentially multiple cmake messages to send to app: +message(STATUS "LIBWOLFSSL_CMAKE_OUTPUT: ${LIBWOLFSSL_CMAKE_OUTPUT}") +LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}" "0") + +file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "\n" + "#endif\n" ) + message(STATUS "************************************************************************************************") message(STATUS "wolfSSL component config complete!") message(STATUS "************************************************************************************************") diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/Kconfig b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/Kconfig index 9a7fcaa07..ee8dc7f1a 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/Kconfig +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/Kconfig @@ -274,10 +274,28 @@ menu "wolfSSL" bool "Do not use the default certificate bundle" endchoice + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE + depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + default n + bool "Use alternate certificate bundle" + help + Typically only used for PlatformIO which cannot generate a certificate bundle at build time. + Enable this option to specify a fixed wolfSSL certificate file path and file name. + + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME + depends on WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + string "Default certificate bundle alternate path and name" + default "./certs/x509_crt_bundle_wolfssl" + help + Name of the default certificate bundle directory. Typically used only with PlatformIO. + Reminder PlatformIO cannot generate a bundle from cmake python script call. Relative + paths are with respect to root of this project. + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL default n bool "Add custom certificates to the default bundle" + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH depends on WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL string "Custom certificate bundle path" @@ -430,6 +448,12 @@ menu "wolfSSL" help Enable debugging messages for wolfSSL. See user_settings.h for additional debug options. + config ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING + bool "Suppress build-time warnings for main stack size" + default n + help + Useful only when wolfSSL is running in main task. See FreeRTOS stack size for custom tasks. + config ESP_WOLFSSL_TEST_LOOP bool "Run test apps in a loop until failure" default y diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/include/user_settings.h b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/include/user_settings.h index 488182ed6..80f89fffe 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/include/user_settings.h +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/include/user_settings.h @@ -853,13 +853,18 @@ #ifndef NO_RSA #define ESP32_USE_RSA_PRIMITIVE - #if defined(CONFIG_IDF_TARGET_ESP32) - #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + /* See idf.py menuconfig for stack warning settings */ + #if !defined(CONFIG_ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING) #if CONFIG_ESP_MAIN_TASK_STACK_SIZE < 10500 - #warning "RSA may be difficult with less than 10KB Stack "/ + #warning "RSA may be difficult with less than 10KB Stack" #endif + #else + /* Implement your own stack warning here */ #endif + #endif + #if defined(CONFIG_IDF_TARGET_ESP32) /* NOTE HW unreliable for small values! */ /* threshold for performance adjustment for HW primitive use */ /* X bits of G^X mod P greater than */ diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt index cc7ef0d47..b4a2b74c1 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt @@ -19,23 +19,62 @@ # # cmake for wolfssl Espressif projects # -# Version 5.7.2 Espressif ESP-IDF integration +# Version 5.8.0 Espressif ESP-IDF + PlatformIO integration (2) # # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html # message(STATUS "Begin wolfssl ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") cmake_minimum_required(VERSION 3.16) +# The scope of this CMAKE_C_FLAGS is just this component: +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWOLFSSL_USER_SETTINGS") + +set(CMAKE_CURRENT_SOURCE_DIR ".") + +# Optionally set your source to wolfSSL in your project CMakeLists.txt like this: +# set(WOLFSSL_ROOT "c:/workspace/my_wolfssl" ) + +if ( "${WOLFSSL_ROOT}" STREQUAL "") + set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" ) +endif() + set(VERBOSE_COMPONENT_MESSAGES 1) # Optional requires include: # set(THIS_ESP_TLS "esp-tls") set(THIS_ESP_TLS "") +# LIBWOLFSSL_CMAKE_OUTPUT can be printed at runtime +set(LIBWOLFSSL_CMAKE_OUTPUT "") + + +if(CMAKE_BUILD_EARLY_EXPANSION) + message(STATUS "Skipping libwolfssl_output.h update during CMAKE_BUILD_EARLY_EXPANSION") +else() + # Initialize a new libwolfssl_output.h in the cmake build directory. + if( EXISTS "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + # The next WRITE replaces a file. + # This is here to remove any ambiguity on file removal & generation. + file(REMOVE "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + endif() + + file(WRITE "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "/* libwolfssl_output.h generated by wolfssl component */\n" + "#ifndef _LIBWOLFSSL_OUTPUT_H_\n" + "\n" + "#define _LIBWOLFSSL_OUTPUT_H_\n\n") +endif() + +# Append messages with: +# LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n"message" "0") +# See function: APPEND_LIBWOLFSSL_CMAKE_OUTPUT + # function: IS_ESP_IDF_COMPONENT # output: RESULT = 1 (true) if this component is located in the ESP-IDF components # otherwise 0 (false) -function( IS_ESP_IDF_COMPONENT RESULT ) +function( IS_ESP_IDF_COMPONENT + RESULT) # NOTE: Component location is based on the location of the CMakeList.txt # and *not* the location of the wolfSSL source code. (which may be anywhere) @@ -55,6 +94,96 @@ function( IS_ESP_IDF_COMPONENT RESULT ) endif() endfunction() +# +# LIBWOLFSSL_SAVE_INFO(VAR_OUTPUT THIS_VAR VAR_RESULT) +# +# Save the THIS_VAR as a string in a macro called VAR_OUTPUT +# +# VAR_OUTPUT: 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_OUTPUT 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_OUTPUT + if(${IS_VALID_VALUE}) + + if(0) + # Optional debug + message(STATUS "Looking for LF in ${THIS_VAR}") + endif() + + # Check if the text to print in THIS_VAR is multi-line + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + list(LENGTH LINES LINE_COUNT) + + # Save var to "libwolfssl_output.h" header if multi-line, otherwise a simple compile def + if(LINE_COUNT GREATER 1) + message(STATUS "Setting HAVE_LIBWOLFSSL_OUTPUT_HEADER=1 for ${VAR_OUTPUT}") + add_compile_definitions(HAVE_LIBWOLFSSL_OUTPUT_HEADER=1) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#undef ${VAR_OUTPUT}\n") + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#define ${VAR_OUTPUT} \\\n") + + # Split into lines + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + foreach(LINE IN LISTS LINES) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\"${LINE}\\n\" \\\n") + endforeach() + + # Final empty line to close the macro + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\n") + + message(STATUS "COMPONENT_LIB=${COMPONENT_LIB}") + target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_BINARY_DIR}") + else() + message(STATUS "No HAS_LIBWOLFSSL_OUTPUT_HEADER") + # We should not have any, but just to be sure: + # 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_OUTPUT} ${VAR_VALUE} PARENT_SCOPE) + + # but we're only using it here in this function + set(${VAR_OUTPUT} ${VAR_VALUE}) + + # we'll print what we found to the console + message(STATUS "Found ${VAR_OUTPUT}=${VAR_VALUE}") + + # the interesting part is defining the VAR_OUTPUT name a value to use in the app + add_compile_definitions(${VAR_OUTPUT}=\"${VAR_VALUE}\") + + endif() + 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_OUTPUT} "Unknown") + endif() + + +endfunction() # LIBWOLFSSL_SAVE_INFO + +# +# APPEND_LIBWOLFSSL_CMAKE_OUTPUT(THIS_MESSAGE OUTPUT_VALUE) +# +# Append the text in THIS_MESSAGE to LIBWOLFSSL_CMAKE_OUTPUT. +# String is available at runtime in app +# + +function( APPEND_LIBWOLFSSL_CMAKE_OUTPUT + THIS_MESSAGE ) + # Normally, we'd simply print a message: + message(STATUS "${THIS_MESSAGE}") + + # But here we'll pass the entire LIBWOLFSSL_CMAKE_OUTPUT as a string definition to the app + set(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n${THIS_MESSAGE}" PARENT_SCOPE) + + # We don't call LIBWOLFSSL_SAVE_INFO here as it would add duplicate definitions + # See single instance at the end of this file. +endfunction() + # Determine if this cmake file is located in the ESP-IDF component directory or not, # and if so, if it is being ignored (allowing the use of a local project one, instead). IS_ESP_IDF_COMPONENT( IS_WOLSSL_ESP_IDF_COMPONENT ) @@ -77,20 +206,6 @@ else() message(STATUS "Cleaned wolfssl path: ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") endif() -# The scope of this CMAKE_C_FLAGS is just this component: -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_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() - if( "$ENV{IDF_PATH}" STREQUAL "" ) message(FATAL_ERROR "IDF_PATH Environment variable not set!") else() @@ -185,7 +300,9 @@ endif() # Check environment variable name EVARPARAM as [name] # If defined, and has a value of EVARVALUE as [value], # then assign a compiler definition "-D[name]=[value]" -function(ENVIRONMENT_VAR_TO_MACRO EVARPARAM EVARVALUE) +function( ENVIRONMENT_VAR_TO_MACRO + EVARPARAM # Environment variable parameter name + EVARVALUE) # Environment variable value # If the EVARPARAM environment variable name is set to EVARVALUE, # set the compiler flag definition to enable CSV output. if ( "$ENV{${EVARPARAM}}" STREQUAL "${EVARVALUE}") @@ -217,7 +334,8 @@ endfunction() # 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 +function( IS_WOLFSSL_SOURCE + DIRECTORY_PARAMETER RESULT ) if (EXISTS "${DIRECTORY_PARAMETER}/wolfcrypt/src") set(${RESULT} "${DIRECTORY_PARAMETER}" PARENT_SCOPE) @@ -233,7 +351,8 @@ endfunction() # Example usage: # FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT) # ********************************************************************************************* -function(FIND_WOLFSSL_DIRECTORY OUTPUT_FOUND_WOLFSSL_DIRECTORY) +function( FIND_WOLFSSL_DIRECTORY + OUTPUT_FOUND_WOLFSSL_DIRECTORY) message(STATUS "Starting FIND_WOLFSSL_DIRECTORY: ${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}") if ( "${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}" STREQUAL "" ) @@ -673,9 +792,9 @@ else() # 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") - if(WOLFSSL_ROOT) - string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) - endif() + if(WOLFSSL_ROOT) + string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) + endif() if(IS_DIRECTORY "${RTOS_IDF_PATH}") message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}") @@ -789,16 +908,35 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE AND NOT CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE AND NOT ("${CONFIG_TARGET_PLATFORM}" STREQUAL "esp8266") ) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("wolfSSL Certificate Bundles Enabled") + if (CMAKE_BUILD_EARLY_EXPANSION) - message(ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") + message(FATAL_ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") endif() # reminder: we need a value for wolfSSL root first! if( "${WOLFSSL_ROOT}" STREQUAL "" ) - message(ERROR "Certificate bundles need a value for WOLFSSL_ROOT") + message(FATAL_ERROR "Certificate bundles need a value for WOLFSSL_ROOT") endif() + + # Cert bundle in wolfSSL source unless otherwise specified later set(WOLFSSL_ESP_CRT_BUNDLE_DIR ${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif/esp_crt_bundle) message(STATUS "WOLFSSL_ESP_CRT_BUNDLE_DIR=${WOLFSSL_ESP_CRT_BUNDLE_DIR}") - if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + + if(DEFINED ENV{PLATFORMIO_PROJECT_DIR}) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO") + set(IS_PLATFORMIO 1) + else() + # Some environments may not have environment variable, so double check if we are in .pio + if("${CMAKE_BINARY_DIR}" MATCHES "/\\.pio/") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO via CMAKE_BINARY_DIR") + set(IS_PLATFORMIO 1) + else() + set(IS_PLATFORMIO 0) + endif() + endif() + + if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}" OR IS_PLATFORMIO) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Special processing for wolfSSL Certificate Bundles") set(bundle_name "x509_crt_bundle_wolfssl") # For now the certs are in the same directory @@ -824,9 +962,9 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE get_filename_component(custom_bundle_path ${CONFIG_WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}") list(APPEND crt_paths ${custom_bundle_path}) - message(STATUS "Using a custom wolfSSL bundle path: ${custom_bundle_path}") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Using a custom wolfSSL bundle path: ${custom_bundle_path}") else() - message(STATUS "Not using a custom wolfSSL bundle path.") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Not using a custom wolfSSL bundle path") endif() list(APPEND args --input ${crt_paths} -q) @@ -843,25 +981,107 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE message(STATUS "args ${args}") message(STATUS "cert_bundle ${cert_bundle}") - # Generate bundle according to config - # File is generated at build time, not cmake load - add_custom_command(OUTPUT ${crt_bundle} - COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} - DEPENDS ${custom_bundle_path} - VERBATIM) + if (IS_PLATFORMIO) + # PlatformIO cannot generate a Certificate Bundle at build time + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("PlatformIO is using a predefined bundle rather than generating one") - if(EXISTS "${crt_bundle}") - message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + if ( "${WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "n") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Alternate Certificate Bundle Path and Name not enabled, assuming [project]/certs/x509_crt_bundle_wolfssl") + # Reminder this CMakeLists.txt should be in [project]/components/wolfssl, so ./certs is two directories up + set(crt_bundle_option "../../certs/x509_crt_bundle_wolfssl") + else() + string(SUBSTRING "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" 0 2 CERT_PATH_FIRST_TWO) + if(CERT_PATH_FIRST_TWO STREQUAL "./" OR CERT_PATH_FIRST_TWO STREQUAL ".\\") + set(IS_CERT_BUNDLE_RELATIVE_PATH 1) + message(STATUS "Alternate Cert Path is relative to project.") + else() + set(IS_CERT_BUNDLE_RELATIVE_PATH 0) + message(STATUS "Alternate Cert Path is not relative to project.") + endif() + + # The cert bundle is not a standard cert, so we con't add to the crt_paths. + # Still, we may have an alternate location, particulatly needed for PlatformIO: + if(IS_CERT_BUNDLE_RELATIVE_PATH) + message(STATUS "CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME = ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Relative alternate_bundle_path: ${alternate_bundle_path}") + + SET(crt_bundle_option "${CMAKE_SOURCE_DIR}/${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + else() + message(STATUS "alternate_bundle_path: ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Not using an alternate wolfSSL bundle file.") + SET(crt_bundle_option "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + endif() + endif() + + # Clean the path, removing any extra "./" etc. + # Number of spaces in message strings is to align path value outputs + message(STATUS "This crt_bundle_option value: ${crt_bundle_option}") + if(${CMAKE_VERSION} VERSION_LESS "3.19") + message("WARNING: CMake version is ${CMAKE_VERSION} ? file(REAL_PATH ...) is not supported. Falling back to manual path normalization.") + # optional fallback logic here + get_filename_component(crt_bundle_file_component "${crt_bundle_option}" ABSOLUTE) + message(STATUS "Interim crt_bundle_file_component: ${crt_bundle_file_component}") + file(TO_CMAKE_PATH "${crt_bundle_file_component}" crt_bundle) + message(STATUS "TO_CMAKE_PATH crt_bundle result: ${crt_bundle}") + # set(crt_bundle "C:/workspace/pio_wolfssl-upstream-test-wolfssl_cert_bundle/esp32-c6/certs/x509_crt_bundle_wolfssl") + else() + file(REAL_PATH "${crt_bundle_option}" crt_bundle) + endif() + + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Certificate Bundle: ${crt_bundle}") + message(STATUS "This cleaned crt_bundle value: ${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + message(STATUS "Reminder: platformio.ini will need this value set for board_build.embed_files =") + message(STATUS "${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + + # e.g. SET(crt_bundle "C:/workspace/pio_wolfssl/esp32-c6/certs/x509_crt_bundle_wolfssl") + # + + # Normally x509_crt_bundle_wolfssl built by python script called from cmake. + # See https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/src/port/Espressif/esp_crt_bundle/gen_crt_bundle.py + # Reminder ESP-IDF scripts are NOT called from CMake for PlatformIO builds. + # + # The easiest way to generate the default file is to build with ESP-IDF and copy the files to [project]/main + # + # for example: + # build\VisualGDB\Debug\x509_crt_bundle_wolfssl.s + # build\VisualGDB\Debug\esp-idf\wolfssl\x509_crt_bundle_wolfssl + # + message(STATUS "Confirming cert bundle exists...") + if(EXISTS "${crt_bundle}") + # Number of spaces is to align path value outputs + message(STATUS "Bundle file found for PlatformIO: ${crt_bundle}") + else() + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("ERROR: Failed to find bundle file found for PlatformIO: ${crt_bundle}") + message(STATUS "Check for entry in platformio.ini: board_build.embed_files = certs/x509_crt_bundle_wolfssl ") + message(FATAL_ERROR "WOLFSSL_CERTIFICATE_BUNDLE is enabled for PlatformIO, but predefined file not found: ${crt_bundle}") + endif() else() - message(STATUS "Bundle file expected during next build: ${crt_bundle}") + # APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Generate bundle: ${GENERATE_CERT_BUNDLEPY} ${args}") + # Not PlatformIO + # Generate bundle according to config + # File is generated at build time, not cmake load + add_custom_command(OUTPUT ${crt_bundle} + COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} + DEPENDS ${custom_bundle_path} + VERBATIM) + + if(EXISTS "${crt_bundle}") + message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + else() + message(STATUS "Bundle file expected during next build: ${crt_bundle}") + endif() + + # Reminder the file is generated at build time, not cmake load time. + message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") endif() - # Reminder the file is generated at build time, not cmake load time. - message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") + add_custom_target(custom_wolfssl_bundle DEPENDS ${crt_bundle}) - add_custom_target(custom_wolfssl_bundle DEPENDS ${cert_bundle}) - - # the wolfSSL crtificate bundle is baked into wolfSSL + # the wolfSSL certificate bundle is baked into wolfSSL add_dependencies(${COMPONENT_LIB} custom_wolfssl_bundle) # COMPONENT_LIB may vary: __idf_wolfssl, __idf_esp_wolfssl, etc @@ -871,7 +1091,12 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${crt_bundle}") else() - message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + if(IS_PLATFORMIO) + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but cannot be generated in PlatformmIO") + else() + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + endif() + message(FATAL_ERROR "not detected") endif() endif() @@ -930,42 +1155,6 @@ 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_compile_definitions(${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 - execute_process( COMMAND ${git_cmd} "rev-parse" "--is-inside-work-tree" OUTPUT_VARIABLE IS_GIT_REPO @@ -1049,6 +1238,14 @@ else() message(STATUS "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") endif() +# A single instance of potentially multiple cmake messages to send to app: +message(STATUS "LIBWOLFSSL_CMAKE_OUTPUT: ${LIBWOLFSSL_CMAKE_OUTPUT}") +LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}" "0") + +file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "\n" + "#endif\n" ) + message(STATUS "************************************************************************************************") message(STATUS "wolfSSL component config complete!") message(STATUS "************************************************************************************************") diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/Kconfig b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/Kconfig index 9a7fcaa07..ee8dc7f1a 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/Kconfig +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/Kconfig @@ -274,10 +274,28 @@ menu "wolfSSL" bool "Do not use the default certificate bundle" endchoice + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE + depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + default n + bool "Use alternate certificate bundle" + help + Typically only used for PlatformIO which cannot generate a certificate bundle at build time. + Enable this option to specify a fixed wolfSSL certificate file path and file name. + + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME + depends on WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + string "Default certificate bundle alternate path and name" + default "./certs/x509_crt_bundle_wolfssl" + help + Name of the default certificate bundle directory. Typically used only with PlatformIO. + Reminder PlatformIO cannot generate a bundle from cmake python script call. Relative + paths are with respect to root of this project. + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL default n bool "Add custom certificates to the default bundle" + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH depends on WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL string "Custom certificate bundle path" @@ -430,6 +448,12 @@ menu "wolfSSL" help Enable debugging messages for wolfSSL. See user_settings.h for additional debug options. + config ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING + bool "Suppress build-time warnings for main stack size" + default n + help + Useful only when wolfSSL is running in main task. See FreeRTOS stack size for custom tasks. + config ESP_WOLFSSL_TEST_LOOP bool "Run test apps in a loop until failure" default y diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/include/user_settings.h b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/include/user_settings.h index 488182ed6..80f89fffe 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/include/user_settings.h +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/include/user_settings.h @@ -853,13 +853,18 @@ #ifndef NO_RSA #define ESP32_USE_RSA_PRIMITIVE - #if defined(CONFIG_IDF_TARGET_ESP32) - #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + /* See idf.py menuconfig for stack warning settings */ + #if !defined(CONFIG_ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING) #if CONFIG_ESP_MAIN_TASK_STACK_SIZE < 10500 - #warning "RSA may be difficult with less than 10KB Stack "/ + #warning "RSA may be difficult with less than 10KB Stack" #endif + #else + /* Implement your own stack warning here */ #endif + #endif + #if defined(CONFIG_IDF_TARGET_ESP32) /* NOTE HW unreliable for small values! */ /* threshold for performance adjustment for HW primitive use */ /* X bits of G^X mod P greater than */ diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt index cc7ef0d47..b4a2b74c1 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt @@ -19,23 +19,62 @@ # # cmake for wolfssl Espressif projects # -# Version 5.7.2 Espressif ESP-IDF integration +# Version 5.8.0 Espressif ESP-IDF + PlatformIO integration (2) # # See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html # message(STATUS "Begin wolfssl ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") cmake_minimum_required(VERSION 3.16) +# The scope of this CMAKE_C_FLAGS is just this component: +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWOLFSSL_USER_SETTINGS") + +set(CMAKE_CURRENT_SOURCE_DIR ".") + +# Optionally set your source to wolfSSL in your project CMakeLists.txt like this: +# set(WOLFSSL_ROOT "c:/workspace/my_wolfssl" ) + +if ( "${WOLFSSL_ROOT}" STREQUAL "") + set(WOLFSSL_ROOT "$ENV{WOLFSSL_ROOT}" ) +endif() + set(VERBOSE_COMPONENT_MESSAGES 1) # Optional requires include: # set(THIS_ESP_TLS "esp-tls") set(THIS_ESP_TLS "") +# LIBWOLFSSL_CMAKE_OUTPUT can be printed at runtime +set(LIBWOLFSSL_CMAKE_OUTPUT "") + + +if(CMAKE_BUILD_EARLY_EXPANSION) + message(STATUS "Skipping libwolfssl_output.h update during CMAKE_BUILD_EARLY_EXPANSION") +else() + # Initialize a new libwolfssl_output.h in the cmake build directory. + if( EXISTS "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + # The next WRITE replaces a file. + # This is here to remove any ambiguity on file removal & generation. + file(REMOVE "${CMAKE_BINARY_DIR}/libwolfssl_output.h") + endif() + + file(WRITE "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "/* libwolfssl_output.h generated by wolfssl component */\n" + "#ifndef _LIBWOLFSSL_OUTPUT_H_\n" + "\n" + "#define _LIBWOLFSSL_OUTPUT_H_\n\n") +endif() + +# Append messages with: +# LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n"message" "0") +# See function: APPEND_LIBWOLFSSL_CMAKE_OUTPUT + # function: IS_ESP_IDF_COMPONENT # output: RESULT = 1 (true) if this component is located in the ESP-IDF components # otherwise 0 (false) -function( IS_ESP_IDF_COMPONENT RESULT ) +function( IS_ESP_IDF_COMPONENT + RESULT) # NOTE: Component location is based on the location of the CMakeList.txt # and *not* the location of the wolfSSL source code. (which may be anywhere) @@ -55,6 +94,96 @@ function( IS_ESP_IDF_COMPONENT RESULT ) endif() endfunction() +# +# LIBWOLFSSL_SAVE_INFO(VAR_OUTPUT THIS_VAR VAR_RESULT) +# +# Save the THIS_VAR as a string in a macro called VAR_OUTPUT +# +# VAR_OUTPUT: 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_OUTPUT 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_OUTPUT + if(${IS_VALID_VALUE}) + + if(0) + # Optional debug + message(STATUS "Looking for LF in ${THIS_VAR}") + endif() + + # Check if the text to print in THIS_VAR is multi-line + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + list(LENGTH LINES LINE_COUNT) + + # Save var to "libwolfssl_output.h" header if multi-line, otherwise a simple compile def + if(LINE_COUNT GREATER 1) + message(STATUS "Setting HAVE_LIBWOLFSSL_OUTPUT_HEADER=1 for ${VAR_OUTPUT}") + add_compile_definitions(HAVE_LIBWOLFSSL_OUTPUT_HEADER=1) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#undef ${VAR_OUTPUT}\n") + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "#define ${VAR_OUTPUT} \\\n") + + # Split into lines + string(REPLACE "\n" ";" LINES "${THIS_VAR}") + foreach(LINE IN LISTS LINES) + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\"${LINE}\\n\" \\\n") + endforeach() + + # Final empty line to close the macro + file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" "\n") + + message(STATUS "COMPONENT_LIB=${COMPONENT_LIB}") + target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_BINARY_DIR}") + else() + message(STATUS "No HAS_LIBWOLFSSL_OUTPUT_HEADER") + # We should not have any, but just to be sure: + # 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_OUTPUT} ${VAR_VALUE} PARENT_SCOPE) + + # but we're only using it here in this function + set(${VAR_OUTPUT} ${VAR_VALUE}) + + # we'll print what we found to the console + message(STATUS "Found ${VAR_OUTPUT}=${VAR_VALUE}") + + # the interesting part is defining the VAR_OUTPUT name a value to use in the app + add_compile_definitions(${VAR_OUTPUT}=\"${VAR_VALUE}\") + + endif() + 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_OUTPUT} "Unknown") + endif() + + +endfunction() # LIBWOLFSSL_SAVE_INFO + +# +# APPEND_LIBWOLFSSL_CMAKE_OUTPUT(THIS_MESSAGE OUTPUT_VALUE) +# +# Append the text in THIS_MESSAGE to LIBWOLFSSL_CMAKE_OUTPUT. +# String is available at runtime in app +# + +function( APPEND_LIBWOLFSSL_CMAKE_OUTPUT + THIS_MESSAGE ) + # Normally, we'd simply print a message: + message(STATUS "${THIS_MESSAGE}") + + # But here we'll pass the entire LIBWOLFSSL_CMAKE_OUTPUT as a string definition to the app + set(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}\n${THIS_MESSAGE}" PARENT_SCOPE) + + # We don't call LIBWOLFSSL_SAVE_INFO here as it would add duplicate definitions + # See single instance at the end of this file. +endfunction() + # Determine if this cmake file is located in the ESP-IDF component directory or not, # and if so, if it is being ignored (allowing the use of a local project one, instead). IS_ESP_IDF_COMPONENT( IS_WOLSSL_ESP_IDF_COMPONENT ) @@ -77,20 +206,6 @@ else() message(STATUS "Cleaned wolfssl path: ${CONFIG_CUSTOM_SETTING_WOLFSSL_ROOT}") endif() -# The scope of this CMAKE_C_FLAGS is just this component: -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_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() - if( "$ENV{IDF_PATH}" STREQUAL "" ) message(FATAL_ERROR "IDF_PATH Environment variable not set!") else() @@ -185,7 +300,9 @@ endif() # Check environment variable name EVARPARAM as [name] # If defined, and has a value of EVARVALUE as [value], # then assign a compiler definition "-D[name]=[value]" -function(ENVIRONMENT_VAR_TO_MACRO EVARPARAM EVARVALUE) +function( ENVIRONMENT_VAR_TO_MACRO + EVARPARAM # Environment variable parameter name + EVARVALUE) # Environment variable value # If the EVARPARAM environment variable name is set to EVARVALUE, # set the compiler flag definition to enable CSV output. if ( "$ENV{${EVARPARAM}}" STREQUAL "${EVARVALUE}") @@ -217,7 +334,8 @@ endfunction() # 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 +function( IS_WOLFSSL_SOURCE + DIRECTORY_PARAMETER RESULT ) if (EXISTS "${DIRECTORY_PARAMETER}/wolfcrypt/src") set(${RESULT} "${DIRECTORY_PARAMETER}" PARENT_SCOPE) @@ -233,7 +351,8 @@ endfunction() # Example usage: # FIND_WOLFSSL_DIRECTORY(WOLFSSL_ROOT) # ********************************************************************************************* -function(FIND_WOLFSSL_DIRECTORY OUTPUT_FOUND_WOLFSSL_DIRECTORY) +function( FIND_WOLFSSL_DIRECTORY + OUTPUT_FOUND_WOLFSSL_DIRECTORY) message(STATUS "Starting FIND_WOLFSSL_DIRECTORY: ${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}") if ( "${${OUTPUT_FOUND_WOLFSSL_DIRECTORY}}" STREQUAL "" ) @@ -673,9 +792,9 @@ else() # 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") - if(WOLFSSL_ROOT) - string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) - endif() + if(WOLFSSL_ROOT) + string(REPLACE "\\" "/" WOLFSSL_ROOT ${WOLFSSL_ROOT}) + endif() if(IS_DIRECTORY "${RTOS_IDF_PATH}") message(STATUS "Found current RTOS path: ${RTOS_IDF_PATH}") @@ -789,16 +908,35 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE AND NOT CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE AND NOT ("${CONFIG_TARGET_PLATFORM}" STREQUAL "esp8266") ) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("wolfSSL Certificate Bundles Enabled") + if (CMAKE_BUILD_EARLY_EXPANSION) - message(ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") + message(FATAL_ERROR "Bundle Cert initialization must occur during CMAKE_BUILD_EARLY_EXPANSION") endif() # reminder: we need a value for wolfSSL root first! if( "${WOLFSSL_ROOT}" STREQUAL "" ) - message(ERROR "Certificate bundles need a value for WOLFSSL_ROOT") + message(FATAL_ERROR "Certificate bundles need a value for WOLFSSL_ROOT") endif() + + # Cert bundle in wolfSSL source unless otherwise specified later set(WOLFSSL_ESP_CRT_BUNDLE_DIR ${WOLFSSL_ROOT}/wolfcrypt/src/port/Espressif/esp_crt_bundle) message(STATUS "WOLFSSL_ESP_CRT_BUNDLE_DIR=${WOLFSSL_ESP_CRT_BUNDLE_DIR}") - if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + + if(DEFINED ENV{PLATFORMIO_PROJECT_DIR}) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO") + set(IS_PLATFORMIO 1) + else() + # Some environments may not have environment variable, so double check if we are in .pio + if("${CMAKE_BINARY_DIR}" MATCHES "/\\.pio/") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Detected PlatformIO via CMAKE_BINARY_DIR") + set(IS_PLATFORMIO 1) + else() + set(IS_PLATFORMIO 0) + endif() + endif() + + if(EXISTS "${WOLFSSL_ESP_CRT_BUNDLE_DIR}" OR IS_PLATFORMIO) + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Special processing for wolfSSL Certificate Bundles") set(bundle_name "x509_crt_bundle_wolfssl") # For now the certs are in the same directory @@ -824,9 +962,9 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE get_filename_component(custom_bundle_path ${CONFIG_WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}") list(APPEND crt_paths ${custom_bundle_path}) - message(STATUS "Using a custom wolfSSL bundle path: ${custom_bundle_path}") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Using a custom wolfSSL bundle path: ${custom_bundle_path}") else() - message(STATUS "Not using a custom wolfSSL bundle path.") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Not using a custom wolfSSL bundle path") endif() list(APPEND args --input ${crt_paths} -q) @@ -843,25 +981,107 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE message(STATUS "args ${args}") message(STATUS "cert_bundle ${cert_bundle}") - # Generate bundle according to config - # File is generated at build time, not cmake load - add_custom_command(OUTPUT ${crt_bundle} - COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} - DEPENDS ${custom_bundle_path} - VERBATIM) + if (IS_PLATFORMIO) + # PlatformIO cannot generate a Certificate Bundle at build time + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("PlatformIO is using a predefined bundle rather than generating one") - if(EXISTS "${crt_bundle}") - message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + if ( "${WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "" OR "$(WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE)" STREQUAL "n") + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Alternate Certificate Bundle Path and Name not enabled, assuming [project]/certs/x509_crt_bundle_wolfssl") + # Reminder this CMakeLists.txt should be in [project]/components/wolfssl, so ./certs is two directories up + set(crt_bundle_option "../../certs/x509_crt_bundle_wolfssl") + else() + string(SUBSTRING "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}" 0 2 CERT_PATH_FIRST_TWO) + if(CERT_PATH_FIRST_TWO STREQUAL "./" OR CERT_PATH_FIRST_TWO STREQUAL ".\\") + set(IS_CERT_BUNDLE_RELATIVE_PATH 1) + message(STATUS "Alternate Cert Path is relative to project.") + else() + set(IS_CERT_BUNDLE_RELATIVE_PATH 0) + message(STATUS "Alternate Cert Path is not relative to project.") + endif() + + # The cert bundle is not a standard cert, so we con't add to the crt_paths. + # Still, we may have an alternate location, particulatly needed for PlatformIO: + if(IS_CERT_BUNDLE_RELATIVE_PATH) + message(STATUS "CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME = ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Relative alternate_bundle_path: ${alternate_bundle_path}") + + SET(crt_bundle_option "${CMAKE_SOURCE_DIR}/${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + else() + message(STATUS "alternate_bundle_path: ${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + message(STATUS "Not using an alternate wolfSSL bundle file.") + SET(crt_bundle_option "${CONFIG_WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME}") + endif() + endif() + + # Clean the path, removing any extra "./" etc. + # Number of spaces in message strings is to align path value outputs + message(STATUS "This crt_bundle_option value: ${crt_bundle_option}") + if(${CMAKE_VERSION} VERSION_LESS "3.19") + message("WARNING: CMake version is ${CMAKE_VERSION} ? file(REAL_PATH ...) is not supported. Falling back to manual path normalization.") + # optional fallback logic here + get_filename_component(crt_bundle_file_component "${crt_bundle_option}" ABSOLUTE) + message(STATUS "Interim crt_bundle_file_component: ${crt_bundle_file_component}") + file(TO_CMAKE_PATH "${crt_bundle_file_component}" crt_bundle) + message(STATUS "TO_CMAKE_PATH crt_bundle result: ${crt_bundle}") + # set(crt_bundle "C:/workspace/pio_wolfssl-upstream-test-wolfssl_cert_bundle/esp32-c6/certs/x509_crt_bundle_wolfssl") + else() + file(REAL_PATH "${crt_bundle_option}" crt_bundle) + endif() + + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Certificate Bundle: ${crt_bundle}") + message(STATUS "This cleaned crt_bundle value: ${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + message(STATUS "Reminder: platformio.ini will need this value set for board_build.embed_files =") + message(STATUS "${crt_bundle}") + message(STATUS "=============================================================================================================") + message(STATUS "=============================================================================================================") + + # e.g. SET(crt_bundle "C:/workspace/pio_wolfssl/esp32-c6/certs/x509_crt_bundle_wolfssl") + # + + # Normally x509_crt_bundle_wolfssl built by python script called from cmake. + # See https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/src/port/Espressif/esp_crt_bundle/gen_crt_bundle.py + # Reminder ESP-IDF scripts are NOT called from CMake for PlatformIO builds. + # + # The easiest way to generate the default file is to build with ESP-IDF and copy the files to [project]/main + # + # for example: + # build\VisualGDB\Debug\x509_crt_bundle_wolfssl.s + # build\VisualGDB\Debug\esp-idf\wolfssl\x509_crt_bundle_wolfssl + # + message(STATUS "Confirming cert bundle exists...") + if(EXISTS "${crt_bundle}") + # Number of spaces is to align path value outputs + message(STATUS "Bundle file found for PlatformIO: ${crt_bundle}") + else() + APPEND_LIBWOLFSSL_CMAKE_OUTPUT("ERROR: Failed to find bundle file found for PlatformIO: ${crt_bundle}") + message(STATUS "Check for entry in platformio.ini: board_build.embed_files = certs/x509_crt_bundle_wolfssl ") + message(FATAL_ERROR "WOLFSSL_CERTIFICATE_BUNDLE is enabled for PlatformIO, but predefined file not found: ${crt_bundle}") + endif() else() - message(STATUS "Bundle file expected during next build: ${crt_bundle}") + # APPEND_LIBWOLFSSL_CMAKE_OUTPUT("Generate bundle: ${GENERATE_CERT_BUNDLEPY} ${args}") + # Not PlatformIO + # Generate bundle according to config + # File is generated at build time, not cmake load + add_custom_command(OUTPUT ${crt_bundle} + COMMAND ${GENERATE_CERT_BUNDLEPY} ARGS ${args} + DEPENDS ${custom_bundle_path} + VERBATIM) + + if(EXISTS "${crt_bundle}") + message(STATUS "Bundle file exists from prior build: ${crt_bundle}") + else() + message(STATUS "Bundle file expected during next build: ${crt_bundle}") + endif() + + # Reminder the file is generated at build time, not cmake load time. + message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") endif() - # Reminder the file is generated at build time, not cmake load time. - message(STATUS "wolfSSL Cert Bundle File to be created at build time in: ${crt_bundle}") + add_custom_target(custom_wolfssl_bundle DEPENDS ${crt_bundle}) - add_custom_target(custom_wolfssl_bundle DEPENDS ${cert_bundle}) - - # the wolfSSL crtificate bundle is baked into wolfSSL + # the wolfSSL certificate bundle is baked into wolfSSL add_dependencies(${COMPONENT_LIB} custom_wolfssl_bundle) # COMPONENT_LIB may vary: __idf_wolfssl, __idf_esp_wolfssl, etc @@ -871,7 +1091,12 @@ if( CONFIG_WOLFSSL_CERTIFICATE_BUNDLE APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${crt_bundle}") else() - message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + if(IS_PLATFORMIO) + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but cannot be generated in PlatformmIO") + else() + message(STATUS "WARNING: CONFIG_WOLFSSL_CERTIFICATE_BUNDLE enabled but directory not found: ${WOLFSSL_ESP_CRT_BUNDLE_DIR}") + endif() + message(FATAL_ERROR "not detected") endif() endif() @@ -930,42 +1155,6 @@ 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_compile_definitions(${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 - execute_process( COMMAND ${git_cmd} "rev-parse" "--is-inside-work-tree" OUTPUT_VARIABLE IS_GIT_REPO @@ -1049,6 +1238,14 @@ else() message(STATUS "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") endif() +# A single instance of potentially multiple cmake messages to send to app: +message(STATUS "LIBWOLFSSL_CMAKE_OUTPUT: ${LIBWOLFSSL_CMAKE_OUTPUT}") +LIBWOLFSSL_SAVE_INFO(LIBWOLFSSL_CMAKE_OUTPUT "${LIBWOLFSSL_CMAKE_OUTPUT}" "0") + +file(APPEND "${CMAKE_BINARY_DIR}/libwolfssl_output.h" + "\n" + "#endif\n" ) + message(STATUS "************************************************************************************************") message(STATUS "wolfSSL component config complete!") message(STATUS "************************************************************************************************") diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/Kconfig b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/Kconfig index 9a7fcaa07..ee8dc7f1a 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/Kconfig +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/Kconfig @@ -274,10 +274,28 @@ menu "wolfSSL" bool "Do not use the default certificate bundle" endchoice + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE + depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + default n + bool "Use alternate certificate bundle" + help + Typically only used for PlatformIO which cannot generate a certificate bundle at build time. + Enable this option to specify a fixed wolfSSL certificate file path and file name. + + config WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE_PATH_AND_NAME + depends on WOLFSSL_ALTERNATE_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL + string "Default certificate bundle alternate path and name" + default "./certs/x509_crt_bundle_wolfssl" + help + Name of the default certificate bundle directory. Typically used only with PlatformIO. + Reminder PlatformIO cannot generate a bundle from cmake python script call. Relative + paths are with respect to root of this project. + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE depends on WOLFSSL_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL default n bool "Add custom certificates to the default bundle" + config WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE_PATH depends on WOLFSSL_CUSTOM_CERTIFICATE_BUNDLE && ESP_TLS_USING_WOLFSSL string "Custom certificate bundle path" @@ -430,6 +448,12 @@ menu "wolfSSL" help Enable debugging messages for wolfSSL. See user_settings.h for additional debug options. + config ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING + bool "Suppress build-time warnings for main stack size" + default n + help + Useful only when wolfSSL is running in main task. See FreeRTOS stack size for custom tasks. + config ESP_WOLFSSL_TEST_LOOP bool "Run test apps in a loop until failure" default y diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/include/user_settings.h b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/include/user_settings.h index 488182ed6..80f89fffe 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/include/user_settings.h +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/include/user_settings.h @@ -853,13 +853,18 @@ #ifndef NO_RSA #define ESP32_USE_RSA_PRIMITIVE - #if defined(CONFIG_IDF_TARGET_ESP32) - #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + #ifdef CONFIG_ESP_MAIN_TASK_STACK_SIZE + /* See idf.py menuconfig for stack warning settings */ + #if !defined(CONFIG_ESP_WOLFSSL_NO_STACK_SIZE_BUILD_WARNING) #if CONFIG_ESP_MAIN_TASK_STACK_SIZE < 10500 - #warning "RSA may be difficult with less than 10KB Stack "/ + #warning "RSA may be difficult with less than 10KB Stack" #endif + #else + /* Implement your own stack warning here */ #endif + #endif + #if defined(CONFIG_IDF_TARGET_ESP32) /* NOTE HW unreliable for small values! */ /* threshold for performance adjustment for HW primitive use */ /* X bits of G^X mod P greater than */ diff --git a/examples/configs/user_settings_platformio.h b/examples/configs/user_settings_platformio.h index 4fd753bce..f1ee655b2 100644 --- a/examples/configs/user_settings_platformio.h +++ b/examples/configs/user_settings_platformio.h @@ -18,8 +18,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#define WOLFSSL_ESPIDF_COMPONENT_VERSION 0x01 /* This is a sample PlatformIO user_settings.h for wolfSSL +/* Examples such as test and benchmark are known to cause watchdog timeouts. + * Note this is often set in project Makefile: + * CFLAGS += -DWOLFSSL_ESP_NO_WATCHDOG=1 */ +#define WOLFSSL_ESP_NO_WATCHDOG 1 + +/* The Espressif project config file. See also sdkconfig.defaults */ +#include "sdkconfig.h" * * Do not include any wolfssl headers here * @@ -47,10 +55,9 @@ /* We don't use WiFi, so don't compile in the esp-sdk-lib WiFi helpers: */ /* #define USE_WOLFSSL_ESP_SDK_WIFI */ -/* Experimental Kyber */ +/* Optional MLKEM (Kyber Post Quantum) */ #if 0 /* Kyber typically needs a minimum 10K stack */ - #define WOLFSSL_EXPERIMENTAL_SETTINGS #define WOLFSSL_HAVE_MLKEM #define WOLFSSL_WC_MLKEM #define WOLFSSL_SHA3 @@ -566,18 +573,33 @@ /* Debug options: See wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h for details on debug options +optionally increase error message size for very long paths. +#define WOLFSSL_MAX_ERROR_SZ 500 + +Turn wolfSSL debugging on/off: + wolfSSL_Debugging_ON(); + wolfSSL_Debugging_OFF(); + #define ESP_VERIFY_MEMBLOCK #define DEBUG_WOLFSSL #define DEBUG_WOLFSSL_VERBOSE #define DEBUG_WOLFSSL_SHA_MUTEX +#define WOLFSSL_DEBUG_IGNORE_ASN_TIME +#define WOLFSSL_DEBUG_CERT_BUNDLE +#define WOLFSSL_DEBUG_CERT_BUNDLE_NAME #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_MUTEX #define WOLFSSL_DEBUG_ESP_RSA_MULM_BITS +#define WOLFSSL_DEBUG_ESP_HW_MOD_RSAMAX_BITS +#define WOLFSSL_DEBUG_ESP_HW_MULTI_RSAMAX_BITS #define ESP_DISABLE_HW_TASK_LOCK +#define ESP_MONITOR_HW_TASK_LOCK +#define USE_ESP_DPORT_ACCESS_READ_BUFFER See wolfcrypt/benchmark/benchmark.c for debug and other settings: @@ -594,7 +616,7 @@ Turn on timer debugging (used when CPU cycles not available) #define WOLFSSL_HW_METRICS #define ALT_ECC_SIZE -/* for test.c: */ +/* for test.c */ /* #define HASH_SIZE_LIMIT */ /* Optionally turn off HW math checks */ @@ -641,6 +663,12 @@ Turn on timer debugging (used when CPU cycles not available) * There are various certificate examples in this header file: * https://github.com/wolfSSL/wolfssl/blob/master/wolfssl/certs_test.h * + * To use the sample certificates in code (not recommended for production!): + * + * #if defined(USE_CERT_BUFFERS_2048) || defined(USE_CERT_BUFFERS_1024) + * #include + * #endif + * * To use the sets of macros below, define *one* of these: * * USE_CERT_BUFFERS_1024 - ECC 1024 bit encoded ASN1 @@ -655,10 +683,10 @@ Turn on timer debugging (used when CPU cycles not available) * CTX_CA_CERT_SIZE, * CTX_CA_CERT_TYPE); * - * See www.wolfssl.com/documentation/manuals/wolfssl/group__CertsKeys.html#function-wolfssl_ctx_load_verify_buffer + * 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: github.com/wolfSSL/wolfssl/blob/master/wolfssl/certs_test.h + * 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. @@ -670,7 +698,7 @@ Turn on timer debugging (used when CPU cycles not available) * CTX_CLIENT_KEY_SIZE, * CTX_CLIENT_KEY_TYPE); * - * see www.wolfssl.com/documentation/manuals/wolfssl/group__CertsKeys.html#function-wolfssl_ctx_use_privatekey_buffer + * 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. @@ -680,17 +708,17 @@ Turn on timer debugging (used when CPU cycles not available) * are the known wolfSSL encoding type integers (e.g. WOLFSSL_FILETYPE_PEM). * * See `SSL_FILETYPE_[name]` in - * github.com/wolfSSL/wolfssl/blob/master/wolfssl/ssl.h + * https://github.com/wolfSSL/wolfssl/blob/master/wolfssl/ssl.h * * See Abstract Syntax Notation One (ASN.1) in: - * github.com/wolfSSL/wolfssl/blob/master/wolfssl/wolfcrypt/asn.h + * 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: - * github.com/wolfSSL/wolfssl/pull/6825 - * github.com/wolfSSL/wolfsm + * 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. */ @@ -703,6 +731,7 @@ Turn on timer debugging (used when CPU cycles not available) /* 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 @@ -720,7 +749,11 @@ Turn on timer debugging (used when CPU cycles not available) #ifdef USE_CERT_BUFFERS_1024 #error "USE_CERT_BUFFERS_1024 is already defined. Pick one." #endif + + /* Be sure to include in app when using example certs: */ #include + + #define USE_CERT_BUFFERS_256 #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 @@ -743,6 +776,11 @@ Turn on timer debugging (used when CPU cycles not available) #ifdef USE_CERT_BUFFERS_2048 #error "USE_CERT_BUFFERS_2048 is already defined. Pick one." #endif + + /* Be sure to include in app when using example certs: */ + #include + + #define USE_CERT_BUFFERS_256 #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 @@ -788,3 +826,11 @@ Turn on timer debugging (used when CPU cycles not available) #else #warning "CONFIG_ESP_MAIN_TASK_STACK_SIZE not defined!" #endif +/* See settings.h for some of the possible hardening options: + * + * #define NO_ESPIDF_DEFAULT + * #define WC_NO_CACHE_RESISTANT + * #define WC_AES_BITSLICED + * #define HAVE_AES_ECB + * #define HAVE_AES_DIRECT + */ diff --git a/src/ssl.c b/src/ssl.c index 1607c4f85..bb1d1176c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6155,6 +6155,12 @@ int wolfSSL_Init(void) WOLFSSL_ENTER("wolfSSL_Init"); +#if defined(LIBWOLFSSL_CMAKE_OUTPUT) + WOLFSSL_MSG(LIBWOLFSSL_CMAKE_OUTPUT); +#else + WOLFSSL_MSG("No extra wolfSSL cmake messages found"); +#endif + #ifndef WOLFSSL_MUTEX_INITIALIZER if (inits_count_mutex_valid == 0) { #if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 872dffd0f..151245120 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -130,6 +130,7 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/Espressif/esp_crt_bundle/cacrt_deprecated.pem \ wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c \ wolfcrypt/src/port/Espressif/esp_crt_bundle/gen_crt_bundle.py \ + wolfcrypt/src/port/Espressif/esp_crt_bundle/pio_install_cryptography.py \ wolfcrypt/src/port/Espressif/esp_crt_bundle/cacrt_local.pem \ wolfcrypt/src/port/Espressif/README.md \ wolfcrypt/src/port/arm/cryptoCell.c \ diff --git a/wolfcrypt/src/port/Espressif/esp32_util.c b/wolfcrypt/src/port/Espressif/esp32_util.c index 90b3cdcc8..b8b387c02 100644 --- a/wolfcrypt/src/port/Espressif/esp32_util.c +++ b/wolfcrypt/src/port/Espressif/esp32_util.c @@ -31,6 +31,11 @@ #include "sdkconfig.h" /* programmatically generated from sdkconfig */ #include +#if HAVE_LIBWOLFSSL_OUTPUT_HEADER + /* see wolfssl component CMakeLists.txt that may have generated this: */ + #include "libwolfssl_output.h" +#endif + /* Espressif */ #include #include @@ -647,6 +652,16 @@ int ShowExtendedSystemInfo(void) LIBWOLFSSL_VERSION_HEX); #endif +#if defined(LIBWOLFSSL_CMAKE_OUTPUT) + /* For some environments such as PlatformIO that may hide CMake output, + * we can have important messages propagated to the app: */ + ESP_LOGI(TAG, "----------------------------------------------------------"); + ESP_LOGI(TAG, "LIBWOLFSSL_CMAKE_OUTPUT:%s", LIBWOLFSSL_CMAKE_OUTPUT); + ESP_LOGI(TAG, "----------------------------------------------------------"); +#else + ESP_LOGW(TAG, "LIBWOLFSSL_CMAKE_OUTPUT: No cmake messages detected"); +#endif + /* some interesting settings are target specific (ESP32, -C3, -S3, etc */ #if defined(CONFIG_IDF_TARGET_ESP32) /* ESP_RSA_MULM_BITS should be set to at least 16 for ESP32 */ diff --git a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c index 6e7b625c4..8a836b664 100644 --- a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c +++ b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c @@ -31,6 +31,13 @@ /* Reminder: settings.h pulls in user_settings.h */ /* Do not explicitly include user_settings.h here. */ #include +#include +#include + +#ifndef SHOW_WOLFSSL_BUNDLE_ERROR + #define SHOW_WOLFSSL_BUNDLE_ERROR(X) ESP_LOGV(TAG, \ + "SHOW_WOLFSSL_BUNDLE_ERROR not enabled, details suppressed."); +#endif /* Espressif */ #include @@ -91,6 +98,8 @@ esp_err_t esp_crt_bundle_attach(void *conf) /* Bundle debug may come from user_settings.h and/or sdkconfig.h */ #if defined(CONFIG_WOLFSSL_DEBUG_CERT_BUNDLE) || \ defined( WOLFSSL_DEBUG_CERT_BUNDLE) + /* someplace to store result of wc_ErrorString(err, string) */ + char last_esp_crt_bundle_error[WOLFSSL_MAX_ERROR_SZ]; /* We'll only locally check this one: */ #undef WOLFSSL_DEBUG_CERT_BUNDLE #define WOLFSSL_DEBUG_CERT_BUNDLE @@ -173,12 +182,16 @@ esp_err_t esp_crt_bundle_attach(void *conf) /* A "Certificate Bundle" is this array of [size] + [x509 CA List] * certs that the client trusts: */ -extern const uint8_t x509_crt_imported_bundle_wolfssl_bin_start[] - asm("_binary_x509_crt_bundle_wolfssl_start"); - -extern const uint8_t x509_crt_imported_bundle_wolfssl_bin_end[] - asm("_binary_x509_crt_bundle_wolfssl_end"); +#if !defined(NO_WOLFSSL_USE_ASM_CERT) + extern const uint8_t x509_crt_imported_bundle_wolfssl_bin_start[] + asm("_binary_x509_crt_bundle_wolfssl_start"); + extern const uint8_t x509_crt_imported_bundle_wolfssl_bin_end[] + asm("_binary_x509_crt_bundle_wolfssl_end"); +#else + extern const unsigned char _binary_x509_crt_bundle_wolfssl_start[]; + extern const unsigned char _binary_x509_crt_bundle_wolfssl_end[]; +#endif /* This crt_bundle_t type must match other providers in esp-tls from ESP-IDF. * TODO: Move to common header in ESP-IDF. (requires ESP-IDF modification). * For now, it is here: */ @@ -453,7 +466,8 @@ static CB_INLINE int cert_manager_load(int preverify, } } else { - ESP_LOGE(TAG, "Failed to load CA"); + ESP_LOGE(TAG, "Failed to load CA, ret = %d", ret); + SHOW_WOLFSSL_BUNDLE_ERROR(ret); } /* We don't free the issue and subject, as they are @@ -861,6 +875,7 @@ static CB_INLINE int wolfssl_ssl_conf_verify_cb_no_signer(int preverify, if (ret == WOLFSSL_FAILURE) { ESP_LOGW(TAG, "Warning: found a matching cert, but not added " "to the Certificate Manager. error: %d", ret); + SHOW_WOLFSSL_BUNDLE_ERROR(ret); } else { ESP_LOGCBI(TAG, "New CA added to the Certificate Manager."); @@ -1338,15 +1353,15 @@ static esp_err_t wolfssl_esp_crt_bundle_init(const uint8_t *x509_bundle, /* If all is ok, proceed with initialization of Certificate Bundle */ if (ret == ESP_OK) { - /* This is the maximum region that is allowed to access */ - ESP_LOGV(TAG, "Bundle Start 0x%x", (intptr_t)x509_bundle); - ESP_LOGV(TAG, "Bundle Size %d", bundle_size); bundle_end = x509_bundle + bundle_size; - ESP_LOGV(TAG, "Bundle End 0x%x", (intptr_t)bundle_end); + /* This is the maximum region that is allowed to access */ + ESP_LOGCBI(TAG, "Bundle Start 0x%x", (intptr_t)x509_bundle); + ESP_LOGCBI(TAG, "Bundle End 0x%x", (intptr_t)bundle_end); + ESP_LOGCBI(TAG, "Bundle Size %u bytes", bundle_size); cur_crt = x509_bundle + BUNDLE_HEADER_OFFSET; for (i = 0; i < num_certs; i++) { - ESP_LOGV(TAG, "Init Cert %d", i); + ESP_LOGCBI(TAG, "Init Cert %d", i); if (cur_crt + CRT_HEADER_OFFSET > bundle_end) { ESP_LOGE(TAG, "Invalid certificate bundle current offset"); _esp_crt_bundle_is_valid = ESP_FAIL; @@ -1357,24 +1372,46 @@ static esp_err_t wolfssl_esp_crt_bundle_init(const uint8_t *x509_bundle, crts[i] = cur_crt; #ifndef IS_WOLFSSL_CERT_BUNDLE_FORMAT + ESP_LOGE("err", "Error: not IS_WOLFSSL_CERT_BUNDLE_FORMAT"); /* For reference only */ size_t name_len = cur_crt[0] << 8 | cur_crt[1]; size_t key_len = cur_crt[2] << 8 | cur_crt[3]; cur_crt = cur_crt + CRT_HEADER_OFFSET + name_len + key_len; #else cert_len = cur_crt[0] << 8 | cur_crt[1]; - #if defined(CONFIG_WOLFSSL_ASN_ALLOW_0_SERIAL) || \ + ESP_LOGCBI(TAG, "- This certificate at 0x%x, length: %u", + (intptr_t)cur_crt, cert_len); + + /* TODO: optional gate out serial check for performance. */ + /* Useful only for custom cert bundle, known to have no zeros. */ + if (wolfssl_is_zero_serial_number(cur_crt + CRT_HEADER_OFFSET, + cert_len) > 0) { + #if defined(CONFIG_WOLFSSL_ASN_ALLOW_0_SERIAL) || \ defined( WOLFSSL_ASN_ALLOW_0_SERIAL) || \ defined(CONFIG_WOLFSSL_NO_ASN_STRICT) || \ defined( WOLFSSL_NO_ASN_STRICT) - if (wolfssl_is_zero_serial_number(cur_crt + CRT_HEADER_OFFSET, - cert_len) > 0) { ESP_LOGW(TAG, "Warning: found zero value for serial number in " "certificate #%d", i); - ESP_LOGW(TAG, "Enable WOLFSSL_NO_ASN_STRICT to allow zero in " - "serial number."); - } - #endif + #if defined(CONFIG_WOLFSSL_ASN_ALLOW_0_SERIAL) + ESP_LOGCBW(TAG, "Allowing zero serial in certificate config."); + #elif defined( WOLFSSL_ASN_ALLOW_0_SERIAL) + ESP_LOGCBW(TAG, "Allowing zero serial in certificate setting."); + #elif defined(CONFIG_WOLFSSL_NO_ASN_STRICT) + ESP_LOGCBW(TAG, "Allowing zero serial, no ASN Strict config."); + #elif defined( WOLFSSL_NO_ASN_STRICT) + ESP_LOGCBW(TAG, "Allowing zero serial, no ASN Strict setting."); + #else + /* Unless explicitly allowed, wolfSSL will reject zero serial */ + ESP_LOGW(TAG, "Certificate has zero serial number!"); + #endif /* zero serial check message, why allowed per setting */ + #else + /* we don't allow zero serial, expect wolfssl error later */ + ESP_LOGE(TAG, "ERROR: Strict ASN and found zero value for " + "serial number in certificate #%d", i); + #endif /* zero serial check */ + } /* wolfssl_is_zero_serial_number */ + + /* look at next cert */ cur_crt = cur_crt + (CRT_HEADER_OFFSET + cert_len); #endif } /* for certs 0 to num_certs - 1 in the order found */ @@ -1427,25 +1464,52 @@ static esp_err_t wolfssl_esp_crt_bundle_init(const uint8_t *x509_bundle, esp_err_t esp_crt_bundle_attach(void *conf) { esp_err_t ret = ESP_OK; + size_t bundle_size = 0; ESP_LOGCBI(TAG, "Enter esp_crt_bundle_attach"); /* If no bundle has been set by the user, * then use the bundle embedded in the binary */ +#ifdef PLATFORMIO + ESP_LOGCBW(TAG, "Found PLATFORMIO, beware of alternate cert bundles."); +#endif if (s_crt_bundle.crts == NULL) { ESP_LOGCBI(TAG, "No bundle set by user; using the embedded binary."); ESP_LOGCBI(TAG, "x509_crt_imported_bundle_wolfssl_bin_start 0x%x", (intptr_t)x509_crt_imported_bundle_wolfssl_bin_start); - ESP_LOGCBI(TAG, "x509_crt_imported_bundle_wolfssl_bin_end 0x%x", + ESP_LOGCBI(TAG, "x509_crt_imported_bundle_wolfssl_bin_end 0x%x", (intptr_t)x509_crt_imported_bundle_wolfssl_bin_end); - ret = wolfssl_esp_crt_bundle_init( - x509_crt_imported_bundle_wolfssl_bin_start, - (x509_crt_imported_bundle_wolfssl_bin_end - - x509_crt_imported_bundle_wolfssl_bin_start)); + if ((intptr_t)x509_crt_imported_bundle_wolfssl_bin_end < + (intptr_t)x509_crt_imported_bundle_wolfssl_bin_start) { + ESP_LOGE(TAG, "Imported bundle end less than starting address"); + ret = ESP_FAIL; + } + else { + bundle_size = (x509_crt_imported_bundle_wolfssl_bin_end + - x509_crt_imported_bundle_wolfssl_bin_start); + if (bundle_size == 0) { + ESP_LOGE(TAG, "Imported bundle size is zero. Empty?"); + ret = ESP_FAIL; + } + else { + ESP_LOGCBI(TAG, "Importing x509 wolfSSL bundle, %u bytes", + bundle_size); + ret = wolfssl_esp_crt_bundle_init( + x509_crt_imported_bundle_wolfssl_bin_start, + bundle_size); + } + } } else { ESP_LOGCBI(TAG, "Cert bundle set by user at 0x%x.", (intptr_t)s_crt_bundle.crts); } + if (((uintptr_t)x509_crt_imported_bundle_wolfssl_bin_start % 4) == 0) { + ESP_LOGCBI(TAG, "Confirmed alignment x509_crt_imported_bundle_wolfssl"); + } + else { + ESP_LOGCBI(TAG, "Not aligned: x509_crt_imported_bundle_wolfssl"); + } + if (ret == ESP_OK) { if (conf) { wolfssl_ssl_config *ssl_conf = (wolfssl_ssl_config *)conf; diff --git a/wolfcrypt/src/port/Espressif/esp_crt_bundle/pio_install_cryptography.py b/wolfcrypt/src/port/Espressif/esp_crt_bundle/pio_install_cryptography.py new file mode 100644 index 000000000..18571403e --- /dev/null +++ b/wolfcrypt/src/port/Espressif/esp_crt_bundle/pio_install_cryptography.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# +# pio_install_cryptography.py +# +# Copyright (C) 2006-2024 wolfSSL Inc. +# +# This file is part of wolfSSL. +# +# wolfSSL is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfSSL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +# +# Import("env") +import subprocess +import sys + +# Function to install a package +def install(package): + subprocess.check_call([sys.executable, "-m", "pip", "install", package]) + +try: + # Check if cryptography is installed + import cryptography +except ImportError: + # If not installed, install it + print("cryptography package not found. Installing...") + install("cryptography") diff --git a/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h b/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h index cc8f48f23..3b089f3fa 100644 --- a/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h +++ b/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h @@ -90,6 +90,16 @@ extern "C" { #define WOLFSSL_X509_VERIFY_CALLBACK (void *, WOLFSSL_X509 *, int, uint32_t *) #include +#if defined(CONFIG_WOLFSSL_DEBUG_CERT_BUNDLE) || \ + defined( WOLFSSL_DEBUG_CERT_BUNDLE) + /* Default WOLFSSL_MAX_ERROR_SZ assigned in settings.h or user_settings.h */ + extern char last_esp_crt_bundle_error[WOLFSSL_MAX_ERROR_SZ]; + #define SHOW_WOLFSSL_BUNDLE_ERROR(THIS_ERR) \ + { \ + wc_ErrorString(THIS_ERR, last_esp_crt_bundle_error); \ + ESP_LOGE(TAG,"%s", last_esp_crt_bundle_error); \ + } +#endif typedef struct wolfssl_ssl_config wolfssl_ssl_config; struct wolfssl_ssl_config diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 2b2078118..ff5cbe795 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -455,6 +455,10 @@ #endif #endif +/* Important build-time configuration messages may be saved. + * Enable DEBUG_WOLFSSL and see wolfSSL_Init() for display. */ +#define LIBWOLFSSL_CMAKE_OUTPUT "" + /* --------------------------------------------------------------------------- * Dual Algorithm Certificate Required Features. * ---------------------------------------------------------------------------