Skip to content

add host passphrase entry and typed device states - #137

Open
benma-agent wants to merge 5 commits into
BitBoxSwiss:masterfrom
benma-agent:benma-agent/host-passphrase
Open

benma-agent wants to merge 5 commits into
BitBoxSwiss:masterfrom
benma-agent:benma-agent/host-passphrase

Conversation

@benma-agent

Copy link
Copy Markdown
Contributor

Add configurable host passphrase entry for firmware v9.28.0 and later,
supporting automatic entry or an optional host-entry button. Prompt for the
passphrase only after device approval, and keep legacy unlocking for older
firmware.

Introduce PairedBitBox::{Locked, Unlocked, Uninitialized} so wallet operations
are only available on UnlockedBitBox. This changes wait_confirm() to return
the appropriate state; initialized devices on newer firmware use an explicit
LockedBitBox::unlock() after pairing.

Includes copied firmware protobufs, simple CLI and Cursive examples, and
separate U2F fixes for the final continuation frame, payload size checking,
and encoding error propagation.

The sequence counter is incremented after writing each continuation
frame. After frame 127 it becomes 128, causing the encoder to reject a
valid completed message. This affects payloads of 7,551 to 7,609 bytes.

Only report too many frames if there is still payload left to encode.
The encoder casts message lengths to u16 before checking the required
buffer size. Lengths above u16::MAX wrap, making that check unreliable;
other oversized messages are only rejected later by buffer or frame limits.

Reject payloads above the 7,609-byte U2F HID limit before narrowing the
length or writing any frames.
U2fHidCommunication::write unconditionally unwraps the framing result.
If a message is too large for U2F HID, encoding returns an error and the
library panics instead of returning a transport error.

Add U2fEncode and propagate encoding failures through ReadWrite::write.
Introduce a PairedBitBox enum with locked, unlocked and uninitialized
variants backed by a private session. Expose wallet operations only on
UnlockedBitBox, and consume UninitializedBitBox when restoring a wallet.

Keep device entry and unlock before pairing on every firmware version.
Validate the legacy unlock response to distinguish an unlocked wallet from
an uninitialized device. Reserve LockedBitBox::unlock for a later transition;
the connection flow cannot return that state yet.

Adapt existing examples and simulator helpers to the typed states.
@benma
benma requested a review from Beerosagos October 13, 2026 10:43
@benma
benma marked this pull request as ready for review October 13, 2026 10:43
@benma

benma commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

This is a breaking API change, but this library is on version 0., so it's expected by semver policy. I think the change is important to support the new passphrase in sane way and also to make the UnitializedBitBox methods type-safe (before they were just in the PairedBitBox struct, so they and the regular api fnctions could be called in the wrong state)

Use paired protobuf unlock on firmware v9.28.0 and later, returning
LockedBitBox after pairing and completing the transition through
LockedBitBox::unlock. Keep legacy device entry on older firmware.

Add PassphraseConfig with asynchronous input and optional availability
callbacks. Integrations can offer a host-entry button while device entry
is available, or request host entry automatically. Invoke the input callback
only after approval on the device. Expire stale request handles and reset
the session when unlocking fails.

Copy the firmware protobuf definitions and regenerate the Rust bindings.
Add a simple automatic CLI example and a Cursive example with a host button.
@benma-agent
benma-agent force-pushed the benma-agent/host-passphrase branch from 205c76e to 7f503d8 Compare October 13, 2026 10:58

This branch has not been deployed

No deployments
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.

2 participants