api/firmware: support host passphrase entry - #188
benma-agent wants to merge 2 commits into
Conversation
00d8217 to
3a80376
Compare
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.
3a80376 to
a2d233a
Compare
| switch reply.Unlock.State { | ||
| case messages.UnlockResponse_DONE: | ||
| return nil | ||
| case messages.UnlockResponse_PASSPHRASE_PENDING: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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: