From 4fe58c7e89f0eb1a7108e507f343aefedb89c705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Mon, 30 Oct 2023 19:06:34 +0000 Subject: [PATCH] Add hashing and cryptography libraries (#2803) --- CMake/Modules/FindNF_NativeAssemblies.cmake | 82 ++++++++++++------- .../FindnanoFramework.System.IO.Hashing.cmake | 51 ++++++++++++ ...amework.System.Security.Cryptography.cmake | 51 ++++++++++++ CMake/binutils.ChibiOS.cmake | 8 +- CMake/binutils.FreeRTOS.cmake | 8 +- CMake/binutils.common.cmake | 58 ++++++++++++- CMake/xtensa-esp32.json | 2 + CMake/xtensa-esp32c3.json | 2 + CMake/xtensa-esp32s2.json | 2 + CMake/xtensa-esp32s3.json | 2 + .../nf_sys_io_hashing.cpp | 30 +++++++ .../nf_sys_io_hashing.h | 25 ++++++ .../nf_sys_sec_cryptography.cpp | 32 ++++++++ .../nf_sys_sec_cryptography.h | 38 +++++++++ ...ystem_Security_Cryptography_HMACSHA256.cpp | 66 +++++++++++++++ .../SiliconLabs/SL_STK3701A/CMakePresets.json | 1 + .../SiliconLabs/_common/nanoSupport_CRC32.c | 13 ++- ...sys_io_hashing_System_IO_Hashing_Crc32.cpp | 76 +++++++++++++++++ targets/ChibiOS/CMakeLists.txt | 54 +----------- .../ST_STM32F769I_DISCOVERY/CMakePresets.json | 2 + targets/ChibiOS/_common/nanoSupport_CRC32.c | 16 ++-- ...sys_io_hashing_System_IO_Hashing_Crc32.cpp | 63 ++++++++++++++ .../os/hal/ports/STM32/LLD/CRCv1/crc_lld.c | 8 +- .../os/hal/ports/STM32/LLD/CRCv1/crc_lld.h | 4 +- ...sys_io_hashing_System_IO_Hashing_Crc32.cpp | 65 +++++++++++++++ 25 files changed, 662 insertions(+), 97 deletions(-) create mode 100644 CMake/Modules/FindnanoFramework.System.IO.Hashing.cmake create mode 100644 CMake/Modules/FindnanoFramework.System.Security.Cryptography.cmake create mode 100644 src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.cpp create mode 100644 src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.h create mode 100644 src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.cpp create mode 100644 src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.h create mode 100644 src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256.cpp create mode 100644 targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp create mode 100644 targets/ESP32/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index b63cec5240..fcafed5029 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -9,45 +9,52 @@ # and the namespace designation is 'System.Device.Gpio' ########################################################################################### -option(API_nanoFramework.Device.Can "option for nanoFramework.Device.Can") -option(API_nanoFramework.Device.OneWire "option for nanoFramework.Device.OneWire") -option(API_nanoFramework.Networking.Sntp "option for nanoFramework.Networking.Sntp") -option(API_nanoFramework.Runtime.Events "option for nanoFramework.Runtime.Events API") -option(API_nanoFramework.ResourceManager "option for nanoFramework.ResourceManager") -option(API_nanoFramework.System.Collections "option for nanoFramework.System.Collections") -option(API_nanoFramework.System.Text "option for nanoFramework.System.Text") -option(API_System.IO.FileSystem "option for System.IO.FileSystem") -option(API_System.Math "option for System.Math") -option(API_System.Net "option for System.Net") -option(API_System.Device.Adc "option for System.Device.Adc API") -option(API_System.Device.Dac "option for System.Device.Dac API") -option(API_System.Device.Gpio "option for System.Device.Gpio API") -option(API_System.Device.I2c "option for System.Device.I2c API") -option(API_System.Device.I2s "option for System.Device.I2s API") -option(API_System.Device.Pwm "option for System.Device.Pwm API") -option(API_System.IO.Ports "option for System.IO.Ports API") -option(API_System.Device.Spi "option for System.Device.Spi API") -option(API_System.Runtime.Serialization "option for System.Runtime.Serialization API") -option(API_Windows.Storage "option for Windows.Storage") -option(API_nanoFramework.Graphics "option for nanoFramework.Graphics") -option(API_nanoFramework.Device.Bluetooth "option for nanoFramework.Device.Bluetooth") -option(API_System.Device.UsbStream "option for System.Device.UsbStream API") +option(API_nanoFramework.Device.Can "option for nanoFramework.Device.Can") +option(API_nanoFramework.Device.OneWire "option for nanoFramework.Device.OneWire") +option(API_nanoFramework.Networking.Sntp "option for nanoFramework.Networking.Sntp") +option(API_nanoFramework.Runtime.Events "option for nanoFramework.Runtime.Events API") +option(API_nanoFramework.ResourceManager "option for nanoFramework.ResourceManager") +option(API_nanoFramework.System.Collections "option for nanoFramework.System.Collections") +option(API_nanoFramework.System.Text "option for nanoFramework.System.Text") +option(API_System.IO.FileSystem "option for System.IO.FileSystem") +option(API_System.Math "option for System.Math") +option(API_System.Net "option for System.Net") +option(API_System.Device.Adc "option for System.Device.Adc API") +option(API_System.Device.Dac "option for System.Device.Dac API") +option(API_System.Device.Gpio "option for System.Device.Gpio API") +option(API_System.Device.I2c "option for System.Device.I2c API") +option(API_System.Device.I2s "option for System.Device.I2s API") +option(API_System.Device.Pwm "option for System.Device.Pwm API") +option(API_System.IO.Ports "option for System.IO.Ports API") +option(API_System.Device.Spi "option for System.Device.Spi API") +option(API_System.Runtime.Serialization "option for System.Runtime.Serialization API") +option(API_Windows.Storage "option for Windows.Storage") +option(API_nanoFramework.Graphics "option for nanoFramework.Graphics") +option(API_nanoFramework.Device.Bluetooth "option for nanoFramework.Device.Bluetooth") +option(API_System.Device.UsbStream "option for System.Device.UsbStream API") +option(API_nanoFramework.System.IO.Hashing "option for nanoFramework.System.IO.Hashing API") +option(API_nanoFramework.System.Security.Cryptography "option for nanoFramework.System.Security.Cryptography API") # Esp32 only -option(API_Hardware.Esp32 "option for Hardware.Esp32") -option(API_nanoFramework.Hardware.Esp32.Rmt "option for nanoFramework.Hardware.Esp32.Rmt") +option(API_Hardware.Esp32 "option for Hardware.Esp32") +option(API_nanoFramework.Hardware.Esp32.Rmt "option for nanoFramework.Hardware.Esp32.Rmt") # Stm32 only -option(API_Hardware.Stm32 "option for Hardware.Stm32") +option(API_Hardware.Stm32 "option for Hardware.Stm32") # TI CC13xxCC26xx -option(API_nanoFramework.TI.EasyLink "option for nanoFramework.TI.EasyLink API") -option(API_nanoFramework.Hardware.TI "option for nanoFramework.Hardware.TI API") +option(API_nanoFramework.TI.EasyLink "option for nanoFramework.TI.EasyLink API") +option(API_nanoFramework.Hardware.TI "option for nanoFramework.Hardware.TI API") # Silabs Giant Gecko only -option(API_nanoFramework.GiantGecko.Adc "option for nanoFramework.GiantGecko.Adc") -option(API_Hardware.GiantGecko "option for Hardware.GiantGecko") +option(API_nanoFramework.GiantGecko.Adc "option for nanoFramework.GiantGecko.Adc") +option(API_Hardware.GiantGecko "option for Hardware.GiantGecko") + +################################### +# add options for private APIs here + +################################### ################################### # add options for private APIs here @@ -261,6 +268,21 @@ if(API_Hardware.GiantGecko) PerformSettingsForApiEntry("nanoFramework.Hardware.GiantGecko") endif() +# nanoFramework.System.IO.Hashing +if(API_nanoFramework.System.IO.Hashing) + ##### API name here (doted name) + PerformSettingsForApiEntry("nanoFramework.System.IO.Hashing") +endif() + +# nanoFramework.System.Security.Cryptography +if(API_nanoFramework.System.Security.Cryptography) + ##### API name here (doted name) + PerformSettingsForApiEntry("nanoFramework.System.Security.Cryptography") + + # enable adding Mbed TLS to the build + set(NF_REQUIRES_MBEDTLS TRUE CACHE BOOL "Enable Mbed TLS for nanoFramework.System.Security.Cryptography" FORCE) +endif() + # nanoFramework.Runtime.Events if(API_nanoFramework.Runtime.Events) ##### API name here (doted name) diff --git a/CMake/Modules/FindnanoFramework.System.IO.Hashing.cmake b/CMake/Modules/FindnanoFramework.System.IO.Hashing.cmake new file mode 100644 index 0000000000..822bc4b751 --- /dev/null +++ b/CMake/Modules/FindnanoFramework.System.IO.Hashing.cmake @@ -0,0 +1,51 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# native code directory +set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.System.IO.Hashing) + + +# set include directories +list(APPEND nanoFramework.System.IO.Hashing_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) +list(APPEND nanoFramework.System.IO.Hashing_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) +list(APPEND nanoFramework.System.IO.Hashing_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) +list(APPEND nanoFramework.System.IO.Hashing_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND nanoFramework.System.IO.Hashing_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) +list(APPEND nanoFramework.System.IO.Hashing_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/nanoFramework.System.IO.Hashing) + +# source files +set(nanoFramework.System.IO.Hashing_SRCS + + nf_sys_io_hashing.cpp + + + nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp + +) + +foreach(SRC_FILE ${nanoFramework.System.IO.Hashing_SRCS}) + + set(nanoFramework.System.IO.Hashing_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(nanoFramework.System.IO.Hashing_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + ${TARGET_BASE_LOCATION} + ${PROJECT_SOURCE_DIR}/src/nanoFramework.System.IO.Hashing + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.System.IO.Hashing_SRC_FILE}") + endif() + + list(APPEND nanoFramework.System.IO.Hashing_SOURCES ${nanoFramework.System.IO.Hashing_SRC_FILE}) + +endforeach() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.System.IO.Hashing DEFAULT_MSG nanoFramework.System.IO.Hashing_INCLUDE_DIRS nanoFramework.System.IO.Hashing_SOURCES) diff --git a/CMake/Modules/FindnanoFramework.System.Security.Cryptography.cmake b/CMake/Modules/FindnanoFramework.System.Security.Cryptography.cmake new file mode 100644 index 0000000000..c9516a814f --- /dev/null +++ b/CMake/Modules/FindnanoFramework.System.Security.Cryptography.cmake @@ -0,0 +1,51 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# native code directory +set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.System.Security.Cryptography) + + +# set include directories +list(APPEND nanoFramework.System.Security.Cryptography_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) +list(APPEND nanoFramework.System.Security.Cryptography_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) +list(APPEND nanoFramework.System.Security.Cryptography_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) +list(APPEND nanoFramework.System.Security.Cryptography_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND nanoFramework.System.Security.Cryptography_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) +list(APPEND nanoFramework.System.Security.Cryptography_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/nanoFramework.System.Security.Cryptography) + +# source files +set(nanoFramework.System.Security.Cryptography_SRCS + + nf_sys_sec_cryptography.cpp + + + nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256.cpp + +) + +foreach(SRC_FILE ${nanoFramework.System.Security.Cryptography_SRCS}) + + set(nanoFramework.System.Security.Cryptography_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(nanoFramework.System.Security.Cryptography_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + ${TARGET_BASE_LOCATION} + ${PROJECT_SOURCE_DIR}/src/nanoFramework.System.Security.Cryptography + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.System.Security.Cryptography_SRC_FILE}") + endif() + + list(APPEND nanoFramework.System.Security.Cryptography_SOURCES ${nanoFramework.System.Security.Cryptography_SRC_FILE}) + +endforeach() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.System.Security.Cryptography DEFAULT_MSG nanoFramework.System.Security.Cryptography_INCLUDE_DIRS nanoFramework.System.Security.Cryptography_SOURCES) diff --git a/CMake/binutils.ChibiOS.cmake b/CMake/binutils.ChibiOS.cmake index 76279accee..b77982b399 100644 --- a/CMake/binutils.ChibiOS.cmake +++ b/CMake/binutils.ChibiOS.cmake @@ -160,6 +160,10 @@ macro(nf_add_platform_dependencies target) endif() + if(API_nanoFramework.System.Security.Cryptography) + FetchContent_GetProperties(mbedtls) + endif() + nf_add_lib_native_assemblies( EXTRA_INCLUDES ${CHIBIOS_INCLUDE_DIRS} @@ -171,7 +175,9 @@ macro(nf_add_platform_dependencies target) ${SPIFFS_INCLUDE_DIRS} ${TARGET_CHIBIOS_COMMON_INCLUDE_DIRS} ${TARGET_CHIBIOS_NANOCLR_INCLUDE_DIRS} - ${chibios_SOURCE_DIR}/os/hal/boards/${TARGET_BOARD}) + ${chibios_SOURCE_DIR}/os/hal/boards/${TARGET_BOARD} + ${mbedtls_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS) add_dependencies(${target}.elf nano::NF_NativeAssemblies) diff --git a/CMake/binutils.FreeRTOS.cmake b/CMake/binutils.FreeRTOS.cmake index feee2643ef..c4f782d919 100644 --- a/CMake/binutils.FreeRTOS.cmake +++ b/CMake/binutils.FreeRTOS.cmake @@ -125,6 +125,10 @@ macro(nf_add_platform_dependencies target) endif() + if(API_nanoFramework.System.Security.Cryptography) + FetchContent_GetProperties(mbedtls) + endif() + nf_add_lib_native_assemblies( EXTRA_INCLUDES ${CMSIS_INCLUDE_DIRS} @@ -137,7 +141,9 @@ macro(nf_add_platform_dependencies target) ${FATFS_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/targets/FreeRTOS/NXP/_fatfs - ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}) + ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD} + ${mbedtls_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS) add_dependencies(${target}.elf nano::NF_NativeAssemblies) diff --git a/CMake/binutils.common.cmake b/CMake/binutils.common.cmake index bdf1b65d0d..8221a10fd8 100644 --- a/CMake/binutils.common.cmake +++ b/CMake/binutils.common.cmake @@ -697,4 +697,60 @@ function(nf_check_path_limits) endif() -endfunction() \ No newline at end of file +endfunction() + +function(nf_add_mbedtls_library) + + # 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 tag for currently supported version + # WHEN CHANGING THIS MAKE SURE TO UPDATE THE DEV CONTAINERS + set(MBEDTLS_GIT_TAG "mbedtls-2.28.5") + + # 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 + message(STATUS "MbedTLS ${MBEDTLS_GIT_TAG} from GitHub repo") + + FetchContent_Declare( + mbedtls + GIT_REPOSITORY https://github.com/ARMmbed/mbedtls + GIT_TAG ${MBEDTLS_GIT_TAG} + ) + + else() + # MbedTLS source was specified + + message(STATUS "MbedTLS ${MBEDTLS_GIT_TAG} (source from: ${MBEDTLS_SOURCE})") + + FetchContent_Declare( + mbedtls + SOURCE_DIR ${MBEDTLS_SOURCE} + ) + + endif() + + # Check if population has already been performed + FetchContent_GetProperties(mbedtls) + if(NOT mbedtls_POPULATED) + # Fetch the content using previously declared details + FetchContent_Populate(mbedtls) + endif() + + # don't include tests or programs, only build libraries + set(ENABLE_TESTING CACHE BOOL OFF) + set(ENABLE_PROGRAMS CACHE BOOL OFF) + + cmake_policy(SET CMP0048 NEW) + add_subdirectory(${mbedtls_SOURCE_DIR} mbedtls_build) + +endfunction() diff --git a/CMake/xtensa-esp32.json b/CMake/xtensa-esp32.json index 6e361fdade..8a156223a7 100644 --- a/CMake/xtensa-esp32.json +++ b/CMake/xtensa-esp32.json @@ -33,6 +33,8 @@ "API_System.Device.Wifi": "ON", "API_System.IO.Ports": "ON", "API_Hardware.Esp32": "ON", + "API_nanoFramework.System.IO.Hashing": "ON", + "API_nanoFramework.System.Security.Cryptography": "ON", "API_nanoFramework.Hardware.Esp32.Rmt": "ON", "API_nanoFramework.ResourceManager": "ON", "API_nanoFramework.System.Collections": "ON", diff --git a/CMake/xtensa-esp32c3.json b/CMake/xtensa-esp32c3.json index bd8783fd14..9ac6a64771 100644 --- a/CMake/xtensa-esp32c3.json +++ b/CMake/xtensa-esp32c3.json @@ -33,6 +33,8 @@ "API_System.Device.Wifi": "ON", "API_System.IO.Ports": "ON", "API_Hardware.Esp32": "ON", + "API_nanoFramework.System.IO.Hashing": "ON", + "API_nanoFramework.System.Security.Cryptography": "ON", "API_nanoFramework.Hardware.Esp32.Rmt": "OFF", "API_nanoFramework.ResourceManager": "ON", "API_nanoFramework.System.Collections": "ON", diff --git a/CMake/xtensa-esp32s2.json b/CMake/xtensa-esp32s2.json index c128abc201..a3b6ac9805 100644 --- a/CMake/xtensa-esp32s2.json +++ b/CMake/xtensa-esp32s2.json @@ -33,6 +33,8 @@ "API_System.Device.Wifi": "ON", "API_System.IO.Ports": "ON", "API_Hardware.Esp32": "ON", + "API_nanoFramework.System.IO.Hashing": "ON", + "API_nanoFramework.System.Security.Cryptography": "ON", "API_nanoFramework.Hardware.Esp32.Rmt": "ON", "API_nanoFramework.ResourceManager": "ON", "API_nanoFramework.System.Collections": "ON", diff --git a/CMake/xtensa-esp32s3.json b/CMake/xtensa-esp32s3.json index 8eee652168..2ec76528db 100644 --- a/CMake/xtensa-esp32s3.json +++ b/CMake/xtensa-esp32s3.json @@ -32,6 +32,8 @@ "API_System.Device.Wifi": "ON", "API_System.IO.Ports": "ON", "API_System.IO.FileSystem": "ON", + "API_nanoFramework.System.IO.Hashing": "ON", + "API_nanoFramework.System.Security.Cryptography": "ON", "API_Hardware.Esp32": "ON", "API_Windows.Storage": "ON", "API_nanoFramework.Hardware.Esp32.Rmt": "ON", diff --git a/src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.cpp b/src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.cpp new file mode 100644 index 0000000000..114f145a17 --- /dev/null +++ b/src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.cpp @@ -0,0 +1,30 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_sys_io_hashing.h" + +// clang-format off + +static const CLR_RT_MethodHandler method_lookup[] = +{ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nf_sys_io_hashing_System_IO_Hashing_Crc32::ComputeHash___STATIC__U4__U4__SystemSpanByte, +}; + +const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_System_IO_Hashing = +{ + "nanoFramework.System.IO.Hashing", + 0xEBD8ED20, + method_lookup, + { 100, 0, 0, 1 } +}; + +// clang-format on diff --git a/src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.h b/src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.h new file mode 100644 index 0000000000..1ddf42f724 --- /dev/null +++ b/src/nanoFramework.System.IO.Hashing/nf_sys_io_hashing.h @@ -0,0 +1,25 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NF_SYS_IO_HASHING_H +#define NF_SYS_IO_HASHING_H + +#include +#include +#include +#include + +struct Library_nf_sys_io_hashing_System_IO_Hashing_Crc32 +{ + static const int FIELD___crc = 1; + + NANOCLR_NATIVE_DECLARE(ComputeHash___STATIC__U4__U4__SystemSpanByte); + + //--// +}; + +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_System_IO_Hashing; + +#endif // NF_SYS_IO_HASHING_H diff --git a/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.cpp b/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.cpp new file mode 100644 index 0000000000..80280f1a9f --- /dev/null +++ b/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.cpp @@ -0,0 +1,32 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_sys_sec_cryptography.h" + +// clang-format off + +static const CLR_RT_MethodHandler method_lookup[] = +{ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256::HashCore___STATIC__SZARRAY_U1__SZARRAY_U1__SZARRAY_U1, +}; + +const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_System_Security_Cryptography = +{ + "nanoFramework.System.Security.Cryptography", + 0xC71CFC75, + method_lookup, + { 100, 0, 0, 1 } +}; + +// clang-format on diff --git a/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.h b/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.h new file mode 100644 index 0000000000..6e49972200 --- /dev/null +++ b/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography.h @@ -0,0 +1,38 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NF_SYS_SEC_CRYPTOGRAPHY_H +#define NF_SYS_SEC_CRYPTOGRAPHY_H + +#include +#include +#include +#include + +#ifdef PLATFORM_ESP32 +#include +#include +#else +#include +#endif + +#include +#include +#include + +struct Library_nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256 +{ + static const int FIELD___disposed = 1; + static const int FIELD___keyValue = 2; + static const int FIELD___hashValue = 3; + + NANOCLR_NATIVE_DECLARE(HashCore___STATIC__SZARRAY_U1__SZARRAY_U1__SZARRAY_U1); + + //--// +}; + +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_System_Security_Cryptography; + +#endif // NF_SYS_SEC_CRYPTOGRAPHY_H diff --git a/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256.cpp b/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256.cpp new file mode 100644 index 0000000000..34888e96a9 --- /dev/null +++ b/src/nanoFramework.System.Security.Cryptography/nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256.cpp @@ -0,0 +1,66 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_sys_sec_cryptography.h" + +HRESULT Library_nf_sys_sec_cryptography_System_Security_Cryptography_HMACSHA256:: + HashCore___STATIC__SZARRAY_U1__SZARRAY_U1__SZARRAY_U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + const mbedtls_md_info_t *md_info = &mbedtls_sha256_info; + mbedtls_md_context_t ctx; + + CLR_RT_HeapBlock_Array *keyArray; + CLR_RT_HeapBlock_Array *sourceArray; + CLR_RT_HeapBlock_Array *outputArray; + + // grab pointers to the arguments + keyArray = stack.Arg0().DereferenceArray(); + FAULT_ON_NULL_ARG(keyArray); + + sourceArray = stack.Arg1().DereferenceArray(); + FAULT_ON_NULL_ARG(sourceArray); + + // create the return array (32 bytes length) + stack.PushValueAndClear(); + NANOCLR_CHECK_HRESULT( + CLR_RT_HeapBlock_Array::CreateInstance(stack.TopValue(), 32, g_CLR_RT_WellKnownTypes.m_UInt8)); + outputArray = stack.TopValue().DereferenceArray(); + + // better clear memory + memset(outputArray->GetFirstElement(), 0, outputArray->m_numOfElements); + + // need to initialize MbedTLS stuff + mbedtls_md_init(&ctx); + if (mbedtls_md_setup(&ctx, md_info, 1) != 0) + { + // failed to initialize + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + // perform calculation + if (mbedtls_md_hmac_starts(&ctx, keyArray->GetFirstElement(), keyArray->m_numOfElements) != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + if (mbedtls_md_hmac_update(&ctx, sourceArray->GetFirstElement(), sourceArray->m_numOfElements) != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + if (mbedtls_md_hmac_finish(&ctx, outputArray->GetFirstElement()) != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + // need to clean up MbedTLS stuff + NANOCLR_CLEANUP(); + + mbedtls_md_free(&ctx); + + NANOCLR_CLEANUP_END(); +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakePresets.json b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakePresets.json index 21e4dd0516..ed8af05573 100644 --- a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakePresets.json +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakePresets.json @@ -40,6 +40,7 @@ "API_nanoFramework.ResourceManager": "ON", "API_nanoFramework.System.Collections": "ON", "API_nanoFramework.System.Text": "ON", + "API_nanoFramework.System.IO.Hashing": "ON", "API_nanoFramework.GiantGecko.Adc": "OFF", "API_Windows.Storage": "OFF", "API_nanoFramework.Graphics": "OFF", diff --git a/targets/AzureRTOS/SiliconLabs/_common/nanoSupport_CRC32.c b/targets/AzureRTOS/SiliconLabs/_common/nanoSupport_CRC32.c index bb084257c1..13e4af8b1d 100644 --- a/targets/AzureRTOS/SiliconLabs/_common/nanoSupport_CRC32.c +++ b/targets/AzureRTOS/SiliconLabs/_common/nanoSupport_CRC32.c @@ -20,7 +20,18 @@ uint32_t SUPPORT_ComputeCRC(const void *rgBlock, const uint32_t nLength, const u return crc; } - if(crc == 0) + // Declare init structs + GPCRC_Init_TypeDef init = GPCRC_INIT_DEFAULT; + + // reverse all bits of the incoming message + init.reverseBits = true; + // all buffers are treated as byte buffers + init.enableByteMode = true; + + // Initialize GPCRC + GPCRC_Init(GPCRC, &init); + + if (crc == 0) { // this is NOT continuing a previous CRC calculation diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp new file mode 100644 index 0000000000..90281a3017 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp @@ -0,0 +1,76 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +// #include +// #include +#include +#include +#include + +typedef Library_corlib_native_System_SpanByte SpanByte; + +HRESULT Library_nf_sys_io_hashing_System_IO_Hashing_Crc32::ComputeHash___STATIC__U4__U4__SystemSpanByte( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock *bufferSpanByte; + CLR_RT_HeapBlock_Array *buffer; + uint8_t *bufferData = NULL; + int16_t bufferSize = 0; + int16_t bufferOffset = 0; + uint32_t crc32 = 0; + uint32_t hash = 0; + + // get a pointer to the managed object instance and check that it's not NULL + bufferSpanByte = stack.Arg1().Dereference(); + FAULT_ON_NULL_ARG(bufferSpanByte); + + // get initial CRC32 value + crc32 = stack.Arg0().NumericByRef().u4; + + // get buffer + buffer = bufferSpanByte[SpanByte::FIELD___array].DereferenceArray(); + + // Get the write offset + bufferOffset = bufferSpanByte[SpanByte::FIELD___start].NumericByRef().s4; + + // use the span length as write size, only the elements defined by the span must be written + bufferSize = bufferSpanByte[SpanByte::FIELD___length].NumericByRef().s4; + bufferData = (unsigned char *)buffer->GetElement(bufferOffset); + + if (bufferSize == 0) + { + hash = 0xFFFFFFFF; + } + else + { + // Declare init structs + GPCRC_Init_TypeDef init = GPCRC_INIT_DEFAULT; + init.initValue = crc32; + // reverse all bits of the incoming message + init.reverseBits = false; + // all buffers are treated as byte buffers + init.enableByteMode = true; + + // Initialize GPCRC + GPCRC_Init(GPCRC, &init); + + // Prepare GPCRC_DATA for inputs + GPCRC_Start(GPCRC); + + for (int32_t i = 0; i < bufferSize; i++) + { + GPCRC_InputU8(GPCRC, *bufferData++); + } + + hash = GPCRC_DataRead(GPCRC); + } + + stack.SetResult_U4(hash); + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/ChibiOS/CMakeLists.txt b/targets/ChibiOS/CMakeLists.txt index 54fe2b769e..53ad69037d 100644 --- a/targets/ChibiOS/CMakeLists.txt +++ b/targets/ChibiOS/CMakeLists.txt @@ -210,59 +210,9 @@ if(NF_FEATURE_HAS_SDCARD OR NF_FEATURE_HAS_USB_MSD) endif() # if Mbed TLS is enabled add it to the build -if(USE_SECURITY_MBEDTLS_OPTION) +if(USE_SECURITY_MBEDTLS_OPTION OR NF_REQUIRES_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 tag for currently supported version - # WHEN CHANGING THIS MAKE SURE TO UPDATE THE DEV CONTAINERS - set(MBEDTLS_GIT_TAG "mbedtls-2.28.5") - - # 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 - message(STATUS "MbedTLS ${MBEDTLS_GIT_TAG} from GitHub repo") - - FetchContent_Declare( - mbedtls - GIT_REPOSITORY https://github.com/ARMmbed/mbedtls - GIT_TAG ${MBEDTLS_GIT_TAG} - ) - - else() - # MbedTLS source was specified - - message(STATUS "MbedTLS ${MBEDTLS_GIT_TAG} (source from: ${MBEDTLS_SOURCE})") - - FetchContent_Declare( - mbedtls - SOURCE_DIR ${MBEDTLS_SOURCE} - ) - - endif() - - # Check if population has already been performed - FetchContent_GetProperties(mbedtls) - if(NOT mbedtls_POPULATED) - # Fetch the content using previously declared details - FetchContent_Populate(mbedtls) - endif() - - # don't include tests or programs, only build libraries - set(ENABLE_TESTING CACHE BOOL OFF) - set(ENABLE_PROGRAMS CACHE BOOL OFF) - - cmake_policy(SET CMP0048 NEW) - add_subdirectory(${mbedtls_SOURCE_DIR} mbedtls_build) + nf_add_mbedtls_library() endif() diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/CMakePresets.json b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/CMakePresets.json index a3f035e6d0..e89ebcb8d4 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/CMakePresets.json +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/CMakePresets.json @@ -43,6 +43,8 @@ "API_nanoFramework.System.Collections": "ON", "API_nanoFramework.System.Text": "ON", "API_Windows.Storage": "ON", + "API_nanoFramework.System.IO.Hashing": "ON", + "API_nanoFramework.System.Security.Cryptography": "ON", "API_nanoFramework.Graphics": "ON", "GRAPHICS_MEMORY": "Graphics_Memory.cpp", "GRAPHICS_DISPLAY": "Otm8009a_DSI_Video_Mode.cpp", diff --git a/targets/ChibiOS/_common/nanoSupport_CRC32.c b/targets/ChibiOS/_common/nanoSupport_CRC32.c index 924f87af71..dd86ede3bf 100644 --- a/targets/ChibiOS/_common/nanoSupport_CRC32.c +++ b/targets/ChibiOS/_common/nanoSupport_CRC32.c @@ -7,18 +7,20 @@ #include #include -#if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F2XX) || \ - defined(STM32F4XX) || defined(STM32F7XX) || defined(STM32L0XX) || \ - defined(STM32L1XX) || defined(STM32H7XX) +#if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX) || \ + defined(STM32L0XX) || defined(STM32L1XX) || defined(STM32H7XX) // strong implementation of this function specific to the STM32 targets -uint32_t SUPPORT_ComputeCRC(const void* rgBlock, const uint32_t nLength, const uint32_t crc) +uint32_t SUPPORT_ComputeCRC(const void *rgBlock, const uint32_t nLength, const uint32_t crc) { - crcAquireModule(); + crcAquireModule(); - uint32_t myCrc = crcCompute(rgBlock, nLength, crc); + crcStart(NULL); + crcReset(); - crcReleaseModule(); + uint32_t myCrc = crcCompute(rgBlock, nLength, crc); + + crcReleaseModule(); return myCrc; }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp new file mode 100644 index 0000000000..2ce98bd318 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +typedef Library_corlib_native_System_SpanByte SpanByte; + +// set config to use standard CRC32 +crcConfig crc32Config = { + .CRCLength = CRC_POLYLENGTH_32B, + .GeneratingPolynomial = DEFAULT_CRC32_POLY, + .InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES, + .FinalValue = 0, + .InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE, + .OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE}; + +HRESULT Library_nf_sys_io_hashing_System_IO_Hashing_Crc32::ComputeHash___STATIC__U4__U4__SystemSpanByte( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock *bufferSpanByte; + CLR_RT_HeapBlock_Array *buffer; + uint8_t *bufferData = NULL; + int16_t bufferSize = 0; + int16_t bufferOffset = 0; + uint32_t crc32 = 0; + uint32_t hash = 0; + + // get a pointer to the managed object instance and check that it's not NULL + bufferSpanByte = stack.Arg1().Dereference(); + FAULT_ON_NULL_ARG(bufferSpanByte); + + // get initial CRC32 value + crc32 = stack.Arg0().NumericByRef().u4; + + // get buffer + buffer = bufferSpanByte[SpanByte::FIELD___array].DereferenceArray(); + + // Get the write offset + bufferOffset = bufferSpanByte[SpanByte::FIELD___start].NumericByRef().s4; + + // use the span length as write size, only the elements defined by the span must be written + bufferSize = bufferSpanByte[SpanByte::FIELD___length].NumericByRef().s4; + bufferData = (unsigned char *)buffer->GetElement(bufferOffset); + + crcAquireModule(); + + crcStart(&crc32Config); + crcReset(); + + hash = crcCompute(bufferData, bufferSize, crc32); + + crcReleaseModule(); + + stack.SetResult_U4(hash); + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.c b/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.c index 15cc2d55d5..02246fa7a5 100644 --- a/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.c +++ b/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.c @@ -91,13 +91,17 @@ void crc_lld_start(const crcConfig *config) // set generating polynomial WRITE_REG(CRCD1.Instance->POL, CRCD1.Config->GeneratingPolynomial); + // reset CRC configuration register CRCD1.Instance->CR = 0; // set generating polynomial size MODIFY_REG(CRCD1.Instance->CR, CRC_CR_POLYSIZE, CRCD1.Config->CRCLength); + // set input format + MODIFY_REG(CRCD1.Instance->CR, CRC_CR_REV_OUT, CRCD1.Config->InputDataFormat); + // set input data inversion mode - MODIFY_REG(CRCD1.Instance->CR, CRC_CR_REV_IN, CRCD1.Config->OutputDataInversionMode); + MODIFY_REG(CRCD1.Instance->CR, CRC_CR_REV_IN, CRCD1.Config->InputDataInversionMode); // set output data inversion mode MODIFY_REG(CRCD1.Instance->CR, CRC_CR_REV_OUT, CRCD1.Config->OutputDataInversionMode); @@ -134,7 +138,7 @@ crc_lld_compute(const void *buffer, const uint32_t size, const uint32_t initialC // anything to do here? if (size == 0) { - return initialCrc; + return DEFAULT_CRC_INITVALUE; } // we'll be reading the buffer in steps of 4 bytes, so the size must be recalculated accordingly diff --git a/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.h b/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.h index 60979b0901..c0ff6988b5 100644 --- a/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.h +++ b/targets/ChibiOS/_nf-overlay/os/hal/ports/STM32/LLD/CRCv1/crc_lld.h @@ -45,10 +45,10 @@ typedef struct crcConfig uint32_t FinalValue; // Specifies input data inversion mode - bool InputDataInversionMode; + uint32_t InputDataInversionMode; // Specifies output data (i.e. CRC) inversion mode - bool OutputDataInversionMode; + uint32_t OutputDataInversionMode; } crcConfig; diff --git a/targets/ESP32/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp b/targets/ESP32/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp new file mode 100644 index 0000000000..b15b6c977d --- /dev/null +++ b/targets/ESP32/_nanoCLR/nanoFramework.System.IO.Hashing/nf_sys_io_hashing_System_IO_Hashing_Crc32.cpp @@ -0,0 +1,65 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +typedef Library_corlib_native_System_SpanByte SpanByte; + +HRESULT Library_nf_sys_io_hashing_System_IO_Hashing_Crc32::ComputeHash___STATIC__U4__U4__SystemSpanByte( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock *bufferSpanByte; + CLR_RT_HeapBlock_Array *buffer; + uint8_t *bufferData = NULL; + int16_t bufferSize = 0; + int16_t bufferOffset = 0; + uint32_t crc32 = 0; + uint32_t hash = 0; + + // get a pointer to the managed object instance and check that it's not NULL + bufferSpanByte = stack.Arg1().Dereference(); + FAULT_ON_NULL_ARG(bufferSpanByte); + + // get initial CRC32 value + crc32 = stack.Arg0().NumericByRef().u4; + + // get buffer + buffer = bufferSpanByte[SpanByte::FIELD___array].DereferenceArray(); + + // Get the write offset + bufferOffset = bufferSpanByte[SpanByte::FIELD___start].NumericByRef().s4; + + // use the span length as write size, only the elements defined by the span must be written + bufferSize = bufferSpanByte[SpanByte::FIELD___length].NumericByRef().s4; + bufferData = (unsigned char *)buffer->GetElement(bufferOffset); + +#ifdef ESP_ROM_HAS_CRC_LE + + // this series has ROM support for CRC32 + + if (bufferSize == 0) + { + hash = 0xFFFFFFFF; + } + else + { + hash = ~esp_rom_crc32_le(~crc32, bufferData, bufferSize); + } + +#else + + // this series does not have ROM support for CRC32 + // for the time being this is not supported + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + +#endif + + stack.SetResult_U4(hash); + + NANOCLR_NOCLEANUP(); +}