mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +00:00
docs: passphrase migration info
This commit is contained in:
parent
577daf09fe
commit
02f2158c1d
146
docs/common/communication/passphrase-redesign-migration.md
Normal file
146
docs/common/communication/passphrase-redesign-migration.md
Normal file
@ -0,0 +1,146 @@
|
||||
|
||||
# Passphrase Redesign In 1.9.0 / 2.3.0
|
||||
|
||||
On the T1, passphrase must be entered on the host PC and sent to Trezor. On the TT, the
|
||||
user can choose whether to enter the passphrase on host or on Trezor's touch screen.
|
||||
|
||||
In versions 1.9.0 and 2.3.0 we have redesigned how the passphrase is
|
||||
communicated between the Host and the Device. The new design is documented
|
||||
thoroughly in [passphrase.md](passphrase.md) and this document should help
|
||||
with the transition from the old design.
|
||||
|
||||
## New features
|
||||
|
||||
* Passphrase flow is now identical for T1 and TT.
|
||||
* By keeping track of _sessions_, it is possible to avoid having to send passphrase repeatedly.
|
||||
* The choice between entering on Host or Device for TT has been moved from Device to Host.
|
||||
* Multiple passphrases are cached simultaneously.
|
||||
|
||||
## Backwards compatibility
|
||||
|
||||
T1 1.9.0 is fully backwards-compatible and works with existing Host code.
|
||||
|
||||
TT 2.3.0 communicating with old Host software degrades to T1-level features: entering
|
||||
passphrase on device will not be available, and on-device passphrase caching via the
|
||||
`state` field will not be available.
|
||||
|
||||
As a workaround, it is possible to use the "passphrase always on device" feature on the
|
||||
new TT firmware. When enabled, the passphrase flow is completely hidden from the Host
|
||||
software, and the Device itself prompts the user to enter the passphrase.
|
||||
|
||||
## Implementation guide
|
||||
|
||||
### Protobuf changes
|
||||
|
||||
Protobuf has built-in backwards compatibility mechanisms, so a conforming implementation
|
||||
should continue to work with old protobuf definitions.
|
||||
|
||||
To restore support for TT on-device passphrase entry, and to make use of the new
|
||||
features, you will need to update to newer protobuf definitions from `trezor-common`
|
||||
(TODO: link to commit in trezor-common).
|
||||
|
||||
The gist of the changes is:
|
||||
|
||||
- `PassphraseRequest.on_device` was deprecated, and renamed to `_on_device`. New Devices
|
||||
will never send this field.
|
||||
- Corresponding field `PassphraseAck.on_device` was added.
|
||||
- `PassphraseStateRequest`/`PassphraseStateAck` messages were deprecated, and renamed
|
||||
with a `Deprecated_` prefix. New Devices will not send or accept these messages.
|
||||
- `Initialize.state` was renamed to `Initialize.session_id`.
|
||||
- Corresponding field `Features.session_id` was added. New Devices will always send this
|
||||
field in response to `Initialize` call.
|
||||
- A new value `Capability_PassphraseEntry` was added to the `Features.Capability`
|
||||
enum. This capability will be sent from a Device that supports on-device passphrase
|
||||
entry (currently only TT).
|
||||
|
||||
### Restoring on-device entry for TT
|
||||
|
||||
The Host software reacts to a `PassphraseRequest` message by prompting the user for a
|
||||
passphrase and sending it in the `PassphraseAck.passphrase` field.
|
||||
|
||||
A new UI element should be added: when the passphrase prompt is displayed on Host, there
|
||||
should be an option to "enter passphrase on device". When the user selects this option,
|
||||
the Host must send a `PassphraseAck(passphrase=null, on_device=true)`.
|
||||
|
||||
The "enter passphrase on device" option should be displayed when `Features.capabilities`
|
||||
contain the `Capability_PassphraseEntry` value, regardless of reported Trezor version or
|
||||
model. Firmwares older than 2.3.0 or 1.9.0 never set this value, so this ensures
|
||||
forwards and backwards compatibility.
|
||||
|
||||
### Cross-version compatibility for TT
|
||||
|
||||
TT version \< 2.3.0 will send `PassphraseRequest(_on_device=true)` if the user selected
|
||||
on-device entry. Neither T1 nor TT >= 2.3.0 will ever set this field to true.
|
||||
|
||||
If the Host receives `PassphraseRequest(_on_device=true)`, it should immediately respond
|
||||
with `PassphraseAck()` with no fields set.
|
||||
|
||||
TT version \< 2.3.0 will send `Deprecated_PassphraseStateRequest(state=[bytes])` after
|
||||
receiving `PassphraseAck`. The Host should immediately respond with
|
||||
`Deprecated_PassphraseStateAck()` with no fields set. If the Host does session
|
||||
management, it should store the value of `state` as the session ID. Note that `state`
|
||||
used to be 64 bytes long, but `session_id` is only 32 bytes.
|
||||
|
||||
### Triggering passphrase prompt
|
||||
|
||||
Use `GetAddress(coin_name="Testnet", address_n=[44'/1'/0'/0/0])` (the first address of
|
||||
the first account of Testnet) to ensure that the Device asks for a passphrase if
|
||||
needed, and caches it for future use.
|
||||
|
||||
### Validating passphrases
|
||||
|
||||
You can store the result of the above call, and in the future, compare it to a newly
|
||||
received address. This is a good way to check if the user is using the same passphrase
|
||||
as last time.
|
||||
|
||||
Do not store user-entered passphrases for the purpose of validation, even in hashed,
|
||||
encrypted, or otherwise obfuscated format.
|
||||
|
||||
### Session support
|
||||
|
||||
A call to `Initialize` can include a `session_id` field. When starting a new user
|
||||
session, this field should be left empty.
|
||||
|
||||
The response `Features` message will always include a `session_id` field. The value of
|
||||
this field should be stored. When calling `Initialize` again, the stored value should
|
||||
be sent as `session_id`. If the received `Features.session_id` is the same, it means
|
||||
that session was resumed successfully and the user will not be prompted for passphrase.
|
||||
|
||||
```
|
||||
--> Initialize()
|
||||
<-- Features(session_id=0xABCDEF, ...)
|
||||
|
||||
--> Initialize(session_id=0xABCDEF)
|
||||
<-- Features(session_id=0xABCDEF)
|
||||
# (session resumed successfully)
|
||||
|
||||
--> Initialize(session_id=0xABCDEF)
|
||||
<-- Features(session_id=0x123456)
|
||||
# (session was not resumed, user will be prompted for passphrase again)
|
||||
```
|
||||
|
||||
Session support is identical on T1 and TT, and both models support multiple sessions,
|
||||
i.e., it is possible to seamlessly switch between using multiple passphrases.
|
||||
|
||||
### Cross-version compatible algorithm summary
|
||||
|
||||
The following algorithm will ensure that your Host application works properly with
|
||||
both T1 and TT with both older and newer firmwares.
|
||||
|
||||
1. If you have a session ID stored, call `Initialize(session_id=stored_session_id)`
|
||||
2. Check the value of `Features.session_id`. If it is identical to `stored_session_id`,
|
||||
the session was resumed and user will not need to be prompted for a passphrase.
|
||||
1. If `Features.session_id` is not set, you are communicating with an older Device.
|
||||
Do not store the null value as session ID.
|
||||
2. Otherwise store the value as `stored_session_id`.
|
||||
3. When you receive a `PassphraseRequest(_on_device=true)`, respond with
|
||||
`PassphraseAck()` with no fields set.
|
||||
4. When you receive a `PassphraseRequest`, prompt the user for passphrase.
|
||||
1. If `Features.capabilities` contains value `Capability_PassphraseEntry`, display a
|
||||
UI element that allows the user to enter passphrase on-device.
|
||||
2. If the user chooses this option, send `PassphraseAck(passphrase=null, on_device=true)`
|
||||
3. If the user enters the passphrase in your application, send
|
||||
`PassphraseAck(passphrase="user entered passphrase", on_device=false)`
|
||||
5. When you receive a `Deprecated_PassphraseStateRequest(state=...)`, store the value
|
||||
of `state` as `stored_session_id`, and respond with `Deprecated_PassphraseStateAck`
|
||||
with no fields set.
|
Loading…
Reference in New Issue
Block a user