Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion .github/workflows/stm32-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ jobs:
renode_platform: stm32f4.repl
avm_address: "0x08060000"
skip_i2c_test: true
# No RNG peripheral on F411, so the firmware has no crypto NIFs
# (mbedTLS is excluded by STM32_HAS_RNG in CMake).
skip_crypto_test: true
- device: stm32f429zit6
max_size: 524288
- device: stm32h743vit6
Expand Down Expand Up @@ -100,6 +103,9 @@ jobs:
# register layout) but the L5 HAL uses the newer I2C registers
# (TIMINGR, ISR, etc.), causing a complete register mismatch.
skip_i2c_test: true
# 512 KB flash with avm_address=0x08060000 leaves only 128 KB,
# but the crypto AVM is 207 KB and gets truncated.
skip_crypto_test: true
- device: stm32f207zgt6
max_size: 524288
- device: stm32u375rgt6
Expand All @@ -108,6 +114,10 @@ jobs:
max_size: 393216
renode_platform: stm32g0b1.repl
avm_address: "0x08060000"
# No RNG peripheral on G0B1 (only G041/G061/G081/G0C1 have one),
# so the firmware has no crypto NIFs (mbedTLS is excluded by
# STM32_HAS_RNG in CMake).
skip_crypto_test: true

steps:
- uses: erlef/setup-beam@v1
Expand Down Expand Up @@ -185,7 +195,7 @@ jobs:
mkdir build-host
cd build-host
cmake .. -G Ninja
cmake --build . -t stm32_boot_test stm32_gpio_test stm32_i2c_test stm32_spi_test
cmake --build . -t stm32_boot_test stm32_gpio_test stm32_i2c_test stm32_spi_test stm32_crypto_test

- name: Install Renode
if: matrix.renode_platform
Expand Down Expand Up @@ -256,3 +266,21 @@ jobs:
--variable AVM:@$PWD/build-host/src/platforms/stm32/tests/test_erl_sources/stm32_spi_test.avm \
--variable AVM_ADDRESS:${{ matrix.avm_address }} \
--variable PLATFORM:$PLATFORM

- name: Run Renode crypto test
# Devices without RNG hardware (F411 / G0) don't ship mbedTLS at all;
# L562 has only 512 KB of flash and the 207 KB crypto AVM is truncated
# at AVM_ADDRESS=0x08060000, which kills kernel boot.
if: matrix.renode_platform && !matrix.skip_crypto_test
run: |
LOCAL_REPL="src/platforms/stm32/tests/renode/${{ matrix.renode_platform }}"
if [ -f "$LOCAL_REPL" ]; then
PLATFORM="@$PWD/$LOCAL_REPL"
else
PLATFORM="@platforms/cpus/${{ matrix.renode_platform }}"
fi
renode-test src/platforms/stm32/tests/renode/stm32_crypto_test.robot \
--variable ELF:@$PWD/src/platforms/stm32/build/AtomVM-${{ matrix.device }}.elf \
--variable AVM:@$PWD/build-host/src/platforms/stm32/tests/test_erl_sources/stm32_crypto_test.avm \
--variable AVM_ADDRESS:${{ matrix.avm_address }} \
--variable PLATFORM:$PLATFORM
13 changes: 13 additions & 0 deletions src/platforms/stm32/cmake/stm32_device.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,22 @@ elseif (STM32_FAMILY_SHORT STREQUAL "wb")
} >RAM_SHARED AT> FLASH]=])
endif()

# Per ST AN4230 Rev 13, Table 2:
# https://www.st.com/resource/en/application_note/dm00073853-stm32-microcontroller-random-number-generation-validation-using-the-nist-statistical-test-suite-stmicroelectronics.pdf
if (DEVICE_LOWER MATCHES "^stm32(f2|f7|g4|h5|h7|l4|u3|u5|wb)")
set(STM32_HAS_RNG TRUE)
elseif (DEVICE_LOWER MATCHES "^stm32f4(05|15|07|17|10|12|13|23|27|37|29|39|69|79)")
set(STM32_HAS_RNG TRUE)
elseif (DEVICE_LOWER MATCHES "^stm32g0(41|61|81|c1)")
set(STM32_HAS_RNG TRUE)
else()
set(STM32_HAS_RNG FALSE)
endif()

message("-----------Device Info-----------")
message(STATUS "Device : ${DEVICE}")
message(STATUS "Family : ${STM32_FAMILY}")
message(STATUS "CPU : ${STM32_CPU}")
message(STATUS "FPU : ${STM32_FPU}")
message(STATUS "Arch Flags : ${_arch_flags_str}")
message(STATUS "Has RNG : ${STM32_HAS_RNG}")
5 changes: 5 additions & 0 deletions src/platforms/stm32/cmake/stm32_hal_conf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extern "C" {
#define HAL_DMA_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
#define HAL_SPI_MODULE_ENABLED
#define HAL_RNG_MODULE_ENABLED
#if defined(STM32H5XX) || defined(STM32L5XX) || defined(STM32U3XX) || defined(STM32U5XX)
#define HAL_ICACHE_MODULE_ENABLED
#endif
Expand Down Expand Up @@ -204,6 +205,10 @@ extern "C" {
#include "@STM32_FAMILY@_hal_spi.h"
#endif

#ifdef HAL_RNG_MODULE_ENABLED
#include "@STM32_FAMILY@_hal_rng.h"
#endif

#ifdef HAL_ICACHE_MODULE_ENABLED
#include "@STM32_FAMILY@_hal_icache.h"
#endif
Expand Down
7 changes: 7 additions & 0 deletions src/platforms/stm32/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ if (EXISTS "${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_spi_ex.c")
list(APPEND HAL_SOURCES ${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_spi_ex.c)
endif()

if (EXISTS "${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_rng.c")
list(APPEND HAL_SOURCES ${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_rng.c)
endif()
if (EXISTS "${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_rng_ex.c")
list(APPEND HAL_SOURCES ${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_rng_ex.c)
endif()

# ICACHE HAL for families that have it (U5, H5)
if (EXISTS "${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_icache.c")
list(APPEND HAL_SOURCES ${HAL_DRIVER_SRC_DIR}/${STM32_FAMILY}_hal_icache.c)
Expand Down
34 changes: 34 additions & 0 deletions src/platforms/stm32/src/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@
cmake_minimum_required (VERSION 3.13)
project (libAtomVMPlatformSTM32)

if (STM32_HAS_RNG)
# Skip mbedTLS programs/tests that pull in POSIX-only code (sockets,
# stdio, etc.) and won't link on bare metal anyway.
set(ENABLE_PROGRAMS OFF CACHE BOOL "" FORCE)
set(ENABLE_TESTING OFF CACHE BOOL "" FORCE)

include(FetchMbedTLS)

# Apply our user config only to the mbedtls targets, not to the rest
# of the firmware.
set(_mbedtls_stm32_cfg "MBEDTLS_USER_CONFIG_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_stm32_user_config.h\"")
foreach(_tgt mbedcrypto mbedtls mbedx509)
if(TARGET ${_tgt})
target_compile_definitions(${_tgt} PRIVATE "${_mbedtls_stm32_cfg}")
endif()
endforeach()
unset(_mbedtls_stm32_cfg)
unset(_tgt)
endif()

set(HEADER_FILES
avm_devcfg.h
avm_log.h
Expand All @@ -41,6 +61,14 @@ set(SOURCE_FILES
../../../../libAtomVM/portnifloader.c
)

if (STM32_HAS_RNG)
list(APPEND HEADER_FILES
../../../../libAtomVM/otp_crypto.h)
list(APPEND SOURCE_FILES
../../../../libAtomVM/otp_crypto.c
otp_crypto_platform.c)
endif()

set(
PLATFORM_LIB_SUFFIX
${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}
Expand All @@ -53,6 +81,12 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif()

target_link_libraries(libAtomVM${PLATFORM_LIB_SUFFIX} PUBLIC libAtomVM)
if (STM32_HAS_RNG)
target_compile_definitions(libAtomVM${PLATFORM_LIB_SUFFIX} PUBLIC ATOMVM_HAS_MBEDTLS)
target_compile_definitions(libAtomVM${PLATFORM_LIB_SUFFIX} PUBLIC
"MBEDTLS_USER_CONFIG_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_stm32_user_config.h\"")
target_link_libraries(libAtomVM${PLATFORM_LIB_SUFFIX} PUBLIC MbedTLS::mbedcrypto)
endif()
target_link_options(libAtomVM${PLATFORM_LIB_SUFFIX} PUBLIC ${LINK_OPTIONS} -Wl,--whole-archive ${CMAKE_CURRENT_BINARY_DIR}/liblibAtomVMGeneric-arm.a -Wl,--no-whole-archive)

# Include HAL/CMSIS headers
Expand Down
67 changes: 67 additions & 0 deletions src/platforms/stm32/src/lib/mbedtls_stm32_user_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* This file is part of AtomVM.
*
* Copyright 2026 Paul Guyot <pguyot@kallisys.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/

#ifndef MBEDTLS_STM32_USER_CONFIG_H
#define MBEDTLS_STM32_USER_CONFIG_H

#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_PLATFORM_MS_TIME_ALT

#undef MBEDTLS_HAVE_TIME_DATE
#undef MBEDTLS_TIMING_C

#undef MBEDTLS_PSA_CRYPTO_C
#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
#undef MBEDTLS_PSA_ITS_FILE_C
#undef MBEDTLS_PSA_CRYPTO_CLIENT
#undef MBEDTLS_PSA_INJECT_ENTROPY
#undef MBEDTLS_LMS_C

#undef MBEDTLS_FS_IO

#undef MBEDTLS_NET_C
#undef MBEDTLS_SSL_TLS_C
#undef MBEDTLS_SSL_CLI_C
#undef MBEDTLS_SSL_SRV_C
#undef MBEDTLS_SSL_SERVER_NAME_INDICATION
#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID
#undef MBEDTLS_SSL_PROTO_DTLS
#undef MBEDTLS_SSL_PROTO_TLS1_2
#undef MBEDTLS_SSL_PROTO_TLS1_3
#undef MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
#undef MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
#undef MBEDTLS_SSL_RENEGOTIATION
#undef MBEDTLS_SSL_TICKET_C
#undef MBEDTLS_SSL_COOKIE_C
#undef MBEDTLS_SSL_CACHE_C
#undef MBEDTLS_X509_USE_C
#undef MBEDTLS_X509_CREATE_C
#undef MBEDTLS_X509_CRT_PARSE_C
#undef MBEDTLS_X509_CRL_PARSE_C
#undef MBEDTLS_X509_CSR_PARSE_C
#undef MBEDTLS_X509_CRT_WRITE_C
#undef MBEDTLS_X509_CSR_WRITE_C
#undef MBEDTLS_PKCS7_C

#undef MBEDTLS_SELF_TEST

#endif /* MBEDTLS_STM32_USER_CONFIG_H */
26 changes: 26 additions & 0 deletions src/platforms/stm32/src/lib/otp_crypto_platform.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* This file is part of AtomVM.
*
* Copyright 2026 by Paul Guyot <pguyot@kallisys.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/

#include <nifs.h>
#include <otp_crypto.h>

#include "stm_sys.h"

REGISTER_NIF_COLLECTION(otp_crypto, NULL, NULL, otp_crypto_nif_get_nif)
10 changes: 5 additions & 5 deletions src/platforms/stm32/src/lib/platform_nifs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <platform_nifs.h>
#include <term.h>

#ifdef ATOMVM_HAS_MBEDTLS
#include <otp_crypto.h>
#endif

// #define ENABLE_TRACE
#include <trace.h>

Expand All @@ -47,9 +51,5 @@ const struct Nif *platform_nifs_get_nif(const char *nifname)
TRACE("Resolved platform nif %s ...\n", nifname);
return &atomvm_platform_nif;
}
const struct Nif *nif = nif_collection_resolve_nif(nifname);
if (nif) {
return nif;
}
return NULL;
return nif_collection_resolve_nif(nifname);
}
12 changes: 12 additions & 0 deletions src/platforms/stm32/src/lib/stm_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@

#include "stm32_hal_platform.h"

#ifdef ATOMVM_HAS_MBEDTLS
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#endif

#define STM32_ATOM globalcontext_make_atom(ctx->global, ATOM_STR("\x5", "stm32"))

/* Define macros for data and instruction barriers for sys_init_icache() */
Expand All @@ -46,6 +51,13 @@ struct LockedPin
struct STM32PlatformData
{
struct ListHead locked_pins;
#ifdef ATOMVM_HAS_MBEDTLS
RNG_HandleTypeDef rng;
mbedtls_entropy_context entropy_ctx;
mbedtls_ctr_drbg_context random_ctx;
bool entropy_is_initialized;
bool random_is_initialized;
#endif
};

void sys_init_icache(void);
Expand Down
Loading
Loading