Skip to main content
Version: Next

Embedded targets and I/O

This page summarizes how the Rust workspace supports no_std, bare-metal style builds, and transport integration.

Feature flags (all library crates)

FeatureMeaning
std (default)Full standard library; file helpers and std::error::Error impls where applicable.
alloc (default)Heap types (Vec, String) for cryptographic and protocol buffers.

Disable defaults for bare-metal style builds:

cargo check -p noxtls --no-default-features --features alloc

std-only APIs

When std is disabled, the following are unavailable (use in-memory / slice APIs instead):

CrateAPI
noxtls-coreLibraryConfig::from_mbedtls_style_file — use from_mbedtls_style_str with bytes you loaded.
noxtls-x509noxtls_pem_file_to_der, noxtls_pem_file_to_der_blocks, noxtls_der_to_pem_file, noxtls_der_to_file.
noxtlsTicketStore::save_to_file, TicketStore::load_from_file.

TLS transport (noxtls)

The transport module defines:

  • transport::blocking::BlockingStream — synchronous read/write.
  • transport::stream_async::AsyncByteStream — async read/write (uses async_trait(?Send) for embedded-io-async compatibility).

Optional Cargo features on noxtls (forwarded to noxtls-io):

FeaturePurpose
adapter-embedded-ioEmbeddedIoTransport wrapping embedded-io Read + Write.
adapter-embedded-io-asyncEmbeddedIoAsyncTransport wrapping embedded-io-async.
adapter-tokioTokioAsyncTransport for tokio types with AsyncReadExt + AsyncWriteExt (implies std).

Example checks:

cargo check -p noxtls --features adapter-embedded-io
cargo check -p noxtls --features adapter-embedded-io-async
cargo check -p noxtls --features adapter-tokio

Handshake helpers

transport::drive::noxtls_read_exact_blocking reads a fixed number of bytes through a BlockingStream for framing layers built on top of the protocol state machine.

transport::drive_async::noxtls_read_record_async (with adapter-embedded-io-async) pumps an AsyncByteStream until one full TLS record is available, using TlsRecordDeframer from noxtls-io.

Embassy integration

Use no_std + alloc with embedded-alloc on the MCU, then enable:

noxtls = { default-features = false, features = ["alloc", "adapter-embedded-io-async"] }
noxtls-platform = { default-features = false, features = ["alloc", "rand-core"] }
rand_core = "0.6"
embedded-io-async = "0.7"

Wire stack:

  1. embassy_net::tcp::TcpSocket implements embedded-io-async Read + Write.
  2. noxtls::transport::EmbeddedIoAsyncTransport::noxtls_new(socket)AsyncByteStream.
  3. embassy_rp::clocks::Rng (or your HAL TRNG) → noxtls_platform::RandCoreEntropynoxtls::noxtls_hmac_drbg_from_entropy.
  4. RTC or NTP → noxtls_platform::StaticTimeSource / custom TimeSourcenoxtls::noxtls_cert_validation_time_now for PKIX checks.

Async server API (TLS 1.3):

Hosted tests can drive the same async API with transport::blocking_as_async::BlockingAsAsync plus an executor such as pollster::block_on (see noxtls dev-dependency in tests).

Vendor ports live under ports/: RP2040 link-check crates in ports/rp2040/, ESP32-S3 N8R8 TLS client in ports/esp32/s3-n8r8-tls-client/.

Cross-compile check:

rustup target add thumbv6m-none-eabi
cargo check -p noxtls --no-default-features --features alloc,adapter-embedded-io-async --target thumbv6m-none-eabi