Isn't this overkill? I mean, writing an encrypted copy of the seed on a USB key doesn't sound dangerous. And it's much easier and less error prone for the user than manually copying it from what's displayed.
Writing to a USB key would require the wallet be capable of being a USB host, as opposed to merely being a USB device. Being a USB host requires far more processing resources than being a USB device. IMO, it just isn't worth the extra complexity and cost. An easier alternative to manually writing down the seed would be to take pictures of the display.
I guess that it would increase complexity, but do you think it's feasible to implement "hidden volumes" like Truecrypt does, in order to have plausible deniability against
this kind of attack (works as long as the attacker doesn't know for sure how much you've got)?
Hidden wallets are a feature I plan to add. I intentionally made the "format storage" command write random data everywhere (instead of all 00s) for this reason.
I had a couple of comments on your protocol:
+ You do not specify the character encodings you are using. For the bitcoin addresses and public keys ASCII will be fine but for the wallet names I would use UTF8 to make it internationalisable (depends if you can display it I guess)
Good point. Currently, the wallet doesn't ever display or parse the wallet name (the wallet name is just there for the convenience of the host), so adding this feature requires no additional code.
+ You have some powerful commands (format, change encryption key) that an attacker can use with no constraints on their use. For instance, a point of sale device that you only want to send sign requests can format your device. Or they can change the encryption password and hold your BTC to ransom. Perhaps you need a 'hardware protect' physical switch to stop this - maybe you have this already.
Just like with transaction signing, all powerful commands require approval from the user. I haven't done this with the "change encryption key" command yet because I'm still figuring out how to deal with ransom attacks.
One major problem I've identified with the hardware Bitcoin wallet is that since its input user interface consists solely of two pushbuttons, there's no way to get a wallet password into it. Currently, the host is supposed to provide an encryption key derived from a password, and this is bad because:
1. The user must type the password using the host's keyboard and the host may have a keylogger.
2. The host may have an advanced trojan which covertly mixes a "ransom key" into the encryption key, lets you load BTC into a wallet, then holds those BTC for ransom.
How can these flaws be dealt with? Here are the ideas I've come up with:
- Keep things the way they are. Rely on the assumption that even if an attacker has your wallet password, they probably won't have physical access to your hardware Bitcoin wallet, so they still can't do anything nasty. Rely on wallet backups to mitigate ransom attacks.
- Change the protocol so that the wallet password is sent in cleartext over the serial port. Then, the wallet has the opportunity (when setting or changing the wallet password) to display the password, allowing the user to detect if a "ransom key" has been inserted.
- Add a USB port to the hardware Bitcoin wallet and allow the user to plug a USB keyboard into the wallet and directly enter the wallet password.
I like the last option the most, but it does involve additional cost (+0.20 to 0.40 USD for quantity = 1000) and complexity*. Also, since the key derivation function is evaluated on the hardware Bitcoin wallet, it can't be as strong, since the microcontroller on the device will be orders of magnitude less powerful than a modern CPU or GPU.
Can anyone think of a better way to deal with ransom attacks?
I am hardware-phobic but very impressed. Do you wantto makethis device tamper proof? Like erase memory when you detect that someone is trying to open the case?
It would be nice to have tamper proof features and there are microcontrollers out there which have such features. But the semiconductor manufacturers all seem to require the signing of an NDA (that goes against my goal of openness) and probably won't bother talking to me unless I commit to an order of at least 10,000 units. I figure it's not such a big deal: Bitcoins are transferrable. If your wallet is compromised or stolen, you create a new one and use a wallet backup to transfer everything to the new wallet.
That would require the device to recognize the signature. A standard like what's done for HTTPS could be created, with the device trusting a priori a set of CA root certificates, and people signing their URI's with a signed cert. But this set of root certs would need to evolve once in a while. The only way to "safely" update such set of trusted CA is by signing the update with a manufacturer's private key, which the device always trust. That only works as long as the manufacturer doesn't lose control to this key.
Difficult to implement, with some level of danger still, but yeah, a possibility, and certainly much better than nothing.
I don't know whether merchants would like to adhere to this protocol though. It would probably make their life easier if the same certificate they use for HTTPS could be used for this, at least they don't have to pay two different CA's.
It may be possible to verify signed Bitcoin addresses on a hardware Bitcoin wallet, as long as the signatures are generated using ECDSA (and preferably using the curve secp256k1). Most of the code needed to verify a signature is already implemented, because signature verification is similar to signature generation. Also, ECDSA public keys are only 64 bytes each, so there will probably be enough spare space to fit a couple in a firmware binary. Nevertheless, I don't think I'll implement this feature in the near future.
*There's a bit of a cheat I can use here. As I mentioned above, being a USB host is difficult. But most (maybe all?) USB keyboards are also PS/2 keyboards: those USB-to-PS/2 dongles they come with simply re-route the USB pins to PS/2 pins. The keyboard uses some electrical checks to determine whether it is plugged into an actual USB port or a USB-to-PS/2 dongle. Thus it's possible to trick a USB keyboard into using the PS/2 interface, and the PS/2 interface is much easier to work with than the USB interface.