From 99291772cdfe241655bcf35481a90055d1c1778b Mon Sep 17 00:00:00 2001 From: trigaux Date: Wed, 14 May 2025 13:50:03 -0400 Subject: [PATCH 1/7] Add cmox. --- CMakeLists.txt | 9 ++++-- cmake/FindSTM32Cryptographic.cmake | 47 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 cmake/FindSTM32Cryptographic.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index b51961a..7f976ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ endif() message(STATUS "CXX Namespace: ${SFRAME_CXX_NAMESPACE}") message(STATUS "CMake Export Namespace: ${SFRAME_EXPORT_NAMESPACE}") -# Use -DCRYPTO=(OPENSSL_1_1 | OPENSSL_3 | BORINGSSL) to configure crypto +# Use -DCRYPTO=(OPENSSL_1_1 | OPENSSL_3 | BORINGSSL | STM32) to configure crypto if(NOT DEFINED CRYPTO) set(CRYPTO "OPENSSL_3") endif() @@ -92,8 +92,13 @@ elseif(${CRYPTO} STREQUAL "BORINGSSL") find_package(OpenSSL REQUIRED) add_compile_definitions(BORINGSSL) set(CRYPTO_LIB OpenSSL::Crypto) +elseif(${CRYPTO} STREQUAL "STM32") + message(STATUS "Configuring with STM32 Crypto") + find_package(STM32Cryptographic REQUIRED) + add_compile_definitions(STM32_CRYPTO) + set(CRYPTO_LIB STM32Cryptographic) else() - message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1 or OPENSSL_3) [${CRYPTO}]") + message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32) [${CRYPTO}]") endif() diff --git a/cmake/FindSTM32Cryptographic.cmake b/cmake/FindSTM32Cryptographic.cmake new file mode 100644 index 0000000..624adde --- /dev/null +++ b/cmake/FindSTM32Cryptographic.cmake @@ -0,0 +1,47 @@ +set(PACKAGE_NAME "STM32Cryptographic") +set(LIBRARY_NAME "STM32Cryptographic") + +# Locate the include directory +find_path( + STM32Cryptographic_INCLUDE_DIR + PATHS + ${STM32Cryptographic_ROOT_DIR} + /usr/local/include + /usr/include + PATH_SUFFIXES include +) + +# Locate the library +find_library( + STM32Cryptographic_LIBRARY + PATHS + ${STM32Cryptographic_ROOT_DIR} + /usr/local/lib + /usr/lib + PATH_SUFFIXES lib +) + +# Set the STM32Cryptographic_FOUND variable +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(${PACKAGE_NAME} + REQUIRED_VARS + STM32Cryptographic_INCLUDE_DIR + STM32Cryptographic_LIBRARY +) + +# Set output variables +if(${PACKAGE_NAME}_FOUND) + set(STM32Cryptographic_INCLUDE_DIRS ${STM32Cryptographic_INCLUDE_DIR}) + set(STM32Cryptographic_LIBRARIES ${STM32Cryptographic_LIBRARY}) +else() + set(STM32Cryptographic_INCLUDE_DIRS "") + set(STM32Cryptographic_LIBRARIES "") +endif() + +# Set compile definitions (if any) +# list(APPEND STM32Cryptographic_DEFINITIONS "-DSTM32Cryptographic_ENABLE_FEATURE") + +mark_as_advanced( + STM32Cryptographic_INCLUDE_DIR + STM32Cryptographic_LIBRARY +) From 901b1ff5019933da09e66694f6504202780a85a6 Mon Sep 17 00:00:00 2001 From: trigaux Date: Tue, 27 May 2025 15:59:41 -0400 Subject: [PATCH 2/7] Adding cmake options for finding stm32 cmox. --- CMakeLists.txt | 23 ++- cmake/FindSTM32Cryptographic.cmake | 43 ++++- src/crypto_stm32.cpp | 290 +++++++++++++++++++++++++++++ src/sframe.cpp | 4 + 4 files changed, 348 insertions(+), 12 deletions(-) create mode 100644 src/crypto_stm32.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f976ef..8c7ad73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,11 +92,27 @@ elseif(${CRYPTO} STREQUAL "BORINGSSL") find_package(OpenSSL REQUIRED) add_compile_definitions(BORINGSSL) set(CRYPTO_LIB OpenSSL::Crypto) -elseif(${CRYPTO} STREQUAL "STM32") +elseif(${CRYPTO} MATCHES "STM32") message(STATUS "Configuring with STM32 Crypto") + if(${CRYPTO} STREQUAL "STM32_CM0_CM0PLUS") + set(CRYPTO_LIB STM32Cryptographic_CM0_CM0PLUS) + elseif(${CRYPTO} STREQUAL "STM32_CM3") + set(CRYPTO_LIB STM32Cryptographic_CM3) + elseif(${CRYPTO} STREQUAL "STM32_CM33") + set(CRYPTO_LIB STM32Cryptographic_CM33) + elseif(${CRYPTO} STREQUAL "STM32_CM4") + set(CRYPTO_LIB STM32Cryptographic_CM4) + elseif(${CRYPTO} STREQUAL "STM32_CM7") + set(CRYPTO_LIB STM32Cryptographic_CM7) + else() + message(FATAL_ERROR "Please select a specific STM32 crypto back-end (STM32_CM0_CM0PLUS, STM32_CM3, STM32_CM33, STM32_CM4, STM32_CM7) [${CRYPTO}]") + endif() + + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) find_package(STM32Cryptographic REQUIRED) - add_compile_definitions(STM32_CRYPTO) - set(CRYPTO_LIB STM32Cryptographic) + + add_compile_definitions(STM32) + set(CRYPTO_INCLUDE_DIR ${STM32Cryptographic_INCLUDE_DIR}) else() message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32) [${CRYPTO}]") endif() @@ -119,6 +135,7 @@ target_include_directories(${LIB_NAME} $ $ $ + ${CRYPTO_INCLUDE_DIR} ) ### diff --git a/cmake/FindSTM32Cryptographic.cmake b/cmake/FindSTM32Cryptographic.cmake index 624adde..9886968 100644 --- a/cmake/FindSTM32Cryptographic.cmake +++ b/cmake/FindSTM32Cryptographic.cmake @@ -4,6 +4,7 @@ set(LIBRARY_NAME "STM32Cryptographic") # Locate the include directory find_path( STM32Cryptographic_INCLUDE_DIR + "cmox_crypto.h" PATHS ${STM32Cryptographic_ROOT_DIR} /usr/local/include @@ -11,15 +12,39 @@ find_path( PATH_SUFFIXES include ) -# Locate the library -find_library( - STM32Cryptographic_LIBRARY - PATHS - ${STM32Cryptographic_ROOT_DIR} - /usr/local/lib - /usr/lib - PATH_SUFFIXES lib -) +if(NOT STM32Cryptographic_INCLUDE_DIR) + message(WARNING "Could not find include dir for ${PACKAGE_NAME}") +else() + message(STATUS "Found include dir: ${STM32Cryptographic_INCLUDE_DIR}") +endif() + +function(find_stm32_crypto_library LIBRARY_NAME) + find_library( + ${LIBRARY_NAME} + NAMES ${LIBRARY_NAME} + PATHS + ${STM32Cryptographic_ROOT_DIR} + /usr/local/lib + /usr/lib + PATH_SUFFIXES lib + NO_DEFAULT_PATH + ) + + if(NOT ${LIBRARY_NAME}) + message(WARNING "Could not find library: ${LIBRARY_NAME}") + else() + message(STATUS "Found library: ${LIBRARY_NAME} at ${${LIBRARY_NAME}}") + endif() + + set(STM32Cryptographic_LIBRARY "${STM32Cryptographic_LIBRARY} ${STM32_CRYPTO_LIBRARY}" PARENT_SCOPE) +endfunction() + +# Locate the libraries +find_stm32_crypto_library(STM32Cryptographic_CM0_CM0PLUS) +find_stm32_crypto_library(STM32Cryptographic_CM3) +find_stm32_crypto_library(STM32Cryptographic_CM33) +find_stm32_crypto_library(STM32Cryptographic_CM4) +find_stm32_crypto_library(STM32Cryptographic_CM7) # Set the STM32Cryptographic_FOUND variable include(FindPackageHandleStandardArgs) diff --git a/src/crypto_stm32.cpp b/src/crypto_stm32.cpp new file mode 100644 index 0000000..e7eb383 --- /dev/null +++ b/src/crypto_stm32.cpp @@ -0,0 +1,290 @@ +#if defined(STM32) + +#include "crypto.h" +#include "header.h" + +#include +#include +#include +#include + +#include + +namespace sframe { + +#define VERIFY_CMOX_CALL(func, success_code) \ + do { \ + auto retval = func; \ + if (retval != success_code) { \ + cmox_error = retval; \ + throw crypto_error(); \ + } \ + } while (0) + +/// +/// Convert between native identifiers / errors and cmox ones +/// + +std::optional cmox_error; + +crypto_error::crypto_error() + : std::runtime_error( + cmox_error.has_value() + ? "CMOX crypto error (error=" + std::to_string(cmox_error.value()) + ")" + : "unknown CMOX crypto error") +{ +} + +extern "C" +{ + static cmox_mac_algo_t cmox_hmac_algo(CipherSuite suite) + { + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: + case CipherSuite::AES_GCM_128_SHA256: + return CMOX_HMAC_SHA256_ALGO; + case CipherSuite::AES_GCM_256_SHA512: + return CMOX_HMAC_SHA512_ALGO; + default: + throw unsupported_ciphersuite_error(); + } + } + + static cmox_hmac_impl_t cmox_hmac_impl(CipherSuite suite) + { + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: + case CipherSuite::AES_GCM_128_SHA256: + return CMOX_HMAC_SHA256; + case CipherSuite::AES_GCM_256_SHA512: + return CMOX_HMAC_SHA512; + default: + throw unsupported_ciphersuite_error(); + } + } + + static std::size_t cmox_hmac_size(CipherSuite suite) + { + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: + case CipherSuite::AES_GCM_128_SHA256: + return CMOX_SHA256_SIZE; + case CipherSuite::AES_GCM_256_SHA512: + return CMOX_SHA512_SIZE; + default: + throw unsupported_ciphersuite_error(); + } + } +} + +/// +/// HKDF +/// + +owned_bytes +hkdf_extract(CipherSuite suite, input_bytes salt, input_bytes ikm) +{ + std::size_t computed_size = 0; + const auto hmac_size = cmox_hmac_size(suite); + auto out = owned_bytes(hmac_size); + VERIFY_CMOX_CALL(cmox_mac_compute(cmox_hmac_algo(suite), + ikm.data(), + ikm.size(), + salt.data(), + salt.size(), + nullptr, + 0, + out.data(), + out.size(), + &computed_size), + CMOX_MAC_SUCCESS); + + return out; +} + +owned_bytes +hkdf_expand(CipherSuite suite, input_bytes prk, input_bytes info, size_t size) +{ + cmox_hmac_handle_t Hmac_Ctx; + cmox_mac_handle_t* mac_ctx; + + const auto digest_size = cmox_hmac_size(suite); + auto N = static_cast(size / digest_size); + if ((N * digest_size) < size) { + N++; + } + + mac_ctx = cmox_hmac_construct(&Hmac_Ctx, cmox_hmac_impl(suite)); + if (mac_ctx == nullptr) { + throw crypto_error(); + } + + owned_bytes computed_hash(size); + owned_bytes out(size); + + uint32_t index = 0; + for (uint8_t i = 1; i <= N; i++) { + VERIFY_CMOX_CALL(cmox_mac_init(mac_ctx), CMOX_MAC_SUCCESS); + + if (i == N) { + VERIFY_CMOX_CALL(cmox_mac_setTagLen(mac_ctx, size - index), + CMOX_MAC_SUCCESS); + } + + VERIFY_CMOX_CALL(cmox_mac_setKey(mac_ctx, prk.data(), prk.size()), + CMOX_MAC_SUCCESS); + + if (i > 1) { + VERIFY_CMOX_CALL( + cmox_mac_append(mac_ctx, computed_hash.data(), digest_size), + CMOX_MAC_SUCCESS); + } + + VERIFY_CMOX_CALL(cmox_mac_append(mac_ctx, info.data(), info.size()), + CMOX_MAC_SUCCESS); + VERIFY_CMOX_CALL(cmox_mac_append(mac_ctx, &i, 1), CMOX_MAC_SUCCESS); + VERIFY_CMOX_CALL( + cmox_mac_generateTag(mac_ctx, computed_hash.data(), nullptr), + CMOX_MAC_SUCCESS); + + if (i == N) { + memcpy(&out[index], computed_hash.data(), size - index); + index = size; + } else { + memcpy(&out[index], computed_hash.data(), digest_size); + index += digest_size; + } + } + + VERIFY_CMOX_CALL(cmox_mac_cleanup(mac_ctx), CMOX_MAC_SUCCESS); + + return out; +} + +static output_bytes +seal_aead(CipherSuite suite, + input_bytes key, + input_bytes nonce, + output_bytes ct, + input_bytes aad, + input_bytes pt) +{ + auto tag_size = cipher_overhead(suite); + if (ct.size() < pt.size() + tag_size) { + throw buffer_too_small_error("Ciphertext buffer too small"); + } + + std::size_t computed_size = 0; + + VERIFY_CMOX_CALL(cmox_aead_encrypt(CMOX_AESFAST_GCMFAST_ENC_ALGO, + pt.data(), + pt.size(), + tag_size, + key.data(), + key.size(), + nonce.data(), + nonce.size(), + aad.data(), + aad.size(), + ct.data(), + &computed_size), + CMOX_CIPHER_SUCCESS); + + return ct.subspan(0, computed_size); +} + +output_bytes +seal(CipherSuite suite, + input_bytes key, + input_bytes nonce, + output_bytes ct, + input_bytes aad, + input_bytes pt) +{ + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: { + throw unsupported_ciphersuite_error(); + } + + case CipherSuite::AES_GCM_128_SHA256: + case CipherSuite::AES_GCM_256_SHA512: { + return seal_aead(suite, key, nonce, ct, aad, pt); + } + + default: + throw unsupported_ciphersuite_error(); + } + + throw unsupported_ciphersuite_error(); +} + +static output_bytes +open_aead(CipherSuite suite, + input_bytes key, + input_bytes nonce, + output_bytes pt, + input_bytes aad, + input_bytes ct) +{ + auto tag_size = cipher_overhead(suite); + if (ct.size() < tag_size) { + throw buffer_too_small_error("Ciphertext buffer too small"); + } + + std::size_t computed_size = 0; + + VERIFY_CMOX_CALL(cmox_aead_decrypt(CMOX_AESFAST_GCMFAST_DEC_ALGO, + ct.data(), + ct.size(), + tag_size, + key.data(), + key.size(), + nonce.data(), + nonce.size(), + aad.data(), + aad.size(), + pt.data(), + &computed_size), + CMOX_CIPHER_AUTH_SUCCESS); + + return pt.subspan(0, computed_size); +} + +output_bytes +open(CipherSuite suite, + input_bytes key, + input_bytes nonce, + output_bytes pt, + input_bytes aad, + input_bytes ct) +{ + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: { + throw unsupported_ciphersuite_error(); + // return open_ctr(suite, key, nonce, pt, aad, ct); + } + + case CipherSuite::AES_GCM_128_SHA256: + case CipherSuite::AES_GCM_256_SHA512: { + return open_aead(suite, key, nonce, pt, aad, ct); + } + default: + throw unsupported_ciphersuite_error(); + } + + throw unsupported_ciphersuite_error(); +} + +} // namespace sframe + +#endif diff --git a/src/sframe.cpp b/src/sframe.cpp index 7616bc1..6c8c988 100644 --- a/src/sframe.cpp +++ b/src/sframe.cpp @@ -71,7 +71,11 @@ KeyRecord::from_base_key(CipherSuite suite, auto key_size = cipher_key_size(suite); auto nonce_size = cipher_nonce_size(suite); +#ifdef STM32 + const auto empty_byte_string = owned_bytes<1>(0); +#else const auto empty_byte_string = owned_bytes<0>(); +#endif const auto key_label = sframe_key_label(suite, key_id); const auto salt_label = sframe_salt_label(suite, key_id); From 0a27ed5369320c26228fe66a241dddf9774cbfcc Mon Sep 17 00:00:00 2001 From: trigaux Date: Thu, 29 May 2025 10:40:24 -0400 Subject: [PATCH 3/7] Fix and improve stm32 crypto library find. --- CMakeLists.txt | 15 +++++++----- cmake/FindSTM32Cryptographic.cmake | 38 +++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c7ad73..317bfff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,24 +95,27 @@ elseif(${CRYPTO} STREQUAL "BORINGSSL") elseif(${CRYPTO} MATCHES "STM32") message(STATUS "Configuring with STM32 Crypto") if(${CRYPTO} STREQUAL "STM32_CM0_CM0PLUS") - set(CRYPTO_LIB STM32Cryptographic_CM0_CM0PLUS) + set(STM32_CRYPTO_LIB CM0_CM0PLUS) elseif(${CRYPTO} STREQUAL "STM32_CM3") - set(CRYPTO_LIB STM32Cryptographic_CM3) + set(STM32_CRYPTO_LIB CM3) elseif(${CRYPTO} STREQUAL "STM32_CM33") - set(CRYPTO_LIB STM32Cryptographic_CM33) + set(STM32_CRYPTO_LIB CM33) elseif(${CRYPTO} STREQUAL "STM32_CM4") - set(CRYPTO_LIB STM32Cryptographic_CM4) + set(STM32_CRYPTO_LIB CM4) elseif(${CRYPTO} STREQUAL "STM32_CM7") - set(CRYPTO_LIB STM32Cryptographic_CM7) + set(STM32_CRYPTO_LIB CM7) else() message(FATAL_ERROR "Please select a specific STM32 crypto back-end (STM32_CM0_CM0PLUS, STM32_CM3, STM32_CM33, STM32_CM4, STM32_CM7) [${CRYPTO}]") endif() + message(STATUS "Crypto component=${STM32_CRYPTO_LIB}") + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) - find_package(STM32Cryptographic REQUIRED) + find_package(STM32Cryptographic COMPONENTS ${STM32_CRYPTO_LIB} REQUIRED) add_compile_definitions(STM32) set(CRYPTO_INCLUDE_DIR ${STM32Cryptographic_INCLUDE_DIR}) + set(CRYPTO_LIB ${STM32Cryptographic_LIBRARIES}) else() message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32) [${CRYPTO}]") endif() diff --git a/cmake/FindSTM32Cryptographic.cmake b/cmake/FindSTM32Cryptographic.cmake index 9886968..fdb38b0 100644 --- a/cmake/FindSTM32Cryptographic.cmake +++ b/cmake/FindSTM32Cryptographic.cmake @@ -1,6 +1,17 @@ set(PACKAGE_NAME "STM32Cryptographic") set(LIBRARY_NAME "STM32Cryptographic") +list(LENGTH ${PACKAGE_NAME}_FIND_COMPONENTS components_length) +if (components_length EQUAL 0) + message(FATAL_ERROR "STM32 Crypto requires specific component(s) be requested (CM0_CM0PLUS, CM3, CM33, CM4, CM7)") +endif() + +list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM0_CM0PLUS" cm0_cm0plus_requested) +list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM3" cm3_requested) +list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM33" cm33_requested) +list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM4" cm4_requested) +list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM7" cm7_requested) + # Locate the include directory find_path( STM32Cryptographic_INCLUDE_DIR @@ -36,15 +47,30 @@ function(find_stm32_crypto_library LIBRARY_NAME) message(STATUS "Found library: ${LIBRARY_NAME} at ${${LIBRARY_NAME}}") endif() - set(STM32Cryptographic_LIBRARY "${STM32Cryptographic_LIBRARY} ${STM32_CRYPTO_LIBRARY}" PARENT_SCOPE) + set(STM32Cryptographic_LIBRARY "${STM32Cryptographic_LIBRARY};${${LIBRARY_NAME}}" PARENT_SCOPE) endfunction() # Locate the libraries -find_stm32_crypto_library(STM32Cryptographic_CM0_CM0PLUS) -find_stm32_crypto_library(STM32Cryptographic_CM3) -find_stm32_crypto_library(STM32Cryptographic_CM33) -find_stm32_crypto_library(STM32Cryptographic_CM4) -find_stm32_crypto_library(STM32Cryptographic_CM7) +if (cm0_cm0plus_requested GREATER -1) + message(STATUS "Requested crypto library for CM0_CM0PLUS cortex, searching...") + find_stm32_crypto_library(STM32Cryptographic_CM0_CM0PLUS) +endif() +if (cm3_requested GREATER -1) + message(STATUS "Requested crypto library for CM3 cortex, searching...") + find_stm32_crypto_library(STM32Cryptographic_CM3) +endif() +if (cm33_requested GREATER -1) + message(STATUS "Requested crypto library for CM33 cortex, searching...") + find_stm32_crypto_library(STM32Cryptographic_CM33) +endif() +if (cm4_requested GREATER -1) + message(STATUS "Requested crypto library for CM4 cortex, searching...") + find_stm32_crypto_library(STM32Cryptographic_CM4) +endif() +if (cm7_requested GREATER -1) + message(STATUS "Requested crypto library for CM7 cortex, searching...") + find_stm32_crypto_library(STM32Cryptographic_CM7) +endif() # Set the STM32Cryptographic_FOUND variable include(FindPackageHandleStandardArgs) From cb7116cbac3ac67b011749d8bef68cfac8fed628 Mon Sep 17 00:00:00 2001 From: trigaux Date: Thu, 29 May 2025 10:44:17 -0400 Subject: [PATCH 4/7] Remove extra message and improve others. --- CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 317bfff..f5060eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,8 +108,6 @@ elseif(${CRYPTO} MATCHES "STM32") message(FATAL_ERROR "Please select a specific STM32 crypto back-end (STM32_CM0_CM0PLUS, STM32_CM3, STM32_CM33, STM32_CM4, STM32_CM7) [${CRYPTO}]") endif() - message(STATUS "Crypto component=${STM32_CRYPTO_LIB}") - list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) find_package(STM32Cryptographic COMPONENTS ${STM32_CRYPTO_LIB} REQUIRED) @@ -117,7 +115,7 @@ elseif(${CRYPTO} MATCHES "STM32") set(CRYPTO_INCLUDE_DIR ${STM32Cryptographic_INCLUDE_DIR}) set(CRYPTO_LIB ${STM32Cryptographic_LIBRARIES}) else() - message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32) [${CRYPTO}]") + message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32_CM0_CM0PLUS, STM32_CM3, STM32_CM33, STM32_CM4, STM32_CM7) [${CRYPTO}]") endif() From cdec59ca6de55479edb14b0b714d74a27c108862 Mon Sep 17 00:00:00 2001 From: trigaux Date: Thu, 29 May 2025 14:06:09 -0400 Subject: [PATCH 5/7] Reduce STM32 complexity and allow app to provide stm32 crypto lib. --- CMakeLists.txt | 27 ++------ cmake/FindSTM32Cryptographic.cmake | 98 ------------------------------ 2 files changed, 4 insertions(+), 121 deletions(-) delete mode 100644 cmake/FindSTM32Cryptographic.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f5060eb..7e701f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,30 +92,12 @@ elseif(${CRYPTO} STREQUAL "BORINGSSL") find_package(OpenSSL REQUIRED) add_compile_definitions(BORINGSSL) set(CRYPTO_LIB OpenSSL::Crypto) -elseif(${CRYPTO} MATCHES "STM32") - message(STATUS "Configuring with STM32 Crypto") - if(${CRYPTO} STREQUAL "STM32_CM0_CM0PLUS") - set(STM32_CRYPTO_LIB CM0_CM0PLUS) - elseif(${CRYPTO} STREQUAL "STM32_CM3") - set(STM32_CRYPTO_LIB CM3) - elseif(${CRYPTO} STREQUAL "STM32_CM33") - set(STM32_CRYPTO_LIB CM33) - elseif(${CRYPTO} STREQUAL "STM32_CM4") - set(STM32_CRYPTO_LIB CM4) - elseif(${CRYPTO} STREQUAL "STM32_CM7") - set(STM32_CRYPTO_LIB CM7) - else() - message(FATAL_ERROR "Please select a specific STM32 crypto back-end (STM32_CM0_CM0PLUS, STM32_CM3, STM32_CM33, STM32_CM4, STM32_CM7) [${CRYPTO}]") - endif() - - list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) - find_package(STM32Cryptographic COMPONENTS ${STM32_CRYPTO_LIB} REQUIRED) - +elseif(${CRYPTO} STREQUAL "STM32") + find_package(STM32Cryptographic COMPONENTS ${STM32_CORTEX} REQUIRED) add_compile_definitions(STM32) - set(CRYPTO_INCLUDE_DIR ${STM32Cryptographic_INCLUDE_DIR}) - set(CRYPTO_LIB ${STM32Cryptographic_LIBRARIES}) + set(CRYPTO_LIB STM32Cryptographic) else() - message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32_CM0_CM0PLUS, STM32_CM3, STM32_CM33, STM32_CM4, STM32_CM7) [${CRYPTO}]") + message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32) [${CRYPTO}]") endif() @@ -136,7 +118,6 @@ target_include_directories(${LIB_NAME} $ $ $ - ${CRYPTO_INCLUDE_DIR} ) ### diff --git a/cmake/FindSTM32Cryptographic.cmake b/cmake/FindSTM32Cryptographic.cmake deleted file mode 100644 index fdb38b0..0000000 --- a/cmake/FindSTM32Cryptographic.cmake +++ /dev/null @@ -1,98 +0,0 @@ -set(PACKAGE_NAME "STM32Cryptographic") -set(LIBRARY_NAME "STM32Cryptographic") - -list(LENGTH ${PACKAGE_NAME}_FIND_COMPONENTS components_length) -if (components_length EQUAL 0) - message(FATAL_ERROR "STM32 Crypto requires specific component(s) be requested (CM0_CM0PLUS, CM3, CM33, CM4, CM7)") -endif() - -list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM0_CM0PLUS" cm0_cm0plus_requested) -list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM3" cm3_requested) -list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM33" cm33_requested) -list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM4" cm4_requested) -list(FIND ${PACKAGE_NAME}_FIND_COMPONENTS "CM7" cm7_requested) - -# Locate the include directory -find_path( - STM32Cryptographic_INCLUDE_DIR - "cmox_crypto.h" - PATHS - ${STM32Cryptographic_ROOT_DIR} - /usr/local/include - /usr/include - PATH_SUFFIXES include -) - -if(NOT STM32Cryptographic_INCLUDE_DIR) - message(WARNING "Could not find include dir for ${PACKAGE_NAME}") -else() - message(STATUS "Found include dir: ${STM32Cryptographic_INCLUDE_DIR}") -endif() - -function(find_stm32_crypto_library LIBRARY_NAME) - find_library( - ${LIBRARY_NAME} - NAMES ${LIBRARY_NAME} - PATHS - ${STM32Cryptographic_ROOT_DIR} - /usr/local/lib - /usr/lib - PATH_SUFFIXES lib - NO_DEFAULT_PATH - ) - - if(NOT ${LIBRARY_NAME}) - message(WARNING "Could not find library: ${LIBRARY_NAME}") - else() - message(STATUS "Found library: ${LIBRARY_NAME} at ${${LIBRARY_NAME}}") - endif() - - set(STM32Cryptographic_LIBRARY "${STM32Cryptographic_LIBRARY};${${LIBRARY_NAME}}" PARENT_SCOPE) -endfunction() - -# Locate the libraries -if (cm0_cm0plus_requested GREATER -1) - message(STATUS "Requested crypto library for CM0_CM0PLUS cortex, searching...") - find_stm32_crypto_library(STM32Cryptographic_CM0_CM0PLUS) -endif() -if (cm3_requested GREATER -1) - message(STATUS "Requested crypto library for CM3 cortex, searching...") - find_stm32_crypto_library(STM32Cryptographic_CM3) -endif() -if (cm33_requested GREATER -1) - message(STATUS "Requested crypto library for CM33 cortex, searching...") - find_stm32_crypto_library(STM32Cryptographic_CM33) -endif() -if (cm4_requested GREATER -1) - message(STATUS "Requested crypto library for CM4 cortex, searching...") - find_stm32_crypto_library(STM32Cryptographic_CM4) -endif() -if (cm7_requested GREATER -1) - message(STATUS "Requested crypto library for CM7 cortex, searching...") - find_stm32_crypto_library(STM32Cryptographic_CM7) -endif() - -# Set the STM32Cryptographic_FOUND variable -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(${PACKAGE_NAME} - REQUIRED_VARS - STM32Cryptographic_INCLUDE_DIR - STM32Cryptographic_LIBRARY -) - -# Set output variables -if(${PACKAGE_NAME}_FOUND) - set(STM32Cryptographic_INCLUDE_DIRS ${STM32Cryptographic_INCLUDE_DIR}) - set(STM32Cryptographic_LIBRARIES ${STM32Cryptographic_LIBRARY}) -else() - set(STM32Cryptographic_INCLUDE_DIRS "") - set(STM32Cryptographic_LIBRARIES "") -endif() - -# Set compile definitions (if any) -# list(APPEND STM32Cryptographic_DEFINITIONS "-DSTM32Cryptographic_ENABLE_FEATURE") - -mark_as_advanced( - STM32Cryptographic_INCLUDE_DIR - STM32Cryptographic_LIBRARY -) From c48d46c90bb9954eb889a6aad864a1f90b3f6354 Mon Sep 17 00:00:00 2001 From: trigaux Date: Fri, 30 May 2025 15:23:28 -0400 Subject: [PATCH 6/7] Cleanup. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e701f4..5c63c37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,8 +93,9 @@ elseif(${CRYPTO} STREQUAL "BORINGSSL") add_compile_definitions(BORINGSSL) set(CRYPTO_LIB OpenSSL::Crypto) elseif(${CRYPTO} STREQUAL "STM32") - find_package(STM32Cryptographic COMPONENTS ${STM32_CORTEX} REQUIRED) + message(STATUS "Configuring with STM32") add_compile_definitions(STM32) + add_compile_definitions(NO_ALLOC) set(CRYPTO_LIB STM32Cryptographic) else() message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32) [${CRYPTO}]") From 9df6dda186a138820afecefa3a6d3dac84d4c5ac Mon Sep 17 00:00:00 2001 From: trigaux Date: Mon, 2 Jun 2025 10:09:51 -0400 Subject: [PATCH 7/7] Address review comments. --- CMakeLists.txt | 4 +- include/sframe/sframe.h | 2 + src/crypto_boringssl.cpp | 10 +++ src/crypto_openssl11.cpp | 10 +++ src/crypto_openssl3.cpp | 10 +++ src/crypto_stm32.cpp | 144 ++++++++++++++++++--------------------- src/sframe.cpp | 4 -- 7 files changed, 99 insertions(+), 85 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c63c37..367017e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,8 +94,8 @@ elseif(${CRYPTO} STREQUAL "BORINGSSL") set(CRYPTO_LIB OpenSSL::Crypto) elseif(${CRYPTO} STREQUAL "STM32") message(STATUS "Configuring with STM32") - add_compile_definitions(STM32) - add_compile_definitions(NO_ALLOC) + find_package(STM32Cryptographic REQUIRED) + add_compile_definitions(STM32 NO_ALLOC) set(CRYPTO_LIB STM32Cryptographic) else() message(FATAL_ERROR "Please select a crypto back-end (OPENSSL_1_1, OPENSSL_3, BORINGSSL, STM32) [${CRYPTO}]") diff --git a/include/sframe/sframe.h b/include/sframe/sframe.h index dcceb72..5179fae 100644 --- a/include/sframe/sframe.h +++ b/include/sframe/sframe.h @@ -29,6 +29,8 @@ namespace SFRAME_NAMESPACE { struct crypto_error : std::runtime_error { crypto_error(); + crypto_error(std::size_t err_code); + crypto_error(const std::string& err_str); }; struct unsupported_ciphersuite_error : std::runtime_error diff --git a/src/crypto_boringssl.cpp b/src/crypto_boringssl.cpp index 4bb6ba3..b3404f3 100644 --- a/src/crypto_boringssl.cpp +++ b/src/crypto_boringssl.cpp @@ -20,6 +20,16 @@ crypto_error::crypto_error() { } +crypto_error::crypto_error(std::size_t err_code) + : std::runtime_error(ERR_error_string(err_code, nullptr)) +{ +} + +crypto_error::crypto_error(const std::string& err_str) + : std::runtime_error(err_str) +{ +} + static const EVP_MD* openssl_digest_type(CipherSuite suite) { diff --git a/src/crypto_openssl11.cpp b/src/crypto_openssl11.cpp index d68e841..4373086 100644 --- a/src/crypto_openssl11.cpp +++ b/src/crypto_openssl11.cpp @@ -26,6 +26,16 @@ crypto_error::crypto_error() { } +crypto_error::crypto_error(std::size_t err_code) + : std::runtime_error(ERR_error_string(err_code, nullptr)) +{ +} + +crypto_error::crypto_error(const std::string& err_str) + : std::runtime_error(err_str) +{ +} + static const EVP_MD* openssl_digest_type(CipherSuite suite) { diff --git a/src/crypto_openssl3.cpp b/src/crypto_openssl3.cpp index d1bda30..468a558 100644 --- a/src/crypto_openssl3.cpp +++ b/src/crypto_openssl3.cpp @@ -20,6 +20,16 @@ crypto_error::crypto_error() { } +crypto_error::crypto_error(std::size_t err_code) + : std::runtime_error(ERR_error_string(err_code, nullptr)) +{ +} + +crypto_error::crypto_error(const std::string& err_str) + : std::runtime_error(err_str) +{ +} + static const EVP_CIPHER* openssl_cipher(CipherSuite suite) { diff --git a/src/crypto_stm32.cpp b/src/crypto_stm32.cpp index e7eb383..193c0ce 100644 --- a/src/crypto_stm32.cpp +++ b/src/crypto_stm32.cpp @@ -14,10 +14,9 @@ namespace sframe { #define VERIFY_CMOX_CALL(func, success_code) \ do { \ - auto retval = func; \ + const auto retval = func; \ if (retval != success_code) { \ - cmox_error = retval; \ - throw crypto_error(); \ + throw crypto_error(retval); \ } \ } while (0) @@ -25,61 +24,67 @@ namespace sframe { /// Convert between native identifiers / errors and cmox ones /// -std::optional cmox_error; - crypto_error::crypto_error() + : std::runtime_error("unknown CMOX crypto error") +{ +} + +crypto_error::crypto_error(std::size_t err_code) : std::runtime_error( - cmox_error.has_value() - ? "CMOX crypto error (error=" + std::to_string(cmox_error.value()) + ")" - : "unknown CMOX crypto error") + "CMOX crypto error (error_code=" + std::to_string(err_code) + ")") { } -extern "C" +crypto_error::crypto_error(const std::string& err_str) + : std::runtime_error("CMOX crypto error (error=" + err_str + ")") { - static cmox_mac_algo_t cmox_hmac_algo(CipherSuite suite) - { - switch (suite) { - case CipherSuite::AES_128_CTR_HMAC_SHA256_80: - case CipherSuite::AES_128_CTR_HMAC_SHA256_64: - case CipherSuite::AES_128_CTR_HMAC_SHA256_32: - case CipherSuite::AES_GCM_128_SHA256: - return CMOX_HMAC_SHA256_ALGO; - case CipherSuite::AES_GCM_256_SHA512: - return CMOX_HMAC_SHA512_ALGO; - default: - throw unsupported_ciphersuite_error(); - } +} + +static cmox_mac_algo_t +cmox_hmac_algo(CipherSuite suite) +{ + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: + case CipherSuite::AES_GCM_128_SHA256: + return CMOX_HMAC_SHA256_ALGO; + case CipherSuite::AES_GCM_256_SHA512: + return CMOX_HMAC_SHA512_ALGO; + default: + throw unsupported_ciphersuite_error(); } +} - static cmox_hmac_impl_t cmox_hmac_impl(CipherSuite suite) - { - switch (suite) { - case CipherSuite::AES_128_CTR_HMAC_SHA256_80: - case CipherSuite::AES_128_CTR_HMAC_SHA256_64: - case CipherSuite::AES_128_CTR_HMAC_SHA256_32: - case CipherSuite::AES_GCM_128_SHA256: - return CMOX_HMAC_SHA256; - case CipherSuite::AES_GCM_256_SHA512: - return CMOX_HMAC_SHA512; - default: - throw unsupported_ciphersuite_error(); - } +static cmox_hmac_impl_t +cmox_hmac_impl(CipherSuite suite) +{ + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: + case CipherSuite::AES_GCM_128_SHA256: + return CMOX_HMAC_SHA256; + case CipherSuite::AES_GCM_256_SHA512: + return CMOX_HMAC_SHA512; + default: + throw unsupported_ciphersuite_error(); } +} - static std::size_t cmox_hmac_size(CipherSuite suite) - { - switch (suite) { - case CipherSuite::AES_128_CTR_HMAC_SHA256_80: - case CipherSuite::AES_128_CTR_HMAC_SHA256_64: - case CipherSuite::AES_128_CTR_HMAC_SHA256_32: - case CipherSuite::AES_GCM_128_SHA256: - return CMOX_SHA256_SIZE; - case CipherSuite::AES_GCM_256_SHA512: - return CMOX_SHA512_SIZE; - default: - throw unsupported_ciphersuite_error(); - } +static std::size_t +cmox_hmac_size(CipherSuite suite) +{ + switch (suite) { + case CipherSuite::AES_128_CTR_HMAC_SHA256_80: + case CipherSuite::AES_128_CTR_HMAC_SHA256_64: + case CipherSuite::AES_128_CTR_HMAC_SHA256_32: + case CipherSuite::AES_GCM_128_SHA256: + return CMOX_SHA256_SIZE; + case CipherSuite::AES_GCM_256_SHA512: + return CMOX_SHA512_SIZE; + default: + throw unsupported_ciphersuite_error(); } } @@ -115,51 +120,38 @@ hkdf_expand(CipherSuite suite, input_bytes prk, input_bytes info, size_t size) cmox_mac_handle_t* mac_ctx; const auto digest_size = cmox_hmac_size(suite); - auto N = static_cast(size / digest_size); - if ((N * digest_size) < size) { - N++; - } + auto N = static_cast((size + digest_size - 1) / digest_size); mac_ctx = cmox_hmac_construct(&Hmac_Ctx, cmox_hmac_impl(suite)); if (mac_ctx == nullptr) { throw crypto_error(); } - owned_bytes computed_hash(size); + owned_bytes computed_hash(digest_size); owned_bytes out(size); uint32_t index = 0; for (uint8_t i = 1; i <= N; i++) { - VERIFY_CMOX_CALL(cmox_mac_init(mac_ctx), CMOX_MAC_SUCCESS); + computed_hash.resize(0); - if (i == N) { - VERIFY_CMOX_CALL(cmox_mac_setTagLen(mac_ctx, size - index), - CMOX_MAC_SUCCESS); - } + VERIFY_CMOX_CALL(cmox_mac_init(mac_ctx), CMOX_MAC_SUCCESS); VERIFY_CMOX_CALL(cmox_mac_setKey(mac_ctx, prk.data(), prk.size()), CMOX_MAC_SUCCESS); - if (i > 1) { - VERIFY_CMOX_CALL( - cmox_mac_append(mac_ctx, computed_hash.data(), digest_size), - CMOX_MAC_SUCCESS); - } - VERIFY_CMOX_CALL(cmox_mac_append(mac_ctx, info.data(), info.size()), CMOX_MAC_SUCCESS); + VERIFY_CMOX_CALL(cmox_mac_append(mac_ctx, &i, 1), CMOX_MAC_SUCCESS); + + computed_hash.resize(digest_size); VERIFY_CMOX_CALL( cmox_mac_generateTag(mac_ctx, computed_hash.data(), nullptr), CMOX_MAC_SUCCESS); - if (i == N) { - memcpy(&out[index], computed_hash.data(), size - index); - index = size; - } else { - memcpy(&out[index], computed_hash.data(), digest_size); - index += digest_size; - } + const auto to_copy = (i == N) ? size - index : digest_size; + std::memcpy(&out[index], computed_hash.data(), to_copy); + index += to_copy; } VERIFY_CMOX_CALL(cmox_mac_cleanup(mac_ctx), CMOX_MAC_SUCCESS); @@ -181,7 +173,6 @@ seal_aead(CipherSuite suite, } std::size_t computed_size = 0; - VERIFY_CMOX_CALL(cmox_aead_encrypt(CMOX_AESFAST_GCMFAST_ENC_ALGO, pt.data(), pt.size(), @@ -211,6 +202,7 @@ seal(CipherSuite suite, case CipherSuite::AES_128_CTR_HMAC_SHA256_80: case CipherSuite::AES_128_CTR_HMAC_SHA256_64: case CipherSuite::AES_128_CTR_HMAC_SHA256_32: { + // TODO(GhostofCookie): return seal_ctr(suite, key, nonce, ct, aad, pt); throw unsupported_ciphersuite_error(); } @@ -218,9 +210,6 @@ seal(CipherSuite suite, case CipherSuite::AES_GCM_256_SHA512: { return seal_aead(suite, key, nonce, ct, aad, pt); } - - default: - throw unsupported_ciphersuite_error(); } throw unsupported_ciphersuite_error(); @@ -240,7 +229,6 @@ open_aead(CipherSuite suite, } std::size_t computed_size = 0; - VERIFY_CMOX_CALL(cmox_aead_decrypt(CMOX_AESFAST_GCMFAST_DEC_ALGO, ct.data(), ct.size(), @@ -270,16 +258,14 @@ open(CipherSuite suite, case CipherSuite::AES_128_CTR_HMAC_SHA256_80: case CipherSuite::AES_128_CTR_HMAC_SHA256_64: case CipherSuite::AES_128_CTR_HMAC_SHA256_32: { + // TODO(GhostofCookie): return open_ctr(suite, key, nonce, pt, aad, ct); throw unsupported_ciphersuite_error(); - // return open_ctr(suite, key, nonce, pt, aad, ct); } case CipherSuite::AES_GCM_128_SHA256: case CipherSuite::AES_GCM_256_SHA512: { return open_aead(suite, key, nonce, pt, aad, ct); } - default: - throw unsupported_ciphersuite_error(); } throw unsupported_ciphersuite_error(); diff --git a/src/sframe.cpp b/src/sframe.cpp index 6c8c988..2db60e9 100644 --- a/src/sframe.cpp +++ b/src/sframe.cpp @@ -71,11 +71,7 @@ KeyRecord::from_base_key(CipherSuite suite, auto key_size = cipher_key_size(suite); auto nonce_size = cipher_nonce_size(suite); -#ifdef STM32 const auto empty_byte_string = owned_bytes<1>(0); -#else - const auto empty_byte_string = owned_bytes<0>(); -#endif const auto key_label = sframe_key_label(suite, key_id); const auto salt_label = sframe_salt_label(suite, key_id);