Skip to content

api/firmware: support host passphrase entry - #188

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

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

Conversation

@benma-agent

@benma-agent benma-agent commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Support host entry of the optional BIP39 passphrase on firmware 9.28.0 and later. Device entry remains available while the host can request approval to enter the passphrase. Invoke host input only after device consent, and let the device confirm the submitted value before unlocking.

Keep polling and protocol handling in the library. Withdraw host-entry availability during consent and confirmation, notify clients when device entry finishes, and handle cancellation, retries and reconnects without reusing stale requests. Preserve the legacy unlock flow on older firmware.

Includes the session-reset prerequisite from #187.

Related PRs:

Unlock through the paired Noise channel on firmware 9.28.0 and later,
keeping the legacy unlock command for older firmware. The new workflow
starts device entry when the optional passphrase feature is enabled and
lets the host request device consent to enter the passphrase on the host.
Uninitialized and already unlocked devices finish immediately.

Expose two callbacks through PassphraseConfig. The availability callback
receives a callable that queues a host-entry request and wakes the polling
loop without doing transport I/O. Notify once per entry phase, withdraw
when consent starts or device entry finishes, and offer a fresh callable
on retry. Separate buffered channels keep delayed or duplicate clicks
from affecting later phases. Without an availability callback, request
host entry once automatically and fall back to device entry on rejection
or cancellation.

Call the blocking input callback only after device approval. A string,
including the empty string, submits input; nil cancels and resumes device
entry. The device confirms the actual passphrase. Keep protocol handling
and device-entry polling inside the library, holding the API lock for the
entire unlock so other queries cannot interrupt its continuations.

Notify clients when device passphrase entry finishes, before confirmation starts. This lets the
app show the confirmation prompt even when device entry wins a simultaneous host-entry request.

Use the device lifetime context to release host input on Close, and make
Close idempotent because disconnect handling and unlock cancellation can
both close the transport. Ignore repeated pairing approvals to avoid
starting duplicate unlocks. Clear temporary protobuf plaintext buffers
after each query. On local failure, withdraw availability, attempt RESET
and close the connection; reconnect uses the preceding session-reset
commit. Keep resetSession's explicit firmware version check independent
of host-passphrase support.

Add simulator coverage for initialization, device passphrase entry, disabled passphrases,
simultaneous host requests, stale clicks, repeated unlocks and repeated closes.
@benma-agent
benma-agent force-pushed the benma-agent/host-passphrase branch from 3a80376 to a2d233a Compare September 29, 2026 10:12
Comment thread api/firmware/unlock.go
switch reply.Unlock.State {
case messages.UnlockResponse_DONE:
return nil
case messages.UnlockResponse_PASSPHRASE_PENDING:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please preserve macOS sleep inhibition throughout the paired-unlock workflow. When the password request returns PASSPHRASE_PENDING, rawQueryV7() runs its deferred sleep.Allow(). Subsequent immediate polling responses leave sleep uninhibited while the user enters the passphrase on the BitBox. This loses the protection provided by the legacy blocking unlock request.

The fix needs to account for nested calls: simply wrapping unlock() with Prevent()/Allow() is insufficient because the existing sleep helper isn’t reference-counted.

Verified with an instrumented protocol test showing Prevent → Allow before device passphrase entry finishes; not tested on macOS hardware.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in fixup commit 703e1ef. Sleep inhibition now covers the full unlock workflow, and the helper uses a mutex-protected reference count so nested transport calls cannot release it early.

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