Skip to content

Try embassy-net on xarxa (embassy main) - #11

Draft
georgesFoundation wants to merge 7 commits into
mainfrom
xarxa
Draft

georgesFoundation wants to merge 7 commits into
mainfrom
xarxa

Conversation

@georgesFoundation

Copy link
Copy Markdown
Collaborator

Experiment: build against embassy's main branch, pinned with [patch.crates-io], where embassy-net runs on xarxa instead of smoltcp.

  • The driver follows the new embassy-net-driver-channel: packets are xarxa PacketBufs from a global pool. RX takes a buffer from the pool, converts the frame into it and queues it; TX gets an owned buffer and gives it back to the pool by dropping it. The channel no longer carries the MTU as a type parameter, ch::new takes it instead.
  • Examples: the new Spim/Qspi argument order (pins first, interrupt binding last), embassy_nrf::crypto::rng for the seed, and in join_open the new embassy-net API: Stack::new with StackStorage, the device added as an interface with DHCP on it, link and address waits on the interface, and a TcpListener for accepting.

join_open on an nRF7002-DK over SPI at 8 MHz: joins, gets a DHCP lease, answers ping, and echoes 200 KB intact in 0.84 s (0.94 s on smoltcp).

@georgesFoundation
georgesFoundation force-pushed the xarxa branch 12 times, most recently from bdf714e to ebd8195 Compare October 5, 2026 06:53
Experiment: build against embassy's main branch, pinned with
[patch.crates-io], where embassy-net runs on xarxa instead of smoltcp.

- The driver follows the new embassy-net-driver-channel: packets are
  xarxa PacketBufs from a global pool. RX takes a buffer from the pool,
  converts the frame into it and queues it; TX gets an owned buffer and
  gives it back to the pool by dropping it. The channel no longer carries
  the MTU as a type parameter, ch::new takes it instead.
- The new channel hands a frame to send over without a peek: one that
  does not fit the TX batch being built waits in the runner, and goes
  first once a TX token is free.
- Examples: the new Spim/Qspi argument order (pins first, interrupt
  binding last), embassy_nrf::crypto::rng for the seed and the handshake
  nonces, and in join_open and join_wpa2 the new embassy-net API:
  Stack::new with StackStorage, the device added as an interface with
  DHCP on it, link and address waits on the interface, and a TcpListener
  for accepting.

join_open on an nRF7002-DK over SPI at 8 MHz: joins, gets a DHCP lease,
answers ping, and echoes 200 KB intact in 0.84 s (0.94 s on smoltcp).
The supplicant no longer brings its own cryptography. It needs two
primitives, HMAC-SHA1 and the AES-128 block cipher, and now calls
embassy-crypto for them, whose drivers are chosen at link time, as a
time driver is: the application says in its Cargo.toml who answers. That
is the microcontroller's accelerator where the HAL has drivers (the
CryptoCell or CRACEN of embassy-nrf), or embassy-crypto-rustcrypto in
software, on anything. The driver's API does not change, and gains no
type parameter.

- aes-kw, hmac, pbkdf2 and sha1 leave the dependencies: `wpa2` is now
  embassy-crypto and rand_core.
- What stood on those crates is written here, on HmacSha1 and Aes128:
  PBKDF2 (RFC 8018) in crypto.rs, which keeps the keyed state so that an
  iteration is two compressions, and the AES key wrap and unwrap (RFC
  3394) in eapol.rs.
- The host tests run on embassy-crypto-rustcrypto, a dev-dependency.
  They gain the test vectors of RFC 6070 and RFC 3394, and the cases a
  key unwrap must refuse: 54 tests with the feature.
- The example's `wpa2` feature registers embassy-nrf's CryptoCell
  drivers. An application that enables `wpa2` and registers no driver
  does not link.

embassy-crypto is not released (0.0.0 on crates.io reserves the name),
so this stays on the branch that builds against embassy's main.

join_wpa2 on an nRF7002-DK, the nRF5340 at 64 MHz, built for size:

                              CryptoCell   software
  flash, more than open only  11.4 KB      16.5 KB
  key from the passphrase     732 ms       2232 ms

Both join the test access point, get a DHCP lease and answer ping; with
the CryptoCell, 200 KB come back intact from the TCP echo server.
Control::join_wpa2 and join_wpa2_psk lose their `rng` parameter: the seed
of the handshake's nonces comes from embassy_crypto::rng_fill_bytes, the
generator the application registers as it registers HMAC-SHA1 and
AES-128. rand_core leaves the dependencies, and `wpa2` is embassy-crypto
alone.

The access points draw their seeds from it as well:
Control::start_ap_wpa2, start_ap_wpa3 and start_ap_wpa2_wpa3 take no
generator either.

The examples register embassy-nrf's CryptoCell generator
(`embassy-crypto-rng`), which takes the CRYPTO_RNG peripheral over, so
join_open takes embassy-net's seed from rng_fill_bytes as well.

The README says which three drivers an application has to provide, and
that software HMAC-SHA1 and AES-128 still need a hardware generator.

join_wpa2 on an nRF7002-DK: the key in 700 ms, the handshake, a DHCP
lease, ping, and 200 KB intact through the TCP echo server.
The embassy revision that [patch.crates-io] pins, in the crate and in
the example, moves from 5e430e6 to a404c78, main's head on 2026-10-01.
Nothing in the driver or the examples needed a change.

join_wpa2 on an nRF7002-DK: the key in 701 ms, the handshake, a DHCP
lease, ping, and 200 KB intact through the TCP echo server.
The runner only took frames from the stack while the link was up. What
the stack sent before that, its DHCP requests during a join that takes a
few tries, stayed in the channel's four slots. At link-up the stack's
fresh DHCP request found no room: xarxa logged "device refused a frame,
dropping it", and the address came with the next retry, 30 s later.

With the link down the runner now takes those frames and drops them:
they cannot be sent, and the channel is empty when the link comes up.
While the link is up nothing changes: frames wait there when every data
token is busy.

Seen on an nRF7002-DK joining a distant access point on its third
attempt. With the change, on a nearer one: no refused frame at link-up.
With HMAC-SHA256 and AES-128-CMAC for management frame protection, the
join_wpa2 example takes 17 KB more flash than join_open on the
CryptoCell, 29 KB in software (11 KB and 17 KB before).
The fuzz crate is a workspace of its own, so it gets the embassy
revision the driver builds against, and links embassy-crypto-rustcrypto
for the driver's HMAC, AES-128 and AES-128-CMAC, as the tests do.

wrap, key_frame and handshake ran 90 s each without a failure, through
the driver's own AES key wrap and unwrap on embassy-crypto's AES-128.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant