Skip to content
Open
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
41 changes: 41 additions & 0 deletions .github/workflows/stm32h563-m33mu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,47 @@ jobs:
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
fi

# Broker persistence (encrypted-at-rest flash KV) lives in wolfMQTT
# PR 538 (broker_features) and is not yet in wolfMQTT master, so the
# stm32h563_m33mu_full job above builds the broker WITHOUT persistence
# (default). This job builds the broker WITH ENABLE_MQTT_BROKER_PERSIST=1
# against the PR 538 head so the feature stays covered until it merges.
# TODO: once wolfMQTT PR 538 merges, add ENABLE_MQTT_BROKER_PERSIST=1 to
# stm32h563_m33mu_full (which clones wolfMQTT master) and drop this job.
stm32h563_m33mu_broker_persist:
runs-on: ubuntu-latest
timeout-minutes: 20
container:
image: ghcr.io/wolfssl/wolfboot-ci-m33mu:v1.2
options: --privileged

steps:
- uses: actions/checkout@v4

- name: Clone wolfSSL + wolfMQTT (PR 538 broker_features)
run: |
set -euo pipefail
cd ..
git clone --depth 1 https://github.com/wolfSSL/wolfssl.git
git clone https://github.com/wolfSSL/wolfmqtt.git
cd wolfmqtt
git fetch --depth 1 origin pull/538/head
git checkout FETCH_HEAD

- name: Build STM32H563 broker with flash persistence
run: |
set -euo pipefail
make -C src/port/stm32h563 \
ENABLE_TLS=1 ENABLE_MQTT_BROKER=1 ENABLE_MQTT_BROKER_PERSIST=1 \
WOLFSSL_SP_NO_ASM=1 \
CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy
# Confirm the persistence backend is compiled in. Write strings to a
# file first: piping into 'grep -q' makes grep close the pipe early,
# so 'strings' takes SIGPIPE (141) which 'set -o pipefail' would turn
# into a spurious job failure.
strings src/port/stm32h563/app.bin > /tmp/app.strings
grep -q "flash persistence enabled" /tmp/app.strings

stm32h563_m33mu_https_tls13:
runs-on: ubuntu-latest
timeout-minutes: 25
Expand Down
50 changes: 47 additions & 3 deletions src/port/stm32h563/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ ENABLE_MQTT ?= 0
# MQTT Broker: set ENABLE_MQTT_BROKER=1 to include wolfMQTT broker (requires TLS)
ENABLE_MQTT_BROKER ?= 0

# MQTT Broker persistence: set ENABLE_MQTT_BROKER_PERSIST=1 to persist broker
# state (sessions/subs/retained/offline-queue) to STM32H5 internal flash,
# AES-256-GCM encrypted at rest. OFF by default because it requires the
# wolfMQTT broker persistence layer (mqtt_broker_persist.c +
# MqttBroker_SetPersistHooks) from wolfMQTT PR 538 (broker_features), which is
# not yet in wolfMQTT master. Requires ENABLE_MQTT_BROKER=1.
ENABLE_MQTT_BROKER_PERSIST ?= 0

# TFTP client demo: set ENABLE_TFTP=1 to include the wolfIP TFTP client
# that downloads a firmware image at boot and stages it into the
# wolfBoot update partition. TZEN=0 only.
Expand Down Expand Up @@ -310,7 +318,7 @@ SRCS += $(WOLFMQTT_SRCS)

# wolfMQTT objects use relaxed warnings + MQTT/SSL include paths + user_settings.h
$(WOLFMQTT_ROOT)/%.o: $(WOLFMQTT_ROOT)/%.c
$(CC) $(CFLAGS_WOLFSSL) -DENABLE_MQTT -DWOLFSSL_USER_SETTINGS -DWOLFMQTT_USER_SETTINGS $(if $(filter 1,$(ENABLE_MQTT_BROKER)),-DENABLE_MQTT_BROKER) -I$(WOLFMQTT_ROOT) -I$(WOLFSSL_ROOT) -I$(ROOT)/src -c $< -o $@
$(CC) $(CFLAGS_WOLFSSL) -DENABLE_MQTT -DWOLFSSL_USER_SETTINGS -DWOLFMQTT_USER_SETTINGS $(if $(filter 1,$(ENABLE_MQTT_BROKER)),-DENABLE_MQTT_BROKER) $(MQTT_PERSIST_DEFS) -I$(WOLFMQTT_ROOT) -I$(WOLFSSL_ROOT) -I$(ROOT)/src -c $< -o $@

endif # ENABLE_MQTT

Expand All @@ -333,13 +341,49 @@ CFLAGS += -DENABLE_MQTT_BROKER
CFLAGS += -DWOLFMQTT_USER_SETTINGS
CFLAGS += -I$(WOLFMQTT_ROOT)

# MQTT broker wrapper
# Opt-in broker persistence. Gated by ENABLE_MQTT_BROKER_PERSIST so the
# default broker build stays compatible with released wolfMQTT (the
# persistence layer is only in wolfMQTT PR 538 / broker_features for now).
# The persistence macros are defined on the command line (not in
# user_settings.h) so they are set before any wolfMQTT/wolfSSL header is
# parsed - the port includes wolfmqtt/mqtt_broker.h before wolfssl/ssl.h
# pulls in user_settings.h, and these also need to precede mqtt_broker.h's
# #ifndef size defaults. MQTT_PERSIST_DEFS is reused by the wolfMQTT object
# pattern rules below.
ifeq ($(ENABLE_MQTT_BROKER_PERSIST),1)
# The flash KV backend writes via the non-secure FLASH register view and a
# fixed flash layout, so it is TZEN=0 only.
ifeq ($(TZEN),1)
$(error ENABLE_MQTT_BROKER_PERSIST=1 requires TZEN=0 (the flash KV backend uses the non-secure FLASH register view))
endif
# NOTE: WOLFMQTT_BROKER_PERSIST_ENCRYPT enables AES-256-GCM at rest, but the
# backend's derive_key hook returns a FIXED DEVELOPMENT KEY (see
# mqtt_broker_persist_flash.c). This is for testing only - replace derive_key
# with a real key source (SE/HSM/device secret) before relying on
# confidentiality.
MQTT_PERSIST_DEFS := -DWOLFMQTT_BROKER_PERSIST -DWOLFMQTT_BROKER_PERSIST_ENCRYPT \
-DBROKER_MAX_PERSIST_SESSIONS=8 -DBROKER_MAX_OFFLINE_MSGS_PER_SUB=8
CFLAGS += $(MQTT_PERSIST_DEFS)
endif

# MQTT broker wrapper (+ STM32H5 internal-flash persistence backend when
# ENABLE_MQTT_BROKER_PERSIST=1).
SRCS += mqtt_broker.c
ifeq ($(ENABLE_MQTT_BROKER_PERSIST),1)
SRCS += mqtt_broker_persist_flash.c
endif

# wolfMQTT broker source files
# Note: mqtt_client.c is needed by broker internals (MqttClient_Init, etc.)
# mqtt_broker_persist.c is the generic persistence codec (encode/decode +
# AES-GCM wrap), built only when persistence is enabled. The POSIX backend
# (mqtt_broker_persist_posix.c) is never built here - it pulls in
# <dirent.h>/<fcntl.h>; we supply a flash backend instead.
WOLFMQTT_BROKER_SRCS := \
$(WOLFMQTT_ROOT)/src/mqtt_broker.c
ifeq ($(ENABLE_MQTT_BROKER_PERSIST),1)
WOLFMQTT_BROKER_SRCS += $(WOLFMQTT_ROOT)/src/mqtt_broker_persist.c
endif

# Only add shared wolfMQTT sources if MQTT client is not already enabled
ifneq ($(ENABLE_MQTT),1)
Expand All @@ -355,7 +399,7 @@ SRCS += $(WOLFMQTT_BROKER_SRCS)
# Only define this pattern rule if MQTT client didn't already define it
ifneq ($(ENABLE_MQTT),1)
$(WOLFMQTT_ROOT)/%.o: $(WOLFMQTT_ROOT)/%.c
$(CC) $(CFLAGS_WOLFSSL) -DENABLE_MQTT_BROKER -DWOLFSSL_USER_SETTINGS -DWOLFMQTT_USER_SETTINGS -I$(WOLFMQTT_ROOT) -I$(WOLFSSL_ROOT) -I$(ROOT)/src -c $< -o $@
$(CC) $(CFLAGS_WOLFSSL) -DENABLE_MQTT_BROKER $(MQTT_PERSIST_DEFS) -DWOLFSSL_USER_SETTINGS -DWOLFMQTT_USER_SETTINGS -I$(WOLFMQTT_ROOT) -I$(WOLFSSL_ROOT) -I$(ROOT)/src -c $< -o $@
endif

endif # ENABLE_MQTT_BROKER
Expand Down
19 changes: 19 additions & 0 deletions src/port/stm32h563/mqtt_broker.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include <string.h>

#include "certs.h"
#ifdef WOLFMQTT_BROKER_PERSIST
#include "mqtt_broker_persist_flash.h"
#endif

/* Configuration defaults */
#define DEFAULT_BROKER_PORT_TLS 8883
Expand All @@ -49,6 +52,9 @@ static struct {
MqttBroker broker;
MqttBrokerNet net;
WOLFSSL_CTX *ssl_ctx;
#ifdef WOLFMQTT_BROKER_PERSIST
MqttBrokerPersistHooks persist_hooks;
#endif
broker_state_t state;
mqtt_broker_debug_cb debug_cb;
uint16_t port;
Expand Down Expand Up @@ -164,6 +170,19 @@ static int handle_init(void)
/* Configure broker */
ctx.broker.port = ctx.port;

#ifdef WOLFMQTT_BROKER_PERSIST
/* Install the STM32H5 internal-flash persistence backend before
* MqttBroker_Start (restore runs inside Start). On failure the broker
* still runs, just without durable state. */
if (MqttBrokerNet_PersistFlash_Init(&ctx.persist_hooks) == 0) {
(void)MqttBroker_SetPersistHooks(&ctx.broker, &ctx.persist_hooks);
debug_print("MQTT Broker: flash persistence enabled\n");
}
else {
debug_print("MQTT Broker: persist init failed (in-memory only)\n");
}
#endif

/* Set up TLS if enabled */
if (ctx.use_tls) {
ctx.broker.use_tls = 1;
Expand Down
Loading
Loading