trezor / trezor-firmware

:lock: Trezor Firmware Monorepo
https://trezor.io
Other
1.29k stars 639 forks source link

Redesign USB protocol (encryption + sessions) #79

Open saleemrashid opened 6 years ago

saleemrashid commented 6 years ago

Since TREZOR 2 will include a new USB protocol, we could add session encryption. This could either be optional or it could be required for the v2 protocol.

We could use ECDH to generate an ephemeral session key and display it on both the TREZOR and the computer. It could be encoded with the BIP39 word list to make it easier for the user to compare.

One reason to include this is that it would make use with Qubes OS more secure, where the USB qube can currently MITM communication with the hardware wallet.

prusnak commented 6 years ago

We are thinking among the same lines here. That's why I added chacha20poly1305 to trezor-crypto.

We also discussed the zrtp-like confirmation (2-3 words) :-))

saleemrashid commented 6 years ago

Are there plans to backport the v2 protocol to TREZOR 1?

Also, does TREZOR Core support the v1 protocol at this point in time?

prusnak commented 6 years ago

T2 supports v1 protocol.

T1 will not support v2 protocol, but we are evaluating porting of the whole trezor-core to T1 hardware.

saleemrashid commented 6 years ago

T2 supports v1 protocol.

Maybe I had something configured incorrectly because it wasn't working last I tried.

we are evaluating porting of the whole trezor-core to T1 hardware.

That would be an impressive feat! MicroPython doesn't yet support the STM32F2 as far as I know and I wonder whether there would be enough ROM space for it.

MelbourneDeveloper commented 6 years ago

Um. Wow. How did I not see this?

@saleemrashid @prusnak

I'm not sure how deep in to this change you guys are, but I recommend structuring the encryption like HTTPS. I.e. firstly the app gets the public key from the Trezor, then the app encrypts its public key with the public key from the Trezor and sends it to the Trezor. Then, both points can talk to each other by decrypting each other's messages with the private key on either device. As long as the private keys are are not exposed as a file that other apps have access to, the messages will remain encrypted just like https.

prusnak commented 6 years ago

This scheme does not provide perfect forward secrecy. There are already protocols for these. My plan is to use ECDH to exchange a shared secret. Then to show shared secret as two-three words on TREZOR and computer display. Then encrypt the protocol using the confirmed shared secret via AEAD (chacha20poly1305).

MelbourneDeveloper commented 6 years ago

Sounds great. From what I've read it seems be to very similar to HTTPS' handshaking protocol. This will be a game changer for privacy.

mcudev commented 6 years ago

One reason to include this is that it would make use with Qubes OS more secure, where the USB qube can currently MITM communication with the hardware wallet.

I was also under the impression that everything on the USB bus, that wanted to, could intercept host to device comms too because it's broadcast communication in that direction. For example, figure 2 here https://www.totalphase.com/support/articles/200472426-Beagle-Protocol-Analyzer-User-Manual

X25519 for the ECDH? Sounds neat.

andrewkozlik commented 5 years ago

So before we can even begin to discuss the protocol design we need to resolve what exactly the requirements are. Below I started a list of possible requirements. Please comment and/or propose more.

  1. Solve collision issues between Trezor Bridge and trezorctl.
  2. Support connecting multiple hosts (Trezor Bridge, trezorctl) to one device at the same time.
  3. Support connecting multiple devices to one host at the same time.
  4. Provide confidentiality of the communication.
  5. Provide assurance to the host that it is communicating with the paired device.
  6. Provide assurance to the device that it is communicating with the paired host.
  7. Be completely independent of the underlying communications protocol (USB, BlueTooth, IP).
  8. Support authentication token stored on host.
  9. Support token revocation in case token gets compromised. (Assuming we want to support 6. and 8.)
prusnak commented 5 years ago

The protocol should probably provide its version.

matejcik commented 5 years ago

Something interesting occured to me. Maybe it's useless, but posting it here just for record.

Assume that we show 3 words on the PC and on the Trezor screen, and ask users to compare that they are identical. There's some space for user confusion and the possibility that they just click through without comparing. Instead, we could display a choice of 4 words and say "Select the word displayed on PC" (similar to the idea with seed backup verification). Then after the user does all this, we could compare to the intended string and allow/refuse connection. This way, on an infected PC, the connection will just keep failing mysteriously, without the ability to override.

ph4r05 commented 5 years ago

Regarding the @matejcik note, I had the same thoughts about the comparison vs. entry. Risk of a mistake or ignoring the comparison is probably higher than the entry mechanism which enforces user to pay attention (otherwise pairing fails). If the entry is done only once during the pairing then it could be OK.

The question is which device is the entry point. If it is a host, then we may have the same problem in the Qubes OS if the user happens to have a USB keyboard, right? The entry on the Trezor is less comfortable but may increase the security level. Another option is to combine entry + comparison after pairing is finished, which adds a bit more complexity.

The Bluetooth LE pairing protocol looks quite nice and might be useful. Tldr: perfect forward secrecy (uses ECDH), supports numeric comparison method (6 digits) and passphrase entry. When pairing is done, long term secrets are derived, used for the session key derivation (active MITM protection). Alternatively, session keys could be derived simply

SHA256(ECDH(ephemeral_host, ephemeral_trezor) || long_term_pairing_sec || nonce)

The FHMQV-C protocol looks nice too.

prusnak commented 5 years ago

Related to Passphrase redesign: https://github.com/trezor/trezor-firmware/issues/1

andrewkozlik commented 5 years ago

@matejcik I like the idea of a more active user confirmation. Nevertheless, with BlueTooth you have a similar situation, where you usually compare a six digit code on two devices, so people are used to it (though not over USB) and therefore I wouldn't expect it to cause much confusion. I am more worried about user carelessness. I think this very much depends on whether we will support the authentication tokens (point 8), so that the pairing can be done only the first time with each host. If we won't support them, then the confirmation needs to be done every time the device connects, which could be a real burden.

Regarding @ph4r05 question about the entry point, if we want to provide mutual assurances to the host and device that they are communicating with a paired entity (points 5. and 6. above), then I think that the authentication words will need to be confirmed both on the host and on the device, i.e. some user action will need to be taken on each.

ph4r05 commented 5 years ago

Regarding @ph4r05 question about the entry point, if we want to provide mutual assurances to the host and device that they are communicating with a paired entity (points 5. and 6. above), then I think that the authentication words will need to be confirmed both on the host and on the device, i.e. some user action will need to be taken on each.

@andrewkozlik I agree. The confirmation should be on both devices. I was speaking about the "pairing passphrase" variant as defined by Bluetooth LE spec. If generated on Trezor and entered on the host with USB keyboard then it can be a security risk.

viralpoetry commented 5 years ago

This is more a UI design issue that must be solved. Either it's passive regarding to the user (bidirectional TOFU, for example Signal safety number comparison), or active, where user must transfer secret generated on host/trezor.

Gemalto SafeNet Luna HSMs are using Server TLS certificate downloaded via SSH from device. Client also generate one and transfer it to the device, but this protocol looks kinda out of scope, because USB can't compare x509 SANs and it's old school and complex. On the other side, Thales nShield HSMs are using symmetric hash that is generated on HSM with display, then used during HSM enrollment on a remote network machine.

I think few words showed on both sides could do the trick, as well as typing words on trezor. The most beautiful will be comparable graphic image, but I am not aware of any bulletproof visual protocol for this.

viralpoetry commented 5 years ago

And one more food for tought. After handshake, socialist millionaire protocol could be used for shared secret comparison without user interaction.

https://en.wikipedia.org/wiki/Socialist_millionaires#Off-the-Record_Messaging_protocol