Mbed TLS setup¶
Wiring SolidSyslogMbedTlsStream so a SolidSyslogStreamSender delivers
RFC 5425 syslog over TLS. The TLS obligations page covers what
any TLS stream must do. The Mbed TLS page covers what this adapter
needs and where it falls short of that. The config fields are documented on the
struct itself, and this page is the wiring — and the things that bite.
The layering¶
TLS is a Stream wrapped around another Stream. The TLS adapter carries the records; the transport underneath carries the bytes.
SolidSyslog_Log ─▶ Buffer ─▶ SolidSyslogStreamSender
│
▼
SolidSyslogMbedTlsStream ◀── your CA / cert / key / DRBG handles
│
▼
a byte-transport Stream ◀── your TCP/IP stack
You supply two things: the byte transport, and the Mbed TLS handles. Everything
above the TLS stream is unchanged from a plaintext wiring — StreamSender
applies RFC 6587 octet-counting framing on top either way.
Wiring it¶
struct SolidSyslogMbedTlsStreamConfig cfg = {
.Transport = myTcpStream,
.Sleep = MySleep, /* required — no fallback */
.Rng = &mySeededDrbg,
.CaChain = &myParsedCaChain,
.ServerName = "syslog.example.com",
.ClientCertChain = &myClientCert, /* both, or neither */
.ClientKey = &myClientKey,
};
struct SolidSyslogStream* tls = SolidSyslogMbedTlsStream_Create(&cfg);
Wire tls into a SolidSyslogStreamSender as its Stream, exactly as you
would a plain TCP stream, and call SolidSyslogMbedTlsStream_Destroy when the
sender is torn down. There is nothing process-wide to install.
If your firmware already uses Mbed TLS for something else — a cloud client, an OTA updater, a vendor framework — that is the whole integration: the adapter consumes handles you have already built and touches no global state.
Bringing Mbed TLS up, if it is new to the target¶
Port Mbed TLS itself first, following the upstream porting guide. Four things then matter specifically for this adapter, and three of them fail in ways that are hard to read.
Seed the DRBG from a source registered as MBEDTLS_ENTROPY_SOURCE_STRONG.
Without a strong-tagged source, mbedtls_entropy_func never reaches its
internal threshold and every mbedtls_ctr_drbg_seed returns
MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED. Production entropy is a hardware
question — a true random number generator, a vendor security element, or a
board-specific source.
Call psa_crypto_init() after the DRBG is seeded, not before. Mbed TLS
3.6 routes TLS 1.3 through PSA, and if PSA is uninitialised the first handshake
state transition returns MBEDTLS_ERR_ERROR_GENERIC_ERROR before any byte
reaches the socket.
On a target with no platform entropy, give PSA a strong source. With
MBEDTLS_NO_PLATFORM_ENTROPY defined — usual on embedded — mbedtls_entropy_init
registers no source of its own, and psa_crypto_init then fails with
PSA_ERROR_INSUFFICIENT_ENTROPY. Two routes out, and either is enough:
- Define
MBEDTLS_PSA_CRYPTO_EXTERNAL_RNGand providembedtls_psa_external_get_randomwrapping the DRBG you just seeded. PSA bypasses the entropy subsystem entirely, so PSA and the classic API run off one chain. - Or define
MBEDTLS_ENTROPY_HARDWARE_ALTand providembedtls_hardware_poll.mbedtls_entropy_initthen registers it as a strong source, and PSA seeds its own DRBG through the standard path.
The first keeps one chain and is the simpler thing to reason about; the second suits a target whose randomness already arrives through a hardware poll.
Parse the CA chain, and the client credential if you are using mutual TLS, by whatever route suits the build: a filesystem, a baked-in array, a blob pulled from a security element. PEM input must be NUL-terminated.
Memory¶
The adapter allocates nothing itself. Everything a TLS session costs is Mbed
TLS's own allocation, governed by your mbedtls_config.h — the record buffer
sizes dominate it, and their defaults are sized for a general-purpose host
rather than a constrained target. Budget for every TLS session you intend to
run concurrently, not one, and take the sizing guidance from the
upstream documentation rather than from
here.
Where Mbed TLS takes its memory from is also your configuration. On a target
whose libc heap is not the one you intend it to use, mbedtls_ssl_setup is
where that shows up.
When it does not work¶
Failures report through the error handler rather than silently. Install one
before you start, and read error severity for what
each level is telling you — a CRITICAL at create time means the stream fell
back to the Null object, and nothing will be delivered.