Skip to content

Host passphrase #1393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft

Host passphrase #1393

wants to merge 3 commits into from

Conversation

benma
Copy link
Collaborator

@benma benma commented Apr 1, 2025

This is a quick prototype for optionally allowing entering the passphrase on the host by adding a new UnlockRequest API call that allows this.

We might split this into two calls, one for unlocking the device and one for entering the passphrase, so the bbapp knows which state we are in. Alternatively, we could keep one UnlockRequest API, but send state updates to the app via next_request(). It is not clear yet which would be better.

benma added 3 commits March 31, 2025 08:57
We had two separate checks to decide if we will allow a protobuf
message API call to proceed: in hww.rs (forbid if initialized and
locked) and in api.rs in the can_call() function that defines which
states the API call can run in.

This makes it a bit hard to follow as split into two locations, and it
also prevents us from introducing a protobuf call that is only allowed
to run if the device is initialized but still locked. `Unlock` would
be such a useful new API call if we want to allow entering the
passphrase on the host.

The hww.rs check passed if `!initialized || !locked`,
which means the same as `uninitialized || seeded || unlocked`.

We change the `can_call` state checks to include this condition. For
this we split the local `Initialized` state into
`InitializedAndLocked` and `InitializedAndUnlocked`. For each line in
can_call, the two conditions are combined. The equivalent state check
in the end is simply to convert all `Initialized` checks to
`InitializedAndUnlocked`.

The `true` entries become explicit as they can't include
`InitializedAndLocked` (e.g. can't change the name using `DeviceName`
if initialized but not yet unlocked).
So one can make a binary choice by leaving the middle one empty.
Previously, the host would unlock before the noise channel was
established using `OP_UNLOCK`, using a raw unencrypted call that is using
protobufs.

To support entering a passphrase on the host, we add a `UnlockRequest`
protobuf message. This needs to happen after the noise channel was
established because:
- we want the passphrase to be encrypted in flight
- we want to make use of protobuf and `next_request()` to query the
  host

`UnlockRequest` has a flag `supports_host_passphrase`, so
wallets (especially third party apps) that do not support this yet
still work seamlessly, as without support the passphrase is simply
entered on the device.

If the host app supports it, then the device will ask the user if they
want to enter on the device or on the host.

The query to the host uses `UnlockRequestHostInfoResponse`. It
contains the `type` enum for future compatbilitiy in case we want to
add more unlock options in the future (e.g. fingerprints).

The `workflow::unlock` calls now get a callback to pick the method of
entering the passphrase, so the old `OP_UNLOCK` can use the previous
way, while `UnlockRequest` provides a callback to ask the user where
to enter and proceeds accordingly.
@benma benma force-pushed the host-passphrase branch from 0b40455 to 30e47f1 Compare April 1, 2025 12:21
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