Repository navigation
Noise sessions on links off the cable (ADR-0015) - #144
Merged
Merged
Conversation
The box answers Noise_IK_25519_ChaChaPoly_SHA256 handshakes keyed by the pairing keys (Ed25519 converted to X25519, so no re-pairing), with clatter in no_std. Over the local network it opens with link.noise in place of link.challenge; over the Relay it sends link.noise as data whenever a computer links, and accepts a session only from the computer the Relay linked. Every line after the handshake is sealed both ways; a line that doesn't open ends the session. Nothing in the clear is acted on off the cable any more. The board seals the box's output line by line (SealedLines), and drops a line it has no room for before sealing it, so a dropped line never costs the other end a nonce. The box prints LINK NOISE before BOX KEY. The app image grows by 32 KB (2,783,360 -> 2,815,808 bytes). Refs #138 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The daemon answers the box's link.noise with the initiator side of Noise_IK_25519_ChaChaPoly_SHA256 (snow), its Ed25519 pairing key converted to X25519. Over the local network the session runs behind a duplex stream, so the serial worker's session loop is unchanged; over the Relay the bridge holds outgoing lines until the session is up, sends device.hello first, and starts a new session whenever the box sends link.noise again. A sealed line that doesn't open ends the link. Firmware without Noise still links in the clear, unless the box has spoken Noise before: the daemon records that (box-noise, next to box-key) from LINK NOISE on the cable or a finished handshake, and from then on refuses link.challenge and believes nothing in the clear from that box. Only the cable can make it forget. Tests run the daemon's snow against the firmware's own clatter code. Docs: the local network handshake, the session inside the Relay, and what the Relay can see, in both READMEs. Refs #138 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bridge sends device.hello first after a handshake; a hello that was waiting for the session is dropped rather than sent a second time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The daemon's bridge read sealed lines inside select!, and the reader cleared its buffer at the start of each call: whenever the daemon sent something (a heartbeat every 5 s) while a long line was half read, that half was dropped and the session ended. A screenshot over the local network failed every time. The reader now keeps what it read across a cancelled read, and the bridge clears the line only after a whole one. On the box, every line of one write was checked against the connection's free room before any of them was sent, so the second line could still overrun the pipe and be cut. Each line is now checked, sealed and sent in turn. On the box: screenshots over the local network (3.4 s) and through relay-staging (6-10 s) now come back whole, three and two in a row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # firmware-rs/core/src/relay_box.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second step of #138, implementing ADR-0015 from #141 (merge that first).
What changes
firmware-rs/core/src/noise.rs, clatter, no_std): the box answersNoise_IK_25519_ChaChaPoly_SHA256handshakes keyed by the pairing keys (Ed25519 → X25519, no re-pairing). LAN opens withlink.noiseinstead oflink.challenge; over the Relay the box sendslink.noiseasdatawhenever a computer links and accepts a session only from the computer the Relay linked. Every line after the handshake is sealed; nothing in the clear is acted on off the cable. The board seals output line by line and drops a line it has no room for before sealing, so it never costs the other end a nonce. The box printsLINK NOISEbeforeBOX KEY.daemon/src/noise_link.rs, snow): initiator side. LAN runs the session behind a duplex stream (session loop unchanged); the Relay bridge holds lines until the session is up, sendsdevice.hellofirst, and re-handshakes on everylink.noise.LINK NOISEon the cable or finished a handshake, it records the box (box-noise) and never links to it in the clear again; only the cable can make it forget (older firmware flashed).datawas already forwarded unread.docs/protocol.md(local network link,LINK NOISE),docs/relay-protocol.md(the session inside the Relay), what the Relay sees inREADME.md/README.zh-CN.md.Release note for later
The firmware release that ships this must set
min_appto the App release that ships this daemon (its front matter indocs/releases/), so older Apps aren't offered firmware that refuses them off the cable. No UI change, so nothing for the Mac or Linux apps.Checked
cargo test --workspace: all pass; daemon tests run snow against the firmware's own clatter code (handshake, both directions, replay, busy inside the session, unpaired, downgrade refused on LAN and Relay).cargo clippy --workspace --all-targets: no new warnings.tools/build-firmware.sh: app image +32 KB (2,783,360 → 2,815,808 bytes).box-noiselearned from the handshake) and through relay-staging (sealed lines both ways).On a box
With dragon's go-ahead: App quit, box flashed with this firmware, this branch's daemon run off the cable (serial pinned elsewhere).
🤖 Generated with Claude Code