This repository is a production-oriented secure IoT firmware reference for the STM32U585 and B-U585I-IOT02A Discovery Kit, built with FreeRTOS, LwIP, and MbedTLS. It demonstrates MQTT over TLS connectivity to AWS IoT Core, Mosquitto, and EMQX, including fleet provisioning, device shadow, jobs, and host OTA update workflows.
If you are searching for a secure STM32 AWS IoT example, STM32U5 MQTT over TLS reference, B-U585I-IOT02A FreeRTOS project, or STSAFE secure element integration, this project is designed for that use case.
- Why This Project
- Upstream and Key Differences
- Key Features
- Supported Hardware and Sensors
- Security Architecture
- Software Components (FreeRTOS, LwIP, MbedTLS, PKCS#11)
- Flash Memory Layout
- Quick Start
- Build Configuration Matrix
- Provisioning Guides
- Run the Examples
- Required CMSIS Packs
- Git Submodules
- STM32CubeMX Regeneration Note
- Enable or Disable Examples
This reference helps embedded developers build secure, cloud-connected firmware on STM32U5 with a modular architecture and production-style security patterns:
- Portable software stack across Wi-Fi and security variants
- MQTT over TLS with software or hardware-backed credentials
- Standard interfaces for cryptography and runtime configuration
- Proven end-to-end flows for provisioning, telemetry, control, and OTA
This repository is derived from the official FreeRTOS STM32U5 reference project:
Main differences in this repository:
- Adds AWS IoT Fleet Provisioning support
- Adds STSAFE security flows (A110/A120)
- Supports both MXCHIP and ST67 Wi-Fi module variants
- Adds support for Mosquitto and EMQX MQTT brokers
- Supports STM32CubeMX project regeneration based on CMSIS packs
- Stores runtime configuration in internal flash or STSAFE (instead of external flash used in the upstream reference)
- Does not support TrustZone
- Secure MQTT Connectivity: AWS IoT Core, test.mosquitto.org, broker.emqx.io
- Hardware Security: STSAFE-A110 and STSAFE-A120 support
- Provisioning at Scale: AWS Fleet Provisioning, MAR, JITP, JITR
- AWS IoT Services: Device Shadow, Jobs, MQTT file delivery, OTA
- Runtime Applications: LED, button, sensors, Home Assistant discovery
- Storage Abstraction: PKCS#11 and KVS over internal flash or STSAFE
- Main board: B-U585I-IOT02A
- Wi-Fi modules:
- X-NUCLEO-67W61M1
- MXCHIP EMW3080B
- Secure element:
- STSAFE-A110
- STSAFE-A120 via X-NUCLEO-ESE01A1
- Sensors:
The project supports connections to AWS IoT Core, test.mosquitto.org, and broker.emqx.io. In all cases, X.509 certificates are required for device/server authentication, ensuring secure and trusted communication with the MQTT broker.
This project provides multiple build configurations to support a variety of hardware platforms and secure connectivity methods. MXCHIP, ST67_T01, and ST67_T02 configurations offer flexibility by supporting different wireless connections. The remaining configurations (FleetProvisioning, STSAFEA110, and STSAFEA120 variants) are tailored specifically for AWS IoT Core, utilizing features such as Just-In-Time Provisioning and hardware-based secure elements to enable secure device onboarding.
In most configurations, the TLS and MQTT stacks run on the host microcontroller. However, in the ST67_T01_Single configuration, TLS and MQTT communication are offloaded to the ST67 Wi-Fi module.
In STSAFEA110 and STSAFEA120 configurations, all sensitive assets, including the TLS private key, device certificate, broker root CA, and device configuration parameters (for example: MQTT endpoint, port, and Wi-Fi credentials), are securely stored within the non-volatile memory of the STSAFE-A secure element.
To further strengthen system resilience, cryptographic operations utilize the hardware-based Random Number Generator (RNG) embedded within STSAFE, rather than relying on the STM32 internal RNG. The STSAFE RNG is designed to meet stringent security standards (such as NIST SP 800-90A/B/C) and generates high-entropy randomness suited for secure key generation, session establishment, and cryptographic protocols. This minimizes predictability and entropy bias risks during TLS handshakes and other secure interactions.
Additionally, encrypted I2C communication between the host MCU and STSAFE can be enabled, ensuring confidentiality and integrity of sensitive exchanges, even on potentially untrusted system buses.
By offloading credential storage and secure random number generation to STSAFE, the system reduces attack surface and aligns with hardware-isolation security best practices.
Whether credentials and configuration are stored in internal flash or in a secure element (STSAFE-A110/A120), the application always accesses them through standardized interfaces, providing a consistent abstraction layer across all configurations.
PKCS#11is used for cryptographic assets such as TLS keys and certificates.KVS(Key-Value Storage) is used for runtime parameters such as MQTT endpoint, port, and Wi-Fi credentials.
This abstraction enables code portability across hardware configurations and promotes secure, modular design without requiring changes in application logic.
| Purpose | STSAFEA110 | STSAFEA120 |
|---|---|---|
| Device certificate | Zone 0 | Zone 0 |
| KV store configuration | Zone 1 | Zone 1 |
| Code signing key | Zone 2 | Zone 2 |
| Server CA certificate | Zone 4 | Zone 11 |
Mapping is configured in stsafe.h and stsafe.c.
See MbedTLS for details.
The CLI interface located in project/Common/ is used to provision the device. It also provides Unix-like utilities. See project/Common/cli/ReadMe.md for details.
The key-value store located in project/Common/kvstore/ is used to store runtime configuration values in STM32 internal flash memory or in STSAFE, depending on the selected project configuration. See project/Common/kvstore/ReadMe.md for details.
The PkiObject API handles conversion between different representations of cryptographic objects such as public keys, private keys, and certificates. See project/Common/crypto/ReadMe.md for details.
The PKCS#11 API is used to manage keys and certificates, whether they are stored in internal flash or within the STSAFE secure element. See corePKCS11 Library for details.
┌────────────────────────────┐
│ Application Layer │
│ (TLS, MQTT, Wi-Fi setup) │
└──────┬──────────┬──────────┘
│ │
┌────▼────┐┌────▼────┐
Manage keys and certs ->│ PKCS#11 ││ KVS │ <- stores runtime config like endpoints and Wi-Fi
└────┬────┘└────┬────┘
│ │
│ │
┌──────▼──────────▼───────┐
│ Storage Backend Layer │
├─────────────────────────┤
│ Internal Flash (lfs) │
│ OR │
│ STSAFE-A (A110/A120) │ <- secure storage and cryptographic engine
└─────────────────────────┘
In STSAFE configurations, all certificates, keys, and runtime settings are stored in STSAFE. In other cases, they reside in the STM32 internal flash.
In ST67_T01_Single, certificates and keys are transferred from STM32 internal flash to ST67 internal file system, and TLS/MQTT is managed by ST67. Otherwise, TLS/MQTT runs on the host processor.
STM32U5 dual-bank flash is partitioned to support boot, application, OTA staging, and persistent assets.
| Flash Bank | Region | Size | Purpose |
|---|---|---|---|
| Bank 1 | Bootloader | 64 KB | Boot and handoff |
| Bank 1 | Main application | 768 KB | Primary firmware image |
| Bank 1 | Reserved | 192 KB | Reserved space |
| Bank 2 | HOTA image | 768 KB | Staging area for host OTA updates |
| Bank 2 | LittleFS | 256 KB | Certificates, keys, and runtime configuration (non-STSAFE profiles) |
Bootloader responsibilities:
- Install validated HOTA image to application region
- Jump to main application
Note: HOTA is available only with AWS-connected profiles.
SECURITY WARNING
The provided bootloader is for demonstration purposes and does not include full production hardening (for example: secure boot enforcement, anti-rollback, signature policy, debug lock strategy). Perform a security review before deployment.
git clone https://github.com/SlimJallouli/b_u585_iota02_iot_reference.git --recurse-submodulesIf already cloned without submodules:
git submodule update --init --recursiveUpdate the ST67 module to firmware revision 1.2.0 using the official binaries/instructions:
Profile note:
profile_t01: TCP/IP, MQTT, TLS on ST67profile_t02: TCP/IP, MQTT, TLS on STM32 host (recommanded)
If you want the fastest path to run this project, use the prebuilt binaries and automation scripts in bin/.
This option is recommended for quick validation because it:
- Avoids immediate IDE/project setup
- Uses prebuilt firmware images
- Automates flash + provisioning through PowerShell scripts
Start here:
- Note: This project was built and tested with STM32CubeIDE v2.1.0.
- Open STM32CubeIDE
- Select Import Project
- Choose the repository root folder
b_u585_iota02_iot_reference - Import both projects (bootloader + reference app)
Use the dropdown next to the hammer icon in STM32CubeIDE.
Use the provided debug configurations to:
- Build bootloader + selected app profile
- Flash both images
- Start execution from bootloader
| Build Config | AWS IoT Core | Mosquitto | EMQX | OTA |
|---|---|---|---|---|
MXCHIP_Single |
Yes | Yes | Yes | Yes |
MXCHIP_FleetProvisioning |
Yes | No | No | Yes |
MXCHIP_STSAFEA110 |
Yes | No | No | Yes |
MXCHIP_STSAFEA120 |
Yes | No | No | Yes |
ST67_T01_Single |
Yes | Yes | Yes | No |
ST67_T02_Single |
Yes | Yes | Yes | Yes |
ST67_T02_FleetProvisioning |
Yes | No | No | Yes |
ST67_T02_STSAFEA110 |
Yes | No | No | Yes |
ST67_T02_STSAFEA120 |
Yes | No | No | Yes |
Notes:
- Fleet provisioning, STSAFE, and OTA options are AWS-specific.
- In STSAFE profiles, keys/certs/config are stored in STSAFE.
- In
ST67_T01_Single, TLS/MQTT is handled by ST67. - For EMQX, use
DigiCertGlobalRootG2.crt.pemas the server root CA.
Choose your broker and onboarding method:
- Mosquitto (
test.mosquitto.org)
- Supported:
MXCHIP_Single,ST67_T01_Single,ST67_T02_Single - Guide: Provision and Run with test.mosquitto.org
- EMQX (
broker.emqx.io)
- Supported:
MXCHIP_Single,ST67_T01_Single,ST67_T02_Single - Guide: Provision and Run with EMQX MQTT Broker
- AWS IoT Core (Single Thing)
- Supported:
MXCHIP_Single,ST67_T01_Single,ST67_T02_Single - Guides:
- AWS IoT Core (Fleet Provisioning)
- Supported:
MXCHIP_FleetProvisioning,ST67_T02_FleetProvisioning - Guide: Provision and Run with AWS Fleet Provisioning
- AWS IoT Core (STSAFE onboarding)
- Supported:
MXCHIP_STSAFEA110,MXCHIP_STSAFEA120,ST67_T02_STSAFEA110,ST67_T02_STSAFEA120 - Methods: MAR, JITP, JITR
- Guide: Provision and Run with AWS using STSAFE
After provisioning, use these feature guides:
- LED Control Example
- Button Status Example
- Environmental Sensor Example
- Ranging Sensor Example
- Motion Sensor Example
- Home Assistant Discovery Example
- Garage Door Cover Control Example
- AWS Fleet Provisioning Guide
- AWS Defender
- AWS Shadow
- AWS OTA
Install these packs in STM32CubeMX before opening the .ioc file:
- ARM.CMSIS-FreeRTOS 11.2.0
- ARM.mbedTLS 3.1.1
- AWS IoT OTA 5.0.1
- AWS IoT Device Defender 4.2.0
- AWS IoT Device Shadow 5.1.0
- AWS IoT Fleet Provisioning 1.1.0
- AWS backoffAlgorithm 4.2.0
- AWS coreJSON 4.2.0
- AWS coreMQTT 5.1.0
- AWS coreMQTT_Agent 5.1.0
- lwIP 2.3.0
Also used via STM32CubeMX dependency flow:
This project includes external dependencies as submodules:
CRITICAL NOTE
If you regenerate code with STM32CubeMX, you must runupdate.shbefore building. Skipping this step causes build failures.
After regenerating from STM32CubeMX, run the project update script before building to avoid generated-code integration issues:
update.sh
Feature toggles are defined in project/Core/Inc/main.h:
#define DEMO_PUB_SUB 0
#define DEMO_OTA 1
#define DEMO_ENV_SENSOR 1
#define DEMO_MOTION_SENSOR 1
#define DEMO_SHADOW 1
#define DEMO_DEFENDER 1
#define DEMO_LED 1
#define DEMO_BUTTON 1
#if !defined(ST67W6X_NCP)
#define DEMO_HOME_ASSISTANT 1
#endif
#define DEMO_ECHO_SERVER 0
#define DEMO_ECHO_CLIENT 0
#define DEMO_PING 0
#if defined(ST67W6X_NCP)
#define DEMO_SNTP 1
#endifSet a macro to 1 to enable and 0 to disable, then rebuild and flash.







