Skip to content

Commit dab3bd3

Browse files
committed
Add Renode GH Action for STM32H753
This adds bare metal wolfCrypt test with hardware RNG and AES-GCM for STM32H753 using Renode. Renode does not support HASH HAL at this time.
1 parent bbc3a72 commit dab3bd3

File tree

10 files changed

+1213
-0
lines changed

10 files changed

+1213
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
cmake_minimum_required(VERSION 3.18)
2+
project(wolfcrypt_stm32h753 LANGUAGES C ASM)
3+
4+
set(WOLFSSL_ROOT "/opt/wolfssl" CACHE PATH "wolfSSL source")
5+
6+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
7+
enable_language(ASM)
8+
9+
# Include paths for CMSIS device headers and STM32 HAL
10+
# Order matters: CMSIS must come before HAL
11+
include_directories(BEFORE
12+
${CMAKE_SOURCE_DIR}
13+
/opt/CMSIS_5/CMSIS/Core/Include # Core CMSIS (core_cm7.h, etc.) - must be first
14+
/opt/cmsis-device-h7/Include # Device-specific CMSIS (stm32h7xx.h)
15+
/opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc/Legacy
16+
/opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc
17+
)
18+
19+
# STM32 HAL source files (minimal set for CRYP and HASH)
20+
# Note: These files are cloned in the Dockerfile before CMake runs
21+
set(HAL_SRC_DIR /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Src)
22+
23+
# Check if HAL directory exists, then add source files
24+
if(EXISTS ${HAL_SRC_DIR})
25+
set(HAL_SOURCES
26+
${HAL_SRC_DIR}/stm32h7xx_hal.c
27+
${HAL_SRC_DIR}/stm32h7xx_hal_rcc.c
28+
${HAL_SRC_DIR}/stm32h7xx_hal_rcc_ex.c
29+
${HAL_SRC_DIR}/stm32h7xx_hal_cortex.c
30+
${HAL_SRC_DIR}/stm32h7xx_hal_dma.c
31+
${HAL_SRC_DIR}/stm32h7xx_hal_dma_ex.c
32+
${HAL_SRC_DIR}/stm32h7xx_hal_rng.c
33+
# CRYP HAL files enabled for AES_GCM only
34+
${HAL_SRC_DIR}/stm32h7xx_hal_cryp.c
35+
${HAL_SRC_DIR}/stm32h7xx_hal_cryp_ex.c
36+
# HASH HAL files disabled - Renode doesn't implement HASH peripheral
37+
# ${HAL_SRC_DIR}/stm32h7xx_hal_hash.c
38+
# ${HAL_SRC_DIR}/stm32h7xx_hal_hash_ex.c
39+
)
40+
else()
41+
message(WARNING "HAL source directory not found: ${HAL_SRC_DIR}")
42+
set(HAL_SOURCES "")
43+
endif()
44+
45+
# wolfSSL build options
46+
set(WOLFSSL_USER_SETTINGS ON CACHE BOOL "Use user_settings.h")
47+
set(WOLFSSL_CRYPT_TESTS OFF CACHE BOOL "")
48+
set(WOLFSSL_EXAMPLES OFF CACHE BOOL "")
49+
set(BUILD_SHARED_LIBS OFF CACHE BOOL "")
50+
51+
add_subdirectory(${WOLFSSL_ROOT} ${CMAKE_BINARY_DIR}/wolfssl-build EXCLUDE_FROM_ALL)
52+
target_include_directories(wolfssl PRIVATE
53+
/opt/CMSIS_5/CMSIS/Core/Include # Core CMSIS first
54+
/opt/cmsis-device-h7/Include # Device CMSIS
55+
/opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc/Legacy
56+
/opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc
57+
${CMAKE_SOURCE_DIR} # For stm32h7xx_hal_conf.h
58+
)
59+
# Suppress the GENSEED_FORTEST warning (expected for emulation/test builds)
60+
target_compile_options(wolfssl PRIVATE -Wno-cpp)
61+
62+
# wolfSSL STM32 port source file (needed for HASH and CRYPTO hardware acceleration)
63+
set(WOLFSSL_STM32_PORT_SRC ${WOLFSSL_ROOT}/wolfcrypt/src/port/st/stm32.c)
64+
65+
add_executable(wolfcrypt_test.elf
66+
startup_stm32h753.c
67+
main.c
68+
${WOLFSSL_ROOT}/wolfcrypt/test/test.c
69+
${HAL_SOURCES}
70+
${WOLFSSL_STM32_PORT_SRC}
71+
)
72+
73+
target_include_directories(wolfcrypt_test.elf PRIVATE
74+
${CMAKE_SOURCE_DIR}
75+
${WOLFSSL_ROOT}
76+
/opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc
77+
/opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc/Legacy
78+
)
79+
80+
target_compile_definitions(wolfcrypt_test.elf PRIVATE
81+
WOLFSSL_USER_SETTINGS
82+
STM32H753xx
83+
USE_HAL_DRIVER
84+
USE_HAL_CONF # Enable HAL configuration
85+
# NO_AES_CBC is defined in user_settings.h, no need to define it here
86+
)
87+
88+
# HAL source files need the same compile options and must include stdint.h
89+
# Disable all warnings for HAL files (third-party code we don't control)
90+
set_source_files_properties(${HAL_SOURCES} PROPERTIES
91+
COMPILE_FLAGS "-mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Os -include stdint.h -w"
92+
)
93+
94+
target_compile_options(wolfcrypt_test.elf PRIVATE
95+
-mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard
96+
-ffunction-sections -fdata-sections -Os
97+
)
98+
99+
target_link_options(wolfcrypt_test.elf PRIVATE
100+
-T${CMAKE_SOURCE_DIR}/stm32h753.ld
101+
-Wl,--gc-sections
102+
-nostartfiles
103+
-specs=nano.specs
104+
-specs=nosys.specs
105+
)
106+
107+
target_link_libraries(wolfcrypt_test.elf PRIVATE wolfssl m c gcc nosys)
108+
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
LOG=/tmp/wolfcrypt-renode.log
5+
TIMEOUT=300 # Maximum 5 minutes
6+
7+
echo "Running wolfCrypt test in Renode..."
8+
9+
# Try to find Renode binary in common installation locations
10+
# When installed via .deb package, Renode is typically in /usr/bin/renode
11+
RENODE_BIN="${RENODE_BIN:-$(command -v renode 2>/dev/null || true)}"
12+
if [ -z "$RENODE_BIN" ]; then
13+
# Check common installation paths (order matters - check standard locations first)
14+
for path in /usr/bin/renode /usr/local/bin/renode /opt/renode/renode; do
15+
if [ -x "$path" ]; then
16+
RENODE_BIN="$path"
17+
break
18+
fi
19+
done
20+
fi
21+
22+
if [ -z "$RENODE_BIN" ] || [ ! -x "$RENODE_BIN" ]; then
23+
echo "Renode binary not found in image."
24+
echo "Checked paths: /usr/bin/renode, /usr/local/bin/renode, /opt/renode/renode"
25+
echo "PATH: $PATH"
26+
which renode || echo "renode not in PATH"
27+
exit 2
28+
fi
29+
30+
echo "Using Renode binary: $RENODE_BIN"
31+
32+
# Determine Renode root directory (where platforms/ directory is located)
33+
if [ -d "/opt/renode/platforms" ]; then
34+
RENODE_ROOT="/opt/renode"
35+
elif [ -d "/usr/lib/renode/platforms" ]; then
36+
RENODE_ROOT="/usr/lib/renode"
37+
elif [ -d "/usr/share/renode/platforms" ]; then
38+
RENODE_ROOT="/usr/share/renode"
39+
else
40+
# Try to find Renode root by checking where the binary is
41+
RENODE_DIR=$(dirname "$(readlink -f "${RENODE_BIN}" 2>/dev/null || echo "${RENODE_BIN}")")
42+
if [ -d "${RENODE_DIR}/../platforms" ]; then
43+
RENODE_ROOT=$(readlink -f "${RENODE_DIR}/.." 2>/dev/null || echo "${RENODE_DIR}/..")
44+
else
45+
echo "Warning: Could not determine Renode root directory"
46+
RENODE_ROOT=""
47+
fi
48+
fi
49+
50+
# Set RENODE_ROOT environment variable (Renode uses this to find platform files)
51+
if [ -n "$RENODE_ROOT" ]; then
52+
export RENODE_ROOT
53+
echo "Using Renode root: ${RENODE_ROOT}"
54+
# Also create .renode-root file in firmware directory as backup
55+
echo "${RENODE_ROOT}" > /opt/firmware/.renode-root
56+
chmod 644 /opt/firmware/.renode-root
57+
else
58+
echo "ERROR: Could not determine Renode root directory"
59+
exit 1
60+
fi
61+
62+
# Verify platform file exists
63+
PLATFORM_FILE="${RENODE_ROOT}/platforms/cpus/stm32h753.repl"
64+
if [ ! -f "${PLATFORM_FILE}" ]; then
65+
echo "ERROR: Platform file not found at ${PLATFORM_FILE}"
66+
echo "Searching for platform files..."
67+
find "${RENODE_ROOT}" -name "stm32h753.repl" 2>/dev/null | head -5 || true
68+
exit 1
69+
fi
70+
71+
echo "Platform file found at: ${PLATFORM_FILE}"
72+
73+
# Change to firmware directory
74+
cd /opt/firmware
75+
76+
# Create a modified Renode script with absolute path to platform file
77+
# This avoids the .renode-root file lookup issue
78+
cat > /opt/firmware/run-renode-absolute.resc <<EOF
79+
# Renode test script for STM32H753 (with absolute platform path)
80+
using sysbus
81+
82+
mach create "stm32h753"
83+
84+
# Use absolute path to platform file to avoid .renode-root lookup issues
85+
machine LoadPlatformDescription @${PLATFORM_FILE}
86+
87+
sysbus LoadELF @/opt/firmware/wolfcrypt_test.elf
88+
89+
# Connect USART3 to the console for wolfCrypt output
90+
showAnalyzer usart3
91+
92+
# Start emulation and run for a long time
93+
# The entrypoint script will kill Renode when test completes
94+
emulation RunFor "600s"
95+
EOF
96+
97+
# Start Renode in background, output to log (unbuffered)
98+
# Use the modified script with absolute path
99+
echo "Starting Renode with command: ${RENODE_BIN} --disable-xwt --console -e \"i @/opt/firmware/run-renode-absolute.resc\""
100+
stdbuf -oL -eL "${RENODE_BIN}" --disable-xwt --console -e "i @/opt/firmware/run-renode-absolute.resc" > "${LOG}" 2>&1 &
101+
RENODE_PID=$!
102+
echo "Renode PID: $RENODE_PID"
103+
104+
# Monitor the log for completion, errors, and flush output frequently
105+
START_TIME=$(date +%s)
106+
RESULT=""
107+
LAST_LOG_SIZE=0
108+
109+
while true; do
110+
# Check if Renode is still running
111+
if ! kill -0 "$RENODE_PID" 2>/dev/null; then
112+
break
113+
fi
114+
115+
# Flush new log content to stdout (unbuffered)
116+
if [ -f "${LOG}" ]; then
117+
CURRENT_LOG_SIZE=$(stat -f%z "${LOG}" 2>/dev/null || stat -c%s "${LOG}" 2>/dev/null || echo 0)
118+
if [ "$CURRENT_LOG_SIZE" -gt "$LAST_LOG_SIZE" ]; then
119+
# Output new lines
120+
tail -c +$((LAST_LOG_SIZE + 1)) "${LOG}" 2>/dev/null | head -c $((CURRENT_LOG_SIZE - LAST_LOG_SIZE))
121+
LAST_LOG_SIZE=$CURRENT_LOG_SIZE
122+
fi
123+
fi
124+
125+
# Check for Renode errors (must check before completion to catch errors early)
126+
if grep -q "\[ERROR\]" "${LOG}" 2>/dev/null; then
127+
echo ""
128+
echo "ERROR: Renode reported an error!"
129+
RESULT="renode_error"
130+
break
131+
fi
132+
133+
# Check for completion messages
134+
if grep -q "=== wolfCrypt test passed! ===" "${LOG}" 2>/dev/null; then
135+
RESULT="passed"
136+
break
137+
fi
138+
139+
if grep -q "=== wolfCrypt test FAILED ===" "${LOG}" 2>/dev/null; then
140+
RESULT="failed"
141+
break
142+
fi
143+
144+
# Check timeout
145+
CURRENT_TIME=$(date +%s)
146+
ELAPSED=$((CURRENT_TIME - START_TIME))
147+
if [ "$ELAPSED" -ge "$TIMEOUT" ]; then
148+
echo ""
149+
echo "Timeout after ${TIMEOUT} seconds"
150+
RESULT="timeout"
151+
break
152+
fi
153+
154+
sleep 0.1 # Check more frequently for better responsiveness
155+
done
156+
157+
# Kill Renode if still running
158+
if kill -0 "$RENODE_PID" 2>/dev/null; then
159+
kill "$RENODE_PID" 2>/dev/null || true
160+
wait "$RENODE_PID" 2>/dev/null || true
161+
fi
162+
163+
# Show the log output
164+
cat "${LOG}"
165+
166+
# Report result
167+
case "$RESULT" in
168+
passed)
169+
echo ""
170+
echo "wolfCrypt tests completed successfully."
171+
exit 0
172+
;;
173+
failed)
174+
echo ""
175+
echo "wolfCrypt tests FAILED."
176+
exit 1
177+
;;
178+
renode_error)
179+
echo ""
180+
echo "Renode reported an error - test aborted."
181+
exit 1
182+
;;
183+
timeout)
184+
echo ""
185+
echo "wolfCrypt tests timed out after ${TIMEOUT} seconds."
186+
exit 1
187+
;;
188+
*)
189+
echo ""
190+
echo "wolfCrypt tests did not report a result."
191+
exit 1
192+
;;
193+
esac
194+

0 commit comments

Comments
 (0)