Skip to content

Commit

Permalink
Work on mbedTLS for ESP32
Browse files Browse the repository at this point in the history
- Add target mbedTLS config file.
- Add platform CMake to include mbedTLS source in network build.
- Add platform implementation of random generator for mbedTLS.
- Rework inclusion of ssl stubs and base64 code because network is build as library in ESP32 and weak functions don't get replaced with hard implementation in this case.
- Remove inclusion of mbedTLS and OpenSSL libraries from ESP32 IDF build.
- Update Azure Pipeline to set security with mbedTLS instead of OpenSSL.

Signed-off-by: José Simões <[email protected]>
  • Loading branch information
josesimoes committed Jul 22, 2019
1 parent de8700f commit 644d913
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 14 deletions.
6 changes: 5 additions & 1 deletion CMake/Modules/FindNF_CoreCLR.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ set(NF_CoreCLR_SRCS

# Helpers
printf.c
base64.c

# HAL
nanoHAL_Time.cpp
Expand All @@ -178,6 +177,11 @@ set(NF_CoreCLR_SRCS
target_BlockStorage.c
)

# need a conditional include because of ESP32 building network as a library
if(NOT USE_SECURITY_MBEDTLS_OPTION)
list(APPEND NF_CoreCLR_SRCS base64.c)
endif()

# include configuration manager file
if(NF_FEATURE_HAS_CONFIG_BLOCK)
# feature enabled, full support
Expand Down
8 changes: 6 additions & 2 deletions CMake/Modules/FindNF_Networking.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ set(NF_Networking_SRCS
LwIP_Sockets.cpp
LwIP_Sockets_functions.cpp

ssl_stubs.cpp
)

# need a conditional include because of ESP32 building network as a library
if(NOT USE_SECURITY_MBEDTLS_OPTION)
list(APPEND NF_Networking_SRCS ssl_stubs.cpp)
endif()

# source files for security layer
set(NF_Networking_Security_SRCS

Expand Down Expand Up @@ -66,7 +70,7 @@ foreach(SRC_FILE ${NF_Networking_SRCS})
${PROJECT_SOURCE_DIR}/src/PAL/COM/sockets/ssl

if(USE_SECURITY_MBEDTLS_OPTION)
# ${PROJECT_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS
${PROJECT_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS
elseif(USE_SECURITY_OPENSSL_OPTION)
${PROJECT_SOURCE_DIR}/src/PAL/COM/sockets/ssl/openssl
endif()
Expand Down
1 change: 1 addition & 0 deletions CMake/Modules/FindmbedTLS.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ endforeach()

# unset this warning as error required for this source file
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_BINARY_DIR}/mbedTLS_Source/library/hmac_drbg.c PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized)
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_BINARY_DIR}/mbedTLS_Source/library/x509_crt.c PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized)

foreach(SRC_FILE ${src_x509})
set(MBEDTLS_SRC_FILE SRC_FILE -NOTFOUND)
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,8 @@ elseif(RTOS_FREERTOS_ESP32_CHECK)
# Define base path for the class libraries
set(BASE_PATH_FOR_CLASS_LIBRARIES_MODULES "${PROJECT_SOURCE_DIR}/targets/FreeRTOS_ESP32/${ESP32_BOARD}/nanoCLR")

add_subdirectory(targets/FreeRTOS_ESP32)

# set target base location
set(TARGET_BASE_LOCATION "${PROJECT_SOURCE_DIR}/targets/FreeRTOS_ESP32/${ESP32_BOARD}")
add_subdirectory(targets/FreeRTOS_ESP32/${ESP32_BOARD})
Expand Down
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ jobs:
matrix:
ESP32_WROOM_32:
BoardName: ESP32_WROOM_32
BuildOptions: -DTARGET_SERIES=ESP32 -DRTOS=FREERTOS_ESP32 -DNF_WP_IMPLEMENTS_CRC32=OFF -DNF_FEATURE_DEBUGGER=ON -DNF_FEATURE_RTC=ON -DNF_FEATURE_HAS_CONFIG_BLOCK=ON -DNF_FEATURE_HAS_SDCARD=ON -DAPI_System.Math=ON -DAPI_Windows.Devices.Gpio=ON -DAPI_Windows.Devices.Spi=ON -DAPI_Windows.Devices.I2c=ON -DAPI_Windows.Devices.Pwm=ON -DAPI_Windows.Devices.SerialCommunication=ON -DAPI_Windows.Devices.Adc=ON -DAPI_System.Net=ON -DAPI_Windows.Devices.Wifi=ON -DAPI_Windows.Storage=ON -DNF_SECURITY_OPENSSL=ON -DAPI_Hardware.Esp32=ON -DSUPPORT_ANY_BASE_CONVERSION=ON -DAPI_nanoFramework.Devices.OneWire=ON
BuildOptions: -DTARGET_SERIES=ESP32 -DRTOS=FREERTOS_ESP32 -DNF_WP_IMPLEMENTS_CRC32=OFF -DNF_FEATURE_DEBUGGER=ON -DNF_FEATURE_RTC=ON -DNF_FEATURE_HAS_CONFIG_BLOCK=ON -DNF_FEATURE_HAS_SDCARD=ON -DAPI_System.Math=ON -DAPI_Windows.Devices.Gpio=ON -DAPI_Windows.Devices.Spi=ON -DAPI_Windows.Devices.I2c=ON -DAPI_Windows.Devices.Pwm=ON -DAPI_Windows.Devices.SerialCommunication=ON -DAPI_Windows.Devices.Adc=ON -DAPI_System.Net=ON -DAPI_Windows.Devices.Wifi=ON -DAPI_Windows.Storage=ON -DNF_SECURITY_MBEDTLS=ON -DAPI_Hardware.Esp32=ON -DSUPPORT_ANY_BASE_CONVERSION=ON -DAPI_nanoFramework.Devices.OneWire=ON

variables:
ESP32_TOOLCHAIN_PATH: $(Agent.TempDirectory)\ESP32_Tools
Expand Down
107 changes: 107 additions & 0 deletions targets/FreeRTOS_ESP32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#
# Copyright (c) 2019 The nanoFramework project contributors
# See LICENSE file in the project root for full license information.
#

# if mbed TLS is enabled add it to the build
if(NF_SECURITY_MBEDTLS)

# check if MBEDTLS_SOURCE was specified or if it's empty (default is empty)
set(NO_MBEDTLS_SOURCE TRUE)

if(MBEDTLS_SOURCE)
if(NOT "${MBEDTLS_SOURCE}" STREQUAL "")
set(NO_MBEDTLS_SOURCE FALSE)
endif()
endif()

# set options for mbed TLS
option(ENABLE_TESTING "no testing when building mbed TLS." OFF)

if(NO_MBEDTLS_SOURCE)
# no mbed TLS source specified, download it from it's repo

# check for Git (needed here for advanced warning to user if it's not installed)
find_package(Git)

# check if Git was found, if not report to user and abort
if(NOT GIT_EXECUTABLE)
message(FATAL_ERROR "error: could not find Git, make sure you have it installed.")
endif()

# set tag for currently supported version
set(MBEDTLS_GIT_TAG "mbedtls-2.14")

# need to setup a separate CMake project to download the code from the GitHub repository
# otherwise it won't be available before the actual build step
configure_file("${PROJECT_SOURCE_DIR}/CMake/mbedTLS.CMakeLists.cmake.in"
"${CMAKE_BINARY_DIR}/mbedTLS_Download/CMakeLists.txt")

# setup CMake project for mbedTLS download
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/mbedTLS_Download")

# run build on mbedTLS download CMake project to perform the download
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/mbedTLS_Download")

# add mbedTLS as external project
ExternalProject_Add(
mbedTLS
PREFIX mbedTLS
SOURCE_DIR ${CMAKE_BINARY_DIR}/mbedTLS_Source
GIT_REPOSITORY https://github.com/nanoframework/mbedtls
GIT_TAG ${MBEDTLS_GIT_TAG} # target specified branch
GIT_SHALLOW 1 # download only the tip of the branch, not the complete history
TIMEOUT 10
LOG_DOWNLOAD 1

# Disable all other steps
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)

else()
# mbedTLS source was specified

# sanity check is source path exists
if(EXISTS "${MBEDTLS_SOURCE}/")

# check if we already have the sources, no need to copy again
if(NOT EXISTS "${CMAKE_BINARY_DIR}/mbedTLS_Source")
message(STATUS "mbedTLS source from: ${MBEDTLS_SOURCE}")
file(COPY "${MBEDTLS_SOURCE}/" DESTINATION "${CMAKE_BINARY_DIR}/mbedTLS_Source")
else()
message(STATUS "Using local cache of mbedTLS source from ${MBEDTLS_SOURCE}")
endif()

set(MBEDTLS_INCLUDE_DIR ${CMAKE_BINARY_DIR}/mbedTLS_Source/include)
else()
message(FATAL_ERROR "Couldn't find mbedTLS source at ${MBEDTLS_SOURCE}/")
endif()

# add mbedTLS as external project
ExternalProject_Add(
mbedTLS
PREFIX mbedTLS
SOURCE_DIR ${CMAKE_BINARY_DIR}/mbedTLS_Source

# Disable all other steps
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)

endif()

# get source dir for mbedTLS CMake project
ExternalProject_Get_Property(mbedTLS SOURCE_DIR)

set(mbedTLS_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/3rdparty/humblelogging/include")
set(mbedTLS_LIBRARIES "${CMAKE_SHARED_LIBRARY_PREFIX}mbedTLS${CMAKE_SHARED_LIBRARY_SUFFIX}")
include_directories(${mbedTLS_INCLUDE_DIRS})

endif()
26 changes: 23 additions & 3 deletions targets/FreeRTOS_ESP32/ESP32_WROOM_32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ else()
set(HAL_USE_RTC_OPTION FALSE CACHE INTERNAL "NF feature RTC")
endif()

# security provider is mbedTLS
if(NF_SECURITY_MBEDTLS)
find_package(mbedTLS REQUIRED)
endif()

#######################################

add_subdirectory("common")
Expand All @@ -57,7 +62,7 @@ add_subdirectory("nanoCLR")
# Build the networking components as a separate library
# This is done this way to stop "Createprocess: file no found" errors in linker when object input file is greater than 32k
if(USE_NETWORKING_OPTION)
add_library(NetworkLib STATIC ${NF_Networking_SOURCES} "${TARGET_ESP32_NETWORK_SOURCES}" "${TARGET_LWIP_SOURCES}" )
add_library(NetworkLib STATIC ${NF_Networking_SOURCES} "${TARGET_ESP32_NETWORK_SOURCES}" "${TARGET_LWIP_SOURCES}" ${mbedTLS_SOURCES} )
endif()


Expand Down Expand Up @@ -129,8 +134,20 @@ foreach( IDF_libraries ${PROJECT_LINK_LIBS} )
endif()
endforeach( IDF_libraries )

# mbed TLS requires a config file
if(NF_SECURITY_MBEDTLS)
# this seems to be only option to properly set a compiler define through the command line that needs to be a string literal
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMBEDTLS_CONFIG_FILE=\"<${PROJECT_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS/nf_mbedtls_config.h>\"")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMBEDTLS_CONFIG_FILE=\"<${PROJECT_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS/nf_mbedtls_config.h>\"")
endif()

if(USE_NETWORKING_OPTION)
set_property(TARGET ${NANOCLR_PROJECT_NAME}.elf APPEND_STRING PROPERTY LINK_FLAGS " -L${CMAKE_CURRENT_BINARY_DIR} -lNetworkLib " )
set_property(TARGET ${NANOCLR_PROJECT_NAME}.elf APPEND_STRING PROPERTY LINK_FLAGS " -L${CMAKE_CURRENT_BINARY_DIR} -lNetworkLib " )

# add dependency for security provider mbedTLS
if(NF_SECURITY_MBEDTLS)
add_dependencies(${NANOCLR_PROJECT_NAME}.elf mbedTLS)
endif()
endif()

set_property(TARGET ${NANOCLR_PROJECT_NAME}.elf APPEND_STRING PROPERTY LINK_FLAGS " -lgcc -lstdc++ -Wl,--end-group -Wl,-EL ")
Expand All @@ -154,6 +171,8 @@ include_directories(

${WireProtocol_INCLUDE_DIRS}

# ${mbedTLS_INCLUDE_DIRS}

${TARGET_ESP32_IDF_INCLUDES}
)

Expand All @@ -175,8 +194,9 @@ target_include_directories(${NANOCLR_PROJECT_NAME}.elf PUBLIC
if(USE_NETWORKING_OPTION)
target_include_directories(NetworkLib PUBLIC
${CMAKE_CURRENT_BINARY_DIR}/nanoCLR
${NF_CoreCLR_INCLUDE_DIRS}
${NF_CoreCLR_INCLUDE_DIRS}
${NF_Networking_INCLUDE_DIRS}
${mbedTLS_INCLUDE_DIRS}
)

target_compile_definitions(NetworkLib PUBLIC "-DPLATFORM_ESP32 " )
Expand Down
8 changes: 4 additions & 4 deletions targets/FreeRTOS_ESP32/ESP32_WROOM_32/IDF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/heap/include")
list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/app_trace/include")
list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/bt/include")
list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/wear_levelling/include")
list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/mbedtls/port/include" "${COMPONENT_PATH}/mbedtls/include" )
# list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/mbedtls/port/include" "${COMPONENT_PATH}/mbedtls/mbedtls/include" )

list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/nghttp/port/include")
list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/nghttp/nghttp2/lib/includes")

list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/openssl/include")
# list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/openssl/include")

list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/app_update/include")
list(APPEND TARGET_ESP32_IDF_INCLUDES "${COMPONENT_PATH}/vfs/include")
Expand Down Expand Up @@ -319,13 +319,13 @@ list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libjsmn.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libjson.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/liblibsodium.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/liblog.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libmbedtls.a)
# list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libmbedtls.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libmdns.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libmicro-ecc.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libnewlib.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libnghttp.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libnvs_flash.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libopenssl.a)
# list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libopenssl.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libsdmmc.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libsoc.a)
list(APPEND DIRECT_LINK_LIBS ${DIRECT_LINK_PATH}/libspi_flash.a)
Expand Down
7 changes: 4 additions & 3 deletions targets/FreeRTOS_ESP32/ESP32_WROOM_32/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ list(APPEND TARGET_ESP32_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c
list(APPEND TARGET_ESP32_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp")

# append networking files, if enabled
if(USE_NETWORKING_OPTION)
list(APPEND TARGET_CHIBIOS_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Network.cpp")
if(NF_SECURITY_MBEDTLS)
list(APPEND NF_Networking_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_entropy_hardware_pool.c)
endif()

# make var global
# make vars global
set(TARGET_ESP32_COMMON_SOURCES ${TARGET_ESP32_COMMON_SOURCES} CACHE INTERNAL "make global")
set(NF_Networking_SOURCES ${NF_Networking_SOURCES} CACHE INTERNAL "make global")
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Copyright (c) 2017 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include <Esp32_os.h>

// Get len bytes of entropy from the hardware RNG.
int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen )
{
(void)data;

for(size_t i = 0; i < len; i++)
{
// our generator returns 32bits numbers
*output = (unsigned char)esp_random();

output++;
}

// callers require this to be set
*olen = len;

return 0;
}
53 changes: 53 additions & 0 deletions targets/FreeRTOS_ESP32/ESP32_WROOM_32/mbedtls_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) 2006-2015, ARM Limited, All Rights Reserved
// See LICENSE file in the project root for full license information.
//

#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H

/* For test certificates */
// #define MBEDTLS_CERTS_C
// #define MBEDTLS_PEM_PARSE_C

// #define SSL_DEBUG_BUF MBEDTLS_SSL_DEBUG_BUF
// #define SSL_DEBUG_CRT MBEDTLS_SSL_DEBUG_CRT
// #define SSL_DEBUG_ECP MBEDTLS_SSL_DEBUG_ECP
// #define SSL_DEBUG_MPI MBEDTLS_SSL_DEBUG_MPI
// #define SSL_DEBUG_MSG MBEDTLS_SSL_DEBUG_MSG
// #define SSL_DEBUG_RET MBEDTLS_SSL_DEBUG_RET

// #define MBEDTLS_SSL_ALL_ALERT_MESSAGES
// #define MBEDTLS_SSL_DEBUG_ALL
// #define MBEDTLS_VERSION_FEATURES
// #define MBEDTLS_CERTS_C
// #define MBEDTLS_ERROR_C
// #define MBEDTLS_VERSION_C

// uncomment the defines below to enable static memory allocation feature
#if 0
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
#define MBEDTLS_PLATFORM_MEMORY
#endif

#ifdef USE_LCD
#include "lcd_log.h"
#define MBEDTLS_PLATFORM_PRINTF_MACRO LCD_UsrLog
#endif

// uncomment the defines bellow to generate debug output
// set below the threshold level for debug messages
// check mbed TLS mbedtls/debug.h header for details.
// Debug levels:
// 0 No debug
// 1 Error
// 2 State change
// 3 Informational
// 4 Verbose

// #define MBEDTLS_DEBUG_C
// #define MBEDTLS_SSL_ALL_ALERT_MESSAGES
#define MBEDTLS_DEBUG_THRESHOLD 2

#endif // MBEDTLS_CONFIG_H

0 comments on commit 644d913

Please sign in to comment.