1. Today’s topic
Today we examine security mechanisms:
Secure Boot — permits only trusted firmware to boot
Flash Encryption — hides external Flash contents
TrustZone — isolates code and data at runtime
Secure Storage — protects keys and secret parameters
Anti-rollback — forbids revoked old versions from bootingThe central idea: Secure Boot protects the boot chain, TrustZone protects the runtime access boundary, and Flash encryption protects data when the device is powered off. None replaces the others.
2. Why this matters in your projects
Firmware acquires sensitive assets:
MQTT client private key
APN and server passwords
command-signing keys
configuration-encryption keys
device certificates
safe OTA parameters
anti-replay counters
factory calibration
critical GPIO and power outputsAn AT-parser bug may allow code execution that reads the MQTT private key. MPU helps detect memory violations but does not create a complete cryptographic boundary. TrustZone on STM32U5/H5/Cortex-M33 can separate keys and secure services from the normal application. The classic ESP32-WROOM-32U has no TrustZone; its foundation is Secure Boot, Flash Encryption, NVS Encryption, eFuse, unique device keys, and architectural access restrictions.
3. Theory
6.3.1 3.1. Threat model
Before enabling security flags, define:
what we protect;
who we protect it from;
in which device state;
what loss is acceptable.6.3.2 3.2. Secure Boot
Chain of trust:
ROM / immutable Root of Trust
→ verify bootloader
→ verify application
→ begin executionSecure Boot verifies code authenticity. It does not hide firmware contents.
6.3.3 3.3. Flash Encryption
Flash Encryption hides external Flash contents. Without Secure Boot, however, it does not guarantee that the executing code is trusted.
Secure Boot without Flash Encryption:
code is verified, but may be read from Flash.
Flash Encryption without Secure Boot:
code is hidden, but chain authenticity is weaker.6.3.4 3.4. TrustZone
On Cortex-M33, the system can be split:
Secure world:
keys;
crypto;
OTA verification;
secure storage;
critical counters;
some peripherals.
NonSecure world:
FreeRTOS;
EC25 parser;
MQTT/TCP;
UI;
normal logic.The Secure API should be narrow:
typedef enum {
SECURE_STATUS_OK = 0,
SECURE_STATUS_INVALID_ARG,
SECURE_STATUS_DENIED,
SECURE_STATUS_INTERNAL_ERROR,
} secure_status_t;
secure_status_t secure_sign_event(const uint8_t *message,
size_t message_size,
uint8_t *signature,
size_t signature_capacity,
size_t *signature_size);The private key is never returned outside. 6.3.5 3.5. A Secure Service validates arguments
The Secure world does not trust NonSecure input. Validate pointer, length, output capacity, state, role, rate limits, and replay. Poor API:
const uint8_t *secure_get_private_key(void);Better API:
secure_status_t secure_hmac_calculate(secure_key_id_t key_id,
const void *message,
size_t message_size,
void *output,
size_t output_size);6.3.6 3.6. What belongs in the Secure world
Suitable:
OTA signature verification
device identity key
HMAC/signing service
anti-replay counter
security version
factory provisioning state
secure storage
critical firmware confirmation operationUnsuitable:
the whole MQTT client
JSON parser
EC25 AT parser
the whole FreeRTOS application
logger
web server
complex business logic6.3.7 3.7. Anti-rollback
Distinguish:
firmware version:
changes with each release
build number:
grows monotonically
security version:
changes only when revoking an old security generationDo not increment secure_version for every normal release, or you will lose functional rollback.
6.3.8 3.8. Provisioning
DEVELOPMENT
→ test keys, debug open
PILOT
→ production-like keys, recovery test
PRODUCTION
→ final keys, eFuse/option bytes, provisioning reportThe private signing key must not be stored in Git, a Docker image, a HIL Raspberry Pi, or a CI PR-job.
4. Common mistakes
1. Treating Flash Encryption as a substitute for Secure Boot.
2. Treating Secure Boot as protection of secrets in RAM.
3. Placing the whole project in the Secure world.
4. Giving NonSecure code a pointer to a key.
5. Not checking NonSecure pointer and length.
6. Keeping a signing key in an ordinary CI secret.
7. Enabling eFuse/option bytes on the only debug board.
8. Using one symmetric key for the whole fleet.
9. Putting a private key in logs or a core dump.
10. Not designing key rotation.5. Practical assignment for 30-60 minutes
Create SECURITY_ARCHITECTURE.md:
# Security architecture
## Assets
| Asset | Confidential? | Integrity critical? | Location |
|---|---:|---:|---|
| Firmware signing private key | yes | yes | offline signing environment |
| Firmware verification key | no | yes | eFuse/bootloader |
| MQTT device private key | yes | yes | secure storage/encrypted NVS |
| CA certificate | no | yes | firmware/read-only storage |
| APN password | yes | medium | encrypted NVS |
| Phase policy | no | yes | signed config/read-only runtime |
| Boot counter | no | yes | protected persistent storage |For ESP32, draw:
Untrusted/external:
EC25 bytes, MQTT, HTTP, CLI
Application:
parser, networking, phase logic
Security services:
OTA verification, encrypted storage
Hardware root:
eFuse, Secure Boot digest, flash encryption keyFor STM32 TrustZone:
NonSecure:
EC25, MQTT, Modbus, UI, phase logic
Secure:
key operations, OTA verification,
anti-replay counter, secure storage
Immutable Root:
STiRoT/OEMiRoT6. Further reading
- ESP-IDF Security Overview, Secure Boot v2, and Flash Encryption.
- STM32H5/U5 TrustZone, STiRoT/OEMiRoT, OBKeys, and secure storage.
Brief recap
immutable root
→ verified bootloader
→ verified application
→ Secure/NonSecure boundary
→ narrow secure services
→ isolated device keys
→ signed OTA
→ anti-rollback
→ controlled provisioningExercise
An application asks a secure service to sign arbitrary input and return a pointer to its private key. Redesign the interface and validation boundary.
Self-check criteria: Explain how an untrusted pointer and output capacity are checked; naming TrustZone alone does not validate an unsafe API.
Show the supplied answer
Never return the private key or a pointer to it. Provide a narrow operation such as signing a bounded digest, validate input/output ranges and lengths plus authorization/state/rate limits, and keep key operations inside the secure boundary.
Exercise
Distinguish firmware version, build number, and security version in a release policy that preserves functional rollback while revoking a compromised generation.
Self-check criteria: Describe the revocation decision and recovery/provisioning evidence before changing irreversible device settings.
Show the supplied answer
Firmware version identifies the feature release; build number grows monotonically; security version changes when an older security generation must be revoked. Avoid advancing the irreversible security threshold for every normal feature release.