Speakers: Stepan Snigirev
Date: June 29, 2019
Transcript By: Bryan Bishop
- Extracting seeds from hardware wallets
- The future of hardware wallets
- coredev.tech 2019 hardware wallets discussion
A bit more than a year ago, I went through Jimmy Song’s Programming Blockchain class. That’s where I met M where he was the teaching assistant. Basically, you write a python bitcoin library from scratch. The API for this library and the classes and fnuctions that Jimmy uses is very easy to read and understand. I was happy with that API, and what I did afterwards was that I wanted to move out of quantum physics to working on bitcoin. I started writing a library that had a similar API- took an arduino board and wrote a similar library that had the same features, and extra things like HD keys and a few other things. I wanted to make a hardware wallet that is easy to program, inspired by Jimmy’s class. That’s about when I met and started CryptoAdvance. Then I made a refactored version that doesn’t require arduino dependencies, so now it works with arduino, Mbed, bare metal C, with a real-time operating system, etc. I also plan to make a micropython binding and embedded rust binding.
I am only considering three hardware wallets today- Trezor, Ledger and ColdCard. Basically all others have similar architectures to one of these. You might know that Trezor uses a general purpose microcontroller, like those used in microwaves or in our cars. These are more or less in every device out there. They made the choice to only use this without a secure element for a few reasons- they wanted to make the hardware wallet completely open-source and say for sure what is running on the hardware wallet. I do not think they do not have any secure element in the hardware wallet unless we develop an open-source secure element. I think our community could make that happen. Maybe we could cooperate with Trezor and Ledger and at some point develop a secure element based on the RISC-V architecture.
I think we need several types of secure elements for different security models. You want to diversify the risk. You want to use multisig with Schnorr signatures. You want different devices with different security models, and ideally each key should be stored with different hardware, and different security models in each one as well. How will the vulnerabilities appear? It could be a poorly designed protocol, hopefully you won’t have a bug in that but sometimes hardware wallets fail. It could be a software vulnerability where the people who wrote the software made a mistake, like overflows or implementation bugs or some not-very-secure cryptographic primitives like leaking information through a sidechannel. The actual hardware can be vulnerable to hardware attacks, like glitching. There’s ways to make microcontrollers not behave according to their specification. There can also be hardware bugs as well, which happen from time to time, and just because the manufacturer of the chip can also make mistakes- most of the chips are still designed not automatically but by humans. When humans put transistors and optimize this by hand, they can also make mistakes. There’s also the possibility of government backdoors, which is why we want an open-source secure element.
There was a talk sometime ago about instructions in x86 processors where basically, they have specific set of instructions that is not documented and not— they call it Appendix H. They share this appendix only with trusted parties ((laughter)). Yeah. These instructions can do weird things, we don’t know exactly what, but some guy was able to find all of the instructions. He was even able to get privileges from the user level, not just to the root level but to the ring-2 level, complete control that even the operating system doesn’t have access to. Even if you run tails, it doesn’t mean that the computer is stateless. There is still a bunch of crap running under the OS that your OS doesn’t know about. You should be careful with that one. On librem computers, they have not only PureOS but also Qubes that you can run and also they use the – which is also open– basically you can have … check that it is booting the real tails. The librem tool is called heads not tails. You should look at that if you are particularly paranoid.
Librem computers have several options. You can eiher rune PureOS or you can run Qubes or tails if you want. The librem key checks the bootloader.
Ledger hardware wallets use a secure element. They have a microcontroller also. There are two different architectures to talk about. Trezor just uses a general-purpose MCU. Then we have ColdCard which is using a general-purpose MCU plus it adds on top of that a secure– I wouldn’t call it a secure element, but it is secure key storage. The thing that is available on the market, ColdCard guys were able to convince the manufacturer to open-source this secure key storage device. So we hope we know what is running on the microcontrollers, but we can’t verify that. If we give you the chip, we can’t verify it. We could in theory do some decapping. With decapping, imagine a chip and you have some epoxy over the semiconductor and the rest of the space is just wires that go into the device. If you want to study what is inside the microcontroller, what you do is you put it into the laser cutter and you first make a hole on the device and then you can put here the nitric acid that you heat up to 100 degrees and it will dissolve all the plastic around it. Then you have a hole to the microcontroller, then you can put this into an optical microscope or electron microscope or whatever you have and actually study the whole surface there. There was an ATmega that someone decapped and it was still able to run. There was a talk at defcon where the guys showed how to make DIY decappers. You could take a trezor or other hardware wallet and you put it on a mount, and then you just put the stream of nitric acid to the microcontroller and it dissolves the plastic but the device itself can still operate. So while you’re doing some cryptography there, you can get to the semiconductor level and put it under the microscope and observe how exactly it operates. Then when the microcontroller operates, you can see how the plastic– not only with the microscope but even also with— like when a transistor flips between 0 and 1, it has a small chance of emitting a photon. So you can watch for emitted photons and there’s probably some information about the keys given by that. Eventually you would be able to extract the keys. You cut the majority of the plastic then you put in the nitric acid to get to the semiconductor level. In this example, the guy was looking at the input and output buffer on the microcontroller. You can also look at the individual registers. It’s slightly different for secure elements or secure key storage, though. They put engineering effort into the hardware side to make sure that it is not easy to do any decapping. When the cryptography is happening on the secure element, they do have certain regions that are dummy parts of the microcontroller. So they are operating and doing something, but they are trying to fool you about where the keys are. They have a bunch of other interesting things there. If you are working with security-focused chips, then it’s much harder to determine what’s going on there. The other thing though is that in the ColdCard the key storage device is pretty old so that is why the manufacturer was more willing to open-source it. If we are able to see what is running there, that means the attacker will also be able to extract our keys from there. So being able to verify the chips, also shows that it is not secure to users. So being able to verify with decapping might not be a good thing. So it’s tricky.
Secure key storage element (not a secure element)
Normally the microcontroller asks the secure storage to give the key to move it to the main microcontroller, then the cryptographic operations occur, and then it is wiped from the memory of the microcontroller. How can you get this key from the secure key storage? Obviously you need to authenticate yourself. In ColdCard, you do this with a PIN code. How would you expect the wallet to behave when you enter the wrong PIN code? In Trezor, you increase a counter and increase the delay between PIN entries, or like in Ledger where you have a limited number of entry attempts before your secrets get wiped. ColdCard is using the increased delay mechanism. The problem is that this delay time delay is enforced not by the secure element but by the general-purpose microcontroller. To guess the correct PIN code, if you are able to somehow stop the microcontroller from increasing the time, then you would be able to bruteforce the PIN code. To communicate with the key storage, the microcontroller has a secret stored here, and hwenever it uses the secret to communicate with the key storage, then the key storage will respond. If the attacker can get this secret, then he can throw away the microcontroller and use his own equipment with that secret and try all the PIN combinations until he finds the right one. This is because of the choice they did where basically you can have any amount of tries for the PIN code for the secure element. This particular secure key storage has the option to limit the number of PIN entry attempts. But the problem is that it is not resettable. This means that for the whole lifetime of the device, you can have a particular number of wrong PIN entries and then you can just as you reach this level you throw away the device. This is a security tradeoff that they did. I would prefer actually to set this limit to say 1000 PIN codes, or 1000 tries, and I doubt that I would fail to enter the PIN code 1000 times. For the ColdCard, they use a nice approach for PIN codes where you have it split into two parts. You can use arbitrary length, but they recommend something like 10 digits. They show some verification words, which helps you verify that the secure element is still the right one. So if someone flips your device for another one, in an evil maid attack, then you would see that there are different words and you can stop entering the PIN. There was actually an attack on the cold card to bruteforce it. The words are deterministic from the first part of your PIN code. Maybe you try multiple digits, and then you write down the words, and you make a table of this, and then when you do the evil maid attack, then you put in that table so that it shows the information to the user. You need to bruteforce the first few PIN numbers and get those words, but the later words are hard to figure out without knowing the PIN code.
Evil maid attacks
No matter what hardware wallet you have, even a Ledger with the nicest hardware– say I take it and put it in my room and put a similar device there that has a wireless connectivity to an attacker’s computer, then it’s a bridged to the real Ledger, and I can have this bidirectional communication and do a man-in-the-middle attack. Whatever the real Ledger shows, I can display on this device and fool the user. I can become an ultimate man-in-the-middle here. Whatever the user enters, I can see what he enters and I know the PIN code and then I can do everything. There are two ways to mitigate this attack— you can use a Faraday cage every time you’re using the hardware wallet, and the second way is to enforce it on the hardware and I think the Blockstream guys suggested this– you have a certain limit on the speed of light, so you can’t communicate faster than the speed of right? Your device is here. If you are communicating with this device here, then you can enforce that the reply should come within a few nanoseconds. Then it is very unlikely that– it is not possible by the laws of physics to get the signal to your real device and then get back.
What about using an encrypted communication channel with the hardware wallet? The attacker is trying to get the PIN code. It’s still vulnerable. Instead of entering the PIN code, you instead use a computer— then you have your hardware wallet connected to it, and then in the potentially comrpomised situation we have this malicious attacker that has wireless connectivity to the real hardware wallet. Say our computer is not compromised. Over this encrypted channel, you can get the mask for your PIN code– like some random numbers that you need to add to your PIN code in order to enter it on the device. Your MITM doesn’t know about this unless he compromises your computer as well. Or a one-time pad situation. Every time you enter the PIN code, you enter the PIN code plus this number. Could work with a one-time pad. When you are operating with your hardware wallet, you probably want to sign a particular transaction. If the attacker is able to replace this transaction with his own, and display to you your own transaction then you are screwed. But if the transaction is passed encrypted to the real hardware wallet, then he can’t replace it because yeah it would be unauthenticated.
Ephemeral disposable hardware wallets
Another way to get rid of the secure key storage is to make the whole hardware wallet ephemeral, so you focus on guarding the seed and the passphrase and enter it each time. The hardware wallet is disposable then. You might never return to use that hardware wallet again. I was thinking about this regarding secure generation of mnemonics on a consumer device. If you have a disposable microcontroller but everything else we’re sure doesn’t have any digital components or memory, then each time we could replace the microcontroller with a new one and the old one we just crush with a hammer. If you already remember the mnemonic, well the PIN discourages you from remembering it. If you use disposable hardware, and it’s not stored in the vault then when someone accesses the vault then they don’t see anything and don’t know what your setup really is.
Offline mnemonic generation and Shamir secret sharing
I prefer 12 word mnemonics because they are easier to remember and they still have good entropy, like 128-bit entropy. I can still remember the 12 words. I would back it up with a Shamir secret sharing scheme. We take our mnemonic and split it into pieces. If you remember the mnemonic, then you don’t need to go recover your shares. Not all shares are required to recover the secret, but you can configure how many shares are required.
If you are worried about your random number generator, then you should be adding user entropy. If you have a tampered random number generator and you’re adding user entropy anyway, the nit doesn’t matter. Older laptops can be a problem, like 32-bit machines and the wallets might not support 32-bit CPUs anymore or something. If your wallet was written for python2.6…. now you have to write something to handle big integers, etc. This is a lot of bitrot in just 5-7 years.
Regarding offline mnemonic generation or secure mnemonic generation… use a dart board, use dices, do you trust yourself to generate your entropy? I am thinking about something like that– we have true random number generators in the chips; we can ask the chips for the random numbers, then use those numbers, and then display them to the user. The word and the corresponding index. We also know that circuits degrade over time, so random number generators could be compromised in a predictable way based on hardware failure statistics.
You can roll some dice, then take a photo of it. If I’m building a malicious hardware wallet and I want to steal your bitcoin, this is by far the most easy way. Maybe the hardware is great, but the software I’m running isn’t using that hardware random number generator. Or maybe there’s a secret known to the attacker. You wait a few years, and then you have a great retirement account. You could also enforce a secure protocol that allows you to use a hardware wallet even if you don’t trust it. You can generate a mnemonic with user entropy and verify that entropy was in fact used.
Signatures leaking private keys due to non-random nonces chosen by the hardware wallet
If I am still an evil manufacturer of the hardware wallet, and I was forced by the community to include this entropy verification mechanism, and I also want the community to like me, so we say we have a completely airgapped solution with QR codes and cameras… and say you can use any software wallet you want because it works with everything. Now you have a setup like this; say you have an uncompromised computer, only a compromised hardware wallet which was manufactured by evil means. You are preparing the unsigned transaction here, you pass it to the hardware wallet using the QR codes. The hardware wallet then displays you the information and you verify everything is correct, and you verify on the computer as well. Then you sign it, and get back the signed transaction. Then you get a perfectly valid bitcoin transaction that you verify is correct and you broadcast it to the network. It’s the nonce attack. Yes, exactly. The problem is that the signature in bitcoin has two numbers, one is a random nonce. Our hardware wallet can choose a deterministically-derived nonce or random nonce to blind the private key. If this nonce is chosen insecurely, either because you’re using a bad random number generator that isn’t producing uniformly random values, or because you’re evil, then just by looking at signatures I will be able to get information about your private key. Something like this happened with yubikey recently. There was FIPS-certified yubikeys and they were leaking your private keys within 3 signatures. The stupid thing is that they introduced the vulnerability by mistake when they were preparing their device for the certification process, which asks you to use random numbers but actually you don’t want to use random numbers– you want to use deterministic derivation of nonces because you don’t trust your random numbers. You can still use the random numbers, but you should use it together with deterministic nonce derivation. Say you have your private key that nobody knows, and you want to sign a certain message…. ideally it should be HMAC something…. This is the nice way, but you can’t verify your hardware wallet is actually doing this. You would have to know your private key to verify this, and you don’t want to put your private key in some other device. Also, you don’t want your device to be able to switch to malicious nonce generation. You want to make sure your hardware wallet cannot choose arbitrary random nonces. You can force the hardware wallet to use not just the numbers it likes, but also the numbers that you like.
You could send the hash of the random number you will be using, such that the hardware wallet doesn’t need to use an RNG, it can use a deterministic algorithm to derive this R value. It would be a pretty secure communication scheme in both cases for both software and hardware but not both of them at the same time. One of them should be fine.
All the hardware wallets currently ignore this. I am preparing a proposal to include this field into bip174 PSBT. Our hardware wallet will definitely support it. I want to build a system where you don’t need to trust the hardware wallet too much, even if it is compromised or if there are bugs. All hardware wallets are hacked from time to time.
With dummy keys, you can check that the signatures are generated determinsitically and make sure it is happening and then you feel safe with the hardware wallet maybe. But switching from this deterministic algorithm to the malicious one can happen at any times. It could be triggered by a hardware update or some phase of the moon, you can’t be sure.
Another solution was that you can use verifiable generation of these random nonces, I think this was proposed by Pieter Wuille. For this you need a particular hashing function that supports zero-knowledge proofs that you were using this algorithm without exposing your private keys. The problem here is that it is very heavy computation for a microcontroller, so you’re probably not going to get it into a microcontroller.
There is also an idea about using sign-to-contract as an anti-nonce-sidechannel measure.
Ledger and multisig
If you have p2sh multisig and this wallet was only one of the signatures, then even if it was malicious then it doesn’t control all the keys– and ideally you’re using different hardware for the other keys. The problem with multisignature is that… well, Trezor supports it nicely. I am very happy with Trezor and multisig. ColdCard released firmware that supports multisig about a day ago. Ledger has terrible implementation of multisignature. What I was expecting from the wallet to show when you’re using multisignature, you want to see your bitcoin address, and you want to see what is the amount that you are actually sending or signing? What is the change output? What are the amounts? With Ledger multisig, you always see two outputs and you don’t know which one you are spending and which one is change address if any. With two Ledgers in a multisig setup, you are less secure than using a single Ledger. If anyone wants to make a pull request to the bitcoin app of Ledger, please do so. It’s there, people are complaining about this issue for more than a year I think. Ledger is not very good at multisignature.
I know about a few supply chain attacks, but those relied on users doing stupid things. I’m not aware of any targeted hardware attacks. Right now the easiest way to attack someone’s hardware wallet is to convince them to do something stupid. I think at the moment there’s just not enough hackers looking into this field. But the value is going to increase. There have definitely been software wallet attacks.
walletrecoveryservices.com sells some of this as a service for hardware wallet recovery. The Wired magazine editor lost his PIN code or something, and he did a lot of work to get the data off the device. So this isn’t a malicious attack, but it is nonetheless an attack.
You should be wary of closed-source third-party hardware devices without a brand name. How do you trust any of this?
Right now it might be easier to get cryptocurrency by launching malware or starting a new altcoin or something or a hard-fork of another altcoin. Those are the easiest ways. Right now it’s easy to target lightning nodes and take money there; you know their public addresses and how much money they have, so you know that if you can get to the server then you can recover your cost of attack. So those targets are much more obvious and easier to attack at this point. There are easier remote attacks at this point, than attacking hardware wallets.
Downsides of microcontrollers
How do secure elements work? Seems like a silver bullet that does everything, right? I can tell you the difference between normal microcontrollers and secure elements. The normal microcontrollers are made for speed, efficiency and they are made easy to develop for. There are so-called security bits that you set when you’re done programming your microcontroller. When the microcontroller boots, so how you would imagine is that it should boot with no-read no-write permissions and then checks the security bits to see whether you should be able to communicate with it, and then you should allow it to have read/write access. But sometimes it’s done the other way around, where the microcontroller is in an open mode for read-write and then it checks the security bits and then locks itself. But the problem is that if you talk to the microcontroller before it was able to read those bits, then you might be able to extract a single byte from microcontroller flash memory. You could keep doing this by doing rebooting over and over again; if you are fast and the microcontroller is slow, you can do this even faster. I think this is something that Ledger is referencing in all their talks– this “unfixable attack” on all microcontrollers like Trezor and others. I think it’s related to this, because this is exactly the thing that is broken by design and cannot be fixed just because the system evolved like this. No, they don’t need to use low temperature here. You just need to be faster than the microcontroller, which is easy because the microcontrollers used in hardware wallets are 200 MHz or so. So if you use a GPU or a modern computer then you would be able to do something.
So the threat is that the microcontroller’s memory would be able to be read, before it can lock itself down? The problem is that you can read out the whole flash memory. This means that even if it is encrypted, you have a key somewhere to decrypt it. What is stored on the flash memory? What is being protected here? Some have secret keys. All the IoT devices probably have your wifi password. There are plenty of different secrets that you might want to protect. The decryption key could in theory be stored somewhere else. Sounds like the threat is that the microcontroller can expose data written on them, and maybe you care about that because it’s proprietary data or a secret or a plaintext bitcoin private key then that’s a huge problem. If you have a microcontroller in some computing device that you have programmed… sounds like this threat is less interesting. Yes, that’s why most people don’t care about the microcontroller. In consumer devices, normally people do even easier things. They forget to disable the debug interface, and then you have direct full access to the microcontroller with like JTAG or something. So you can read out flash memory or this other stuff, and reprogram it if you want.
There’s also the JTAG interface. There’s another standard too, serial wire debug interface (SWDI). These interfaces are used for debugging. They allow you during development to see and completely control the whole microcontroller, you can set breakpoints, you can observe the memory, you can trigger all the pins around the device. You can do whatever you want using these interfaces. There’s a way to disable this, and that’s what manufacturers of hardware wallets do. Or another security bit, but again the security bit is not checked at the moment of boot, but a little bit later, so it’s another race condition. Ledger forgot to disable JTAG interface on the microcontroller that controls their display, some time ago. But they still had a secure element, so it wasn’t a big deal. Yes, disabling it is a software thing. All the security bits are software-measures. You just set the flags for your firmware to disable certain features.
Also, the microcontrollers like the normal ones, they are designed to work in certain conditions. In the temperature range from here to here, or the voltage level or power supply here from 1.7 volts to +- 0.2 volts, and with a clock rate within a certain range. What happens if this environment changes? You can get undefined behavior, which is exactly what the attacker wants. What this means is that the microcontroller operated beyond those limits could skip instructions, make miscalculations, it can do lots of different things. It can also reboot. It can skip instructions, or make incorrect calculations.
As an example, one of the attacks on the Trezor hardware wallets using this stuff was ….. when they connect the Trezor to my computer over USB, the computer asks the device who are you and how can I help you? What kind of device are you? The Trezor says I am Trezor model G for example. Then what the attacker was able to do- even before you unlock your hardware wallet- how this data is sent over to the computer… Trezor is basically checking what is the length it should send to the computer? And this length is calculated during certain instructions. If you breach the microcontroller at this time, and make this calculation do something random, like more than the 14 bits the hardware wallet is expecting, you get not only the trezor model X information but also in addition to that you would be able to get the mnemonic and the full content of the memory. The model information was stored right next the mnemonic information. They fixed this, though. Right now, you have to unlock the Trezor with the PIN, it doesn’t send any data out at all until unlocked. There’s some non-readable part of memory that the microcontroller can’t read; so if there’s overflow, it will throw an error and not be able to read those bits. So this is also a good approach. In principle, they made a lot of fixes recently. This was a software fix not a hardware fix.
The mnemonic phrase on the hardware wallet was stored plaintext and the PIN verification was vulnerable to a sidechannel attack. Another big attack for microcontrollers is sidechannel attacks. When microcontrollers are comparing numbers, they can leak information by just consuming different amounts of power, or taking a slightly different amount of time to calculate something. Trezor was vulnerable to this as well, some time ago, in particular to PIN code verification. So they were verifying this by you entering a PIN and comparing to a stored PIN. This comparison was consuming different cycles, different patterns were causing different– by observing the emission of this sidechannel from the microcontroller, LedgerHQ was able to distinguish between different digits in the PIN. They built a machine learning system to distinguish between the systems and after trying 5 different PINs, this program was able to say your real PIN. 5 PINs was still doable in terms of delay, so you can do it in a few hours. This was also fixed. Now PIN codes aren’t stored in plaintext; now they use it to derive a decryption key that decrypts the mnemonic phrase. This way is nicer because even if you have a wrong PIN, the decryption key is wrong and then you can’t decrypt the mnemonic and it’s not vulnerable to any kind of sidechannel attack.
On the hardware side, there’s race conditions, sidechannel attacks, operating environment manipulation, and debug interfaces for microcontrollers. You could also decap it and shoot it with lasers or something, and make it behave in a weird way. So this can be exploited by an attacker.
Secure elements again
On the other hand, what does a secure element do? They are similar to microcontrollers, but they don’t have debug interfaces. They don’t have the read-write flags. They also have a bunch of different countermeasures against these attacks, for example hardware measures. There is a watchdog that monitors the voltage on the power supply PIN and as soon as it sees it goes below some value, it triggers the alarm and you can erase the keys as soon as you see this occur. Or you just stop operating. If you see the voltage supply is varying, you just stop operation. If you see the temperature is changing too much, you can also stop operation. You could either stop, or erase your secrets. There’s also this mechanism that allows the microcontroller to detect if you are trying to decap, like with a simple light sensor. If you decap the chip, you have access to the semiconductor and you can see a lot of light coming out and then you stop operations. Here you definitely want to wipe your secrets clean and delete all of those. They also use a bunch of interesting techniques against sidechannel attacks. For example, they don’t do just constant power consumption and constant timing, but then on top of that they introduce additional random delays and random noise on the power lines making it more and more difficult for the attacker to get any data from there. They also normally have a very limited capacity on bits. You have power supply pin, ground, maybe a few more to drive something simple like an LED on the ColdCard or on the modern Ledger Model X they are actually able to talk to the display driver to control the display which is a nice improvement on the hardware. In principle, it is not very capable. You can’t expect the secure element to drive a large display or to react to user input. Button is probably fine, but definitely not the best thing.
The reason why the Ledger has a tiny screen with low resolution is because they are trying to drive everything from the secure element, at least on Ledger Model X. Previously this was not the case, where they had a normal microcontroller talking to the secure element where you unlock it and then it signs whatever you want. And then this microcontroller controls the display. This was actually a big point that was pointed out by — … this architecture is not perfect because you have this man-in-the-middle that controls this display. You have to trust your hardware wallet has a trusted display, but with this architecture you can’t because there’s a man-in-the-middle. It’s hard to mitigate this and figure out how to tradeoff between complete security versus user usability. I hope you get the idea of why secure elements are actually secure.
Problems with secure elements
There are in fact some problems with secure elements, though. They have all of these nice anti-tampering mechanisms but they also like to hide other stuff. The common practice in the security field is that when you close-source your security solution, you get some extra points on the security certification like ELF 5 and other standards. Just by closing sourcing what you wrote or what you did, you get extra points. Now what we have is the problem that we can’t really find out what is running inside these devices. If you want to work with a secure element, you have to be big enough to talk to these companies and get the keys required to program it. And you also have to sign their non-disclosure agreement. And only at that point would they give you documentation; and then the problem is that you can’t open-source what you wrote. Alternatively, you use a secure element that is running a Java Card OS in there so it’s something like a subset of Java developed for the banking industry because bankers like Java for some reason. Basically they have this Java VM that can run your applet… so you have no idea how the thing is operating, you just trust them because it’s certified and it has been there for 20-30 years already and we know all the security research institutes are trying very hard to even get a single …. and then you can completely open-source the Java Card applet that you upload to the secure element but you don’t know what’s running underneath it. Java Card is considered a secure element, yes.
By the way, the most secure Java Cards or secure elements were normally developed for the … like when you buy this card, you have a secret there that allows you to watch TV from a certain account. They were very good at protecting the secrets because they had the same secret everywhere. The signal is coming from space or satellite, the signal is always the same. You’re forced to use the same secret on all the devices. This means that if even one is hacked, you get free TV for everyone, so they put a lot of effort into securing this kind of chip because as soon as it is hacked then you’re really screwed and you have to replace all devices.
Also, let’s talk about the Sony Playstation 3 key compromise attack. They use ECDSA signing, and you’re not supposed to get all the games for free right? The only way to get the game running, you need to have a proper signature on the game, so the signature from Sony. The problem was that they suppose didn’t hire a cryptographer or anyone decent at cryptography… they implemented a digital signing algorithm in a way where they were reusing the same nonce over and over again. It’s the same problem with the hardware wallets we described earlier today. If you are reusing the same nonce, then I can actually extract your private key just by having two signatures from you. I can then get your private key and then I can run whatever game I want because I have the Sony private key. This was for the Sony Playstation 2. I think it was the fastest hack of a gaming console ever.
QR code wallets
Constraining the unidirectionality of information. Bits can’t flow backwards. The only place a decrypted key should be is in a running hardware wallet. There’s a slip39 python implementation. Chris Howe contributed a slip39 C library.
With multisig and each key sharded, can you mix the shards from the different keys and is that safe?
The qr code is json -> gzip -> base64 and it fits like 80-90 outputs and it’s fine. Animated QR codes could be cool, but there’s some libraries like color QR codes that give you a boost. It’s packetization. Is the user going to be asked to display certain QR codes in a certain order, or will it be negotiated graphically between the devices? You can use high contrast cameras.
Printed QR code… each packet can say it’s 1-of-n, and as it reads it, it figures out which one it is, and then it figures out which one is done or not done yet.
Signatures could be batched into a bigger output QR code on the device. So it’s not a huge bottleneck yet. Packetized QR codes are an interesting area. When you parse the QR code from Christopher Allen’s stuff, the QR code says what it is saying.
There were some recent attacks that showed that even if you are using secure hardware, it doesn’t mean you’re secure. When you have an attacker that can get to your device, then you’re in trouble and they can do nasty attacks against the microcontroller. Another idea is to wipe the device every time. There are wallets that use secure elements, such as the Ledger hardware wallet.
On the hardware side, it’s wonderful. The team is strong on the hardware side. They came from the security industry. They know about certification of secure elements, they know how to hack microcontrollers and they keep showing interesting attacks on Trezor and other random wallets. They are extremely good on the software side, but that doesn’t mean they can’t screw up on the software side. It actually happened a few times.
One of the more scary attacks on Ledger happened at the end of the last year, and it was change address related. When you are sending money to someone, what you expect is that you have your inputs and let’s say you have the inputs of the— one bitcoin, say, and then you have normally two outputs, like one is for the payment and the other is the change output. How do you verify this is the change address? You should be able to derive the corresponding private key and public key that will control that output. If you get the same address for the change output, then you are sure the money goes back to you. Normally what you do is you provide the derivation path for the corresponding private key, because we have this hierarchical deterministic tree of keys. So the hardware wallet just needs to know how to derive the key. So you send to the wallet the derivation path as well, like the bip32 derivation path. Then the hardware wallet can derive the corresponding key and see it exactly this output will be controlled by this key so it has the right address. …. So what Ledger did is that they didn’t do the verification…. they just assumed that if there was an output with some derivation path, then it is probably right. This means that the attacker could replace the address for this output to any address at all, just put any derivation path and all the money could go to the attacker when you’re sending some small amount of bitcoin then all the change goes to the attacker. It was disclosed last year, and it was discovered by the Mycelium guys because they were working on transfer of funds between different accounts on Ledger and they found that somehow it is too easy to implement this in Ledger so something is going wrong here and they discovered the attack. It was fixed, but who knows how long this problem was there. From the hardware wallet perspective, if someone doesn’t tell me it’s a change output or prove that to me, then I should say it’s not a change output. This was one problem.
There was a minor issue too, where they didn’t read the documentation of the microcontroller. The problem was, how did they verify the firmware that is running on this microcontroller? They basically…. when we have our new firmware, then the Ledger has a specific region in memory where they hda a magic sequence of bytes in particular for Ledger it was some hex magic number. Then they store that there. What happened next is that when you’re updating the Ledger firmware, the Ledger was first erasing this and then flashing the firmware and then at the end they were verifying if the signature if this firmware is correct. If the signature was generated by the Ledger key, then they put back this magic number into the register and then you were able to start this firmware and make it start working. Sounds good, right? If you are provided a wrong signature, then these magic bytes are all zeroes at the moment so it wouldn’t run this firmware, it would just rollback to the previous firmware. The problem is that if you read the documentation for the microcontroller, you see there are two different addresses to access this memory region where they store these magic bytes. One was completely blocked from external read-write such that if you try to write to these registers then you fail because only the microcontroller can write it. But then there was another one that had access to the same memory region and you could write any bytes there, and then you could make the microcontroller run any firmware you give it. Someone was able to play a game of snake on the Ledger hardware wallet as a result of this. If you get control of this display and the buttons, with custom firmware- you can hide arbitrary outputs. You can fool the user in different ways, because you’re controlling what the user will see when he is signing. So I think it’s a pretty big problem. It was a hard problem to exploit but still a problem.
Another super serious fuckup that happened with Bitbox… you know this one? Some of the wallets have a nice hidden wallet feature. The idea is that if someone takes your hardware wallet and tells you please unlock it, otherwise I will hit you with a wrench. You will probably unlock it, and then spend the money to the attacker because you don’t want to die. The hidden wallet feature is supposed to secure your money in such a way that there is also a hidden wallet that the attacker doesn’t know about and they will only get a fraction of your money. You use the same mnemonic but you use a different passphrase, normally. The Bitbox guys did it slightly differently, and it was a bad idea to reinvent the protocol with their own rules. So what they did was, you have this master private key like a bip32 xprv. It has a chaincode and the private key in there. So when you have the master public key, you have the same chaincode and just the public key corresponding to this private key. Given the master public key, you can derive all your addresses but not spend, and if you have the private key you could spend. The hidden wallet they used the same xpub with the same chaincode but they flip the chaincode and the key. So that means if your software wallet knows the master public key of both the normal wallet and the hidden wallet, then it basically knows both the chaincode and the private key so they can get all your money. If you are using this hidden wallet feature, then you are screwed.
Is the attacker not supposed to know about the hidden wallet feature? How is this supposed to work? In principle, this hidden wallet feature is questionable. As an attacker, I would keep hitting you with a wrench until you give me all the hidden wallets you have. I would keep hitting you until you give me the next password or next passphrase and so on, they would never trust that you don’t have a next wallet. The wallet would have to be sufficiently funded so that the attacker would think it is likely everything. You could also do the replace-by-fee race where you burn all your money to the miners ((hopefully you sign the fee possibilities correctly)). The attacker isn’t going to stop physically attacking you. But there’s still a big difference between physically hitting someone and killing them. Murder seems like a line that less people would be willing to cross.
TruCrypt had plausible deniability in the encryption because you could have multiple drives encrypted, but you didn’t know how many are there. It might be suspicious that a 1 GB encrypted volume has only a single 10 kb file… but the idea is to put something really incriminating along with your 10 BTC, and you just say I’m so embarrassed and this would make it seem more legitimate that it is actually your full coin amount.
Having secure hardware doesn’t mean you’re not vulnerable to attacks. I really think the best thing to do is to use multisignature.
If you are willing to wait for a delay, you can use a timelock, or spend instantly with 2-of-2 multisig keys. You would enforce on the hardware wallet to only make these timelock transactions. The attacker provides the address. It doesn’t what your wallet say; at best, your wallet has already locked it. You can’t spend it in a way that locks it, because presumably the attacker wants to use their only address. You could pre-sign the transaction and delete your private key– hope you got that fee right.
If you can prove to a bank that you will get $1 billion one year from now, then they will front you the money. You get the use of the money, you negotiate with the attacker and pay them a percentage. But this gets into K&R insurance stuff…. You could also use a bank, that is 2-of-2 multisig or my key but with a delay of 6 months. So this means every time you need to make a transaction, you go to the bank and make a transaction— you can still get your money back if the bank disappears, and then the attacker can’t get anything because they probably don’t want to go with you to the bank or cross multiple borders as you travel around the world to get all your keys or something.
The best protection is to never tell anyone how much bitcoin you hold.
How could you combine a timelock with a third-party? Timelock with multisig is fine.
We’re planning to add support for miniscript, which could include timelocks. But no hardware wallet currently enforces timelocks, to my knowledge.
Miniscript (or here) was introduced by Pieter Wuille. It’s not one-to-one mapping to all possible bitcoin script, it’s a subset of bitcoin script but it covers like 99.99% of all use cases observed on the network so far. The idea is you describe the logic of your script in a convenient form such that a wallet can parse this information and figure out what keys or information it needs to get in order to produce a key. This also works for many of the lightning scripts and also various multisig scripts. You can then compile this miniscript policy into bitcoin script. Then you can analyze and say this branch is the most probable that I will use most of the time, and then order the branches in the script to make it more efficiently executed on average in terms of sigops. It can optimize the script in such a way that actually your fees or your data that you have when you’re signing this script will be minimal according to your priorities. So if you’re mostly spending with this, then this will be superoptimal and this other branch might be a bit longer.
After implementing miniscript, it will be possible to use timelock. Until then, you need something like a raspberrypi with custom firmware. We can try to implement a timelock feature together tomorrow if you will still be here.
Pieter has a proof-of-concept on his website where you can type out policies and get an actual bitcoin script. I don’t think he has the demonstration of going the other way around; but it is described in many details how this all works. I think they are finishing their multiple implementations at the moment and I think it’s almost ready to really get started. Some pull requests have been merged for output descriptors. In Bitcoin Core you can provide a script descriptor and feed this into the wallet, like whether it’s segwit or legacy, nested segwit or native segwit etc. You can also use script descriptors for multisignature wallets, you can already use Bitcoin Core with existing hardware wallets… it’s still a bit of a trouble because you need to run a command line interface and it’s not super user friendly and not in the GUI yet, but if you’re fine with command line interfaces and if you’re willing to make a small script that will do it for you, then you’re probably fine. I think integration with Bitcoin Core is very important and nice that we have this moving forward.
Advanced features for hardware wallets
Something we could do is coinjoin. Right now hardware wallets only support situations where all inputs belong to the hardware wallets. In coinjoin transactions, that’s not the case. If we can fool the hardware wallet into displaying something wrong, then we can potentially steal the funds. How could the hardware wallet understand if this input belongs to the hardware wallet or not? It needs to derive the key and checks is it able to sign. It requires some help from the software wallet to do this. The user needs to sign transactions twice for this protocol.
It is pretty normal to have multiple signing of a coinjoin transaction in a short period of time, because sometimes the coinjoin protocol stalls due to users falling off the network or just being too delayed.
Signing transactions with external inputs is tricky.
Hardware wallet proof of (non)-ownership
Say we’re a malicious wallet. I am not a coinjoin server, but a client application. I can put two identical user inputs, which is usually common in coinjoin, and you put them in the inputs and you put only one user output and then the others are other outputs. How can the hardware wallet decide if the input belongs to the user or not? Right now there’s no way. So we trust the software to mark the input needed to sign. The attack is to mark only one of the user inputs as mine, and then the hardware wallet signs it and we get the signature for the first input. The software wallet then pretends the coinjoin transaction failed, and sends to the hardware transaction the same transaction but marking the second input as ours. So the hardware wallet doesn’t have a way to determine which inputs were his. You could do SPV proofs to proof that an input is yours. We need a reliable way to determine if the input belongs to the hardware wallet or not. Trezor is working on this with achow101.
We could make a proof for every input, and we need to sign this proof with a key. The idea is to prove that you can spend and prove that… it can commit to the whole coinjoin transaction to prove to the server that this is owned, and it helps the server defend against denial of service attacks because now the attacker has to spend his own UTXOs. The proof can only be signed by the hardware wallet itself. You also have a unique transaction identifier.. It’s sign(UTI||proof_body, input_key). They can’t take this proof and send it to another coinjoin round. This technique proves that we own the input. The problem arises from the fact that we have this crazy derivation path. Use the unique identity key, which can be a normal bitcoin key with a fixed derivation path. The proof body will be HMAC(id_key, txid || vout). This can be wallet-specific and the host may collect them for UTXOs. You can’t fake this because the hardware wallet is the only thing that can generate this proof.
This could be extend to multisig or even MuSig key aggregation.
We can ask all participants of this coinjoin transaction to sign a certain message with the private key that controls this input. So we have some message, and a signature. The signature proves to us, to everyone, that the guy who put this message there actually controls the corresponding private key. This is the signature from the key that controls this input. On the message side, we can put whatever the hardware wallet wants. The hardware wallet is the guy who can sign this proof. He is the only one that controls this key. So what it can do is generate a particular message that it will be able to recognize afterwards. So I take the transaction hash and hash it together with my fixed key that I store in my memory, and then I get a unique message that looks random but I will be able to reproduce it whenever I see it and I will be able to make sure it was my input because I was the guy who generated this inside the message. Once we provide all these proofs for every input, our hardware wallet can go through each input and make sure which inputs are mine and which are not mine. This can then help detect when the software wallet is trying to fool you.
I hope hardware wallets will be able to do coinjoins fairly soon. Trezor will probably deploy it first because we’re working with them on that.
Q: What’s the use case for this? Say I want to leave something connected to the internet to make money from something like joinmarket? Or I want to be a privacy taker?
A: It works in both cases. If you want to participate in coinjoin and earn something- but right now it doesn’t work this way. Right now all the revenue is going to the Wasabi Wallet guys. Their servers take fees to connect people together. At the moment I think it’s if you want to use the coinjoin to get some privacy, then you need this kind of protocol, so you probably need to either connect your hardware wallet to do this or you still can do it using the airgap.
In our case for example, I was thinking about having a screen on the computer and then a QR code and they can communicate over QR codes like this is a webcam and this is a screen. I was also thinking about audio output, like a 3.5mm jack from the hardware wallet to the computer. The bandwidth there is pretty good. You could also just play audio on a speaker. But then your hardware wallet needs a speaker, and it can just send your private key out. But a 3.5mm audio jack makes sense.
Q: What about coinshuffle, or coinswap?
A: I only know a little about this. For wasabi wallet, it doesn’t know which inputs correspond to which outputs because it registers them separately. You get back a blinded signature, and you give them a blinded output or something. They generate a blind signature and they don’t know what they are signing. It allows the coinjoin server to verify that yes I signed something and this guy wants to register this output so it looks right and I should put it into the coinjoin. For all this communication they use Schnorr signatures because there you can use blind signatures. In principles this means you have two virtual identities that are not connected to each other; your inputs and outputs are completely disconnected even for the coinjoin server. They also generate outputs of the same value and then they make another section of the outputs with a different value so you can also get anonymity for some amount of change.
Wasabi wallet supports hardware wallets, but not for coinjoin. Then the only remaining benefit of using Wasabi is having complete coin control and being able to pick coins to send to people.
Q: How does Wasabi deal with privacy when fetching your UTXOs?
A: I think they are using the Neutrino protocol, they ask for the filters from the server and then they download blocks from random bitcoin nodes. You don’t need to trust their central server at that point. I think it’s already enabled to connect to your own node, awesome that’s great. Cool. Then now you can actually get it from your Bitcoin Core node.
Lightning for hardware wallets
Lightning is still in development, but it’s already running live on mainnet. We know the software isn’t super stable yet, but people were excited and they started to use it with real money. Not a lot of real money, it’s like a few hundred bitcoin on the whole lightning network at this point.
Right now lightning network works only with hot wallets with the keys on your computer. It’s probably not an issue for us, but for normal customers buying coffee daily this is a problem. It might be okay to store a few hundred dollars on your mobile wallet and maybe it gets stolen, that’s fine it’s a small amount of money. But for merchants and payment processors, then you care about losing coins or payments, and you want to have enough channels open so that you don’t have to close any and you won’t have any liquidity issues on the network. You have to store your private keys on an online computer that has a particular IP address, or maybe through tor, and certain ports open, and you’re broadcasting to the whole world how much money you have in those channels. Not very good, right? So this is another thing we’re working on that would be nice to get the lightning private keys on a hardware wallet. Unfortunately, here you can’t really use an airgap.
You could partially use cold storage. You could at least make sure that when the channel is closed that the money goes to cold storage. There’s a nice separation of different keys in lightning. When you open a channel, you should verify what address to use when closing the channel. Then even if your node is hacked, if the attacker tries to close the channels and get the money, then it fails because all the money goes to the cold storage.
But if he is able to get all the money through the lightning network to his node, then you’re probably screwed. To store these private keys on the hardware wallet is challenging, but you could have a …. he can also do a signed channel update. If you provide enough information to the hardware wallet, that you are actually routing a transaction and that your balance is increasing, then the hot wallet hardware wallet could sign automatically. If the amount is decreasing then you definitely need to ask the user to confirm. So we’re working on that.
Schnorr signatures for hardware wallets
The advantage of Schnorr signatures for hardware wallets is key aggregation. Imagine you’re using normal multisig transactions, like 3-of-5. This means that every time you’re signing the transaction and putting it into the blockchain, you see there’s 5 pubkeys and 3 signatures. It’s a huge amount of data, and everyone in the world can see that you’re using a 3-of-5 multisig setup. Terrible for privacy, and terrible in terms of fees.
With Schnorr signatures, you can actually combine these keys together into a single key. So you can have several devices or signers that generate signatures and then you can combine the signatures and corresponding public keys into a single public key and a single signature. Then all the transactions on the blockchain and most of the transactions on the blockchain would look similar, just a public key and a signature.
With taproot (or here), it’s even better. You can add the scripting functionality there as well. If everything goes well, like in lightning maybe you and your counterparty are freely cooperating and you don’t need to do a unilateral close. You could do a 2-of-2 multisig mutual close, and then it looks exactly like a public key and a single signature. If someone is not cooperating and things are going wrong, then you can show a branch in the taproot script that shows that you are allowed to claim the money but this script is only revealed if you have to go down this path. Otherwise you get a single public key and a single signature on the blockchain.
We can use chips on a single hardware wallet device with different architectures and different heterogeneous security models, and put three different chips with three different keys on there, and make sure we can spend the bitcoin only if each of these chips are signing in the hardware wallet. So one can be a proprietary secure element, and then a few other microcontrollers in the same hardware wallet, and the output is only a single public key and a single signature. We could also do one chip from Russia and one chip from China. So even if there is a backdoor, it is unlikely that both the Russian government and the U.S. government will cooperate to attack your wallet. From the user’s perspective, it looks like only a single key or a single signature.
All these watchdogs and anti-tamper mechanisms and preventions of fault injections and stuff…. they are not implemented yet, but I know there’s a few companies that are working on security peripherals around the RISC-V architecture. So hopefully we will get secure elements soon. The only problem at the moment is that most of– some of the companies, I would say, they take this open-source RISC-V architecture and they put on top of it a bunch of proprietary closed-source modules and this kind of ruins the whole idea. We need a fully open-source RISC-V chip. I would definitely recommend looking at RISC-V.
There’s also the IBM Power9’s are also open-source at this point. Raptor Computing Systems is one of the few manufacturers that will actually sell you the device. It’s a server, so not ideal, but it is actually open-source. It’s a $2000 piece of equipment, it’s a full computer. So it’s not an ideal consumer device for hardware wallets. I believe the CPU and most of the device on the board are open-source including the core. It’s an IBM architecture. Okay, I should probably look at that. Sounds interesting.
I want to talk about best practices, and then talk about developing our own hardware wallet. But first about best practices.
Never store mnemonics as plaintext. Never load the mnemonic into the memory of the microcontroller before it’s unlocked. There was something called “frozen Trezor attack”. You take your Trezor, you power it on, the first thing it does is load your mnemonic into memory and then what you can do is freeze the Trezor with low temperature to make sure the memory of the key is still visible. Then you update the firmware to custom firmware, which Trezor allows, which is normally OK because your flash memory is wiped and they assume your RAM is decaying but at cold temperatures it stays there. Next, once you have the firmware there, you don’t have the mnemonic but you can print on the serial… but you can still get the data out of there. The problem was that they were loading the mnemonic to RAM before checking the bit. So never do that.
The ultimate and one thing that prevents an attacker from spending your funds is the PIN code or whatever verification method you’re using. It’s extremely better here to store the correct PIN code on the device. In principle, comparing the correct PIN code to the wrong PIN code is bad because during these comparisons there’s a sidechannel attack. Instead, you want to use a PIN code and another authentication method to derive the decryption key to decrypt the encrypted mnemonic. This way, you remove all the sidechannel attacks and you don’t have the mnemonic as plaintext.
Another nice feature that people should use is, have you heard about physically unclonable functions? It’s a really nice feature. Say you have a manufactured microcontroller… when the RAM is manufactured, there are certain fluctuations in the environment such that the RAM is manufactured differently for every bit. When you power on the microcontroller, the state of your memory will be random. Then you erase it and start using it as normal. But this randomness has a certain pattern, and this pattern is unclonable because you cannot observe it and it cannot be reproduced in another RAM device. You can use this pattern as a fingerprint, as the unique key on the device. This is why it’s called a physically unclonable function, it’s due to variations in the manufacturing process. You can use that together with a PIN code and other stuff to encrypt your mnemonic. When this device is booted, it will be able to decrypt the mnemonic. But extracting the full flash memory will not help this, because it still needs to get the physically unclonable function which is in the device. The only way to get that is to flash the firmware, read the key and extract it over serial or whatever. It’s a fail of both the read protection and write protection.
Q: Why not get rid of the PIN and the mnemonic storage, and require the user to enter that and wipe the device?
A: You could. So it’s a secure signing device, but not a secure storage device. So there’s secure storage, and then secure signing. So you store the passphrase or the wallet encrypted on paper or CryptoSteel in a bank vault or something with the mnemonic or something… and it’s encrypted, and you remember the passphrase. So you never store the passphrase anywhere.
The secure storage problem and the secure signing problem should be separated. So you could use replaceable commodity hardware for signing, and the mnemonic should be stored encrypted on paper or something. The problem with entering a mnemonic every time is that you could have an evil maid attack. The prevention here is to not have wifi or anything. But maybe the attacker is clever and they put in a battery pack and some kind of broadcast mechanism, but this goes back to having a disposable commodity wallet.
Besides RAM, you can use a piece of glass to make a physically unclonable function. You could put a piece of glass into the wallet and it has a laser and can measure the imperfections in the screen and uses this to derive the decryption key for your mnemonic. This isn’t a fingerprint. Glass might degrade over time though. A piece of plastic can have a unique pattern that generates an interference pattern and then can be used to extract a decryption key from that. But that’s not going to happen for a while.
This other thing about evil maid attacks and hardware implants, how can we prevent that? There’s a way to do anti-tamper mesh around the device such that whenever someone is trying to get into the device, like drilling a hole, your security measures are automatically activated. In HSMs in the banking industry, they basically have a device constantly connected to power and it monitors current going through this conductive mesh. If they detect the change in current in this mesh, then they wipe the device. The problem here is that when you’re running out of power, you have to rely on the battery, and then when the battery is draining before it is drained you have to wipe the keys anyway.
There’s a better way, where you don’t just check the current, but you also check the capacity of the wires in the mesh and you use that as a unique fingerprint to generate the unique decryption key of your secrets. Even if someone drills a 100 micron hole in here, the decryption key changes and they will not be able to extract the secrets anymore. You can’t just buy a device like this at the moment, but it’s a very promising approach. It’s probably for people who really care about large amounts of money, because this is really expensive.
If you are going to wipe the keys, then you might as well pre-sign a transaction before you wipe the keys, to send the coins to backup cold storage or something.
Rolling your own hardware security
You should not expect that rolling your own hardware wallet is a good idea. Your device will probably not be as secure as Trezor or Ledger because they have large teams. But if there is a bug in the Trezor firmware, then attackers will probably try to exploit that across all Trezor users. But if you have a custom implementation that might not be super secure but it’s custom, then what are the chances that the guy who comes to your place and finds a weird looking device and figures out it’s a hardware wallet and then how does he figure out how to break it? Another thing you can do is hide your hardware wallet in a Trezor shell ((laughter)).
Someone in a video suggested making a fake hardware wallet, and when it is powered on by someone, then it sends an alert message to a telegram group and says call 911 I’m being attacked. You could put this into the casing of Trezor. When the guy connects to it, it sends the message. Another thing you could do is install malware on the attacker’s computer, and then track them and do various surveillance things. You could also claim yeah I need to use Windows XP with this setup or something equally insecure, which is plausible because maybe you set this system up 10 years ago.
Options for making a hardware wallet prototype
What can we use to make a hardware wallet? If you think making hardware is hard, it’s not. You just write firmware and upload it. You can also use FPGAs which are fun to develop with. I like the boards that support micropython, which is a limited version of python. You can talk to peripherals, display QR codes and so on. Trezor and ColdCard are using micropython for their firmware. I think micropython has a long way to go though, because as soon as you move away from what has already been implemented then you end up having problems where you need to dive into the internals of micropython and you end up having to write new C code or something. But if you like everything already there, then it is extremely easy to work with.
Another option is to work with arduinos. This is the framework developed maybe 20 years ago I don’t know, and it’s used throughout the whole do-it-yourself community. It became extremely easy to start writing code. I know people who learned programming by using arduino. It’s C++, and not as user friendly as python, but still the way how they make all the libraries and all the modules, it is extremely friendly to the user. They didn’t develop this framework with security in mind, though.
There’s also the Mbed framework. They support a huge variety of boards. This framework was developed by ARM. You’re again writing C++ code, and then you compile it into the binary, and then when you connect the board you drag-and-drop it into the board. It’s literally drag-and-drop. Even more, you don’t need to install any toolchain. You can go online and use their online browser compiler. It’s not very convenient, except for getting started and getting some LEDs blinking. You don’t even need to install anything on your computer.
Something else to pay attention to is the rust language, which focuses on memory safety. It makes a lot of sense. They also have rust for Mbed systems. So you can start writing rust for microcontrollers, but you can also access the libraries normally written by the manufacturer or something- like for talking to the displays, LEDs and all this stuff. In the microcontroller world, everything is written in C. You can write your hardware wallet logic in rust, and then still have the bindings to the C libraries.
There’s a very interesting project called TockOS. This is an operating system written in rust completely, but you can keep writing in C or C++ but the OS itself like the management system can make sure that even if one of your libraries is completely compromised then you’re still fine and it can’t access memory from other programs. So I think that’s really nice. At the moment, I think there’s not too many people that know rust, but that’s improving. Definitely very interesting toolchain.
Another nice thing you can do with DIY hardware wallets, or not just DIY but with flexible hardware, is custom authentication. If you’re not happy with just a PIN code, like you want a longer password, or you want to have an accelerometer and you want to flip the hardware wallet in a certain way that only you know or something, or for example you can enforce one-time passwords and multi-factor authentication. You don’t only require the PIN but also a signature from your yubikey, and all these weird kinds of things, or even your fingerprint but that’s a bad idea because fingerprints have a low entropy and people can just take your finger anyway or steal your fingerprints.
You could use yubikey, Google Titan, or even some banking cards. You could do multi-factor authentication and different private key storage devices to do multisig having nothing to do with bitcoin, to authenticate to get into a hardware wallet.
Note that all of these boards I am talking about are not super secure. They all use microcontrollers and they don’t have a secure element. You can get a really cheap board that is like $2 bucks. Keep in mind, it’s manufactured and designed in China. It’s very widespread but who knows, maybe there’s still a backdoor in the device somewhere. Who knows. Also, it has bluetooth and wifi so that’s something to be aware of. If you want a not very secure version of the Ledger X, then you could do it. It would probably be safer than storing the money on your laptop that is constantly connected. All other developer boards tend to have simple application-specific microcontrollers. This one here has the same chip that Trezor has, in theory you could port trezor to this. So you get the security of a Trezor wallet, a much larger screen and maybe some additional functionality that you might like. So it might make sense in some cases. I wouldn’t rely completely on DIY hardware for security.
There’s also some cheap security-focused chips available on the market. The one that is used in the ColdCard is on the market, some sort of ECC blahblahblha from Microchip. You can also apply it in the arduino form factor. So it can provide you a secure key storage for your bitcoin keys, and the rest can be done on the normal microcontroller.
No secure elements are available on the market at the moment that would allow you to use elliptic curve cryptography for the bitcoin curve. They haven’t been built yet.
To make a fully secure element that is completely open-source from the very bottom to the very top, will cost like $20 million. What we are releasing is what is accessible to us at the moment. So what we can do is we can get this secure element that has a proprietary Java Card OS on top of it, and then on top of this we can write a bitcoin-specific that can talk to the hardware and use all the elliptic curve accelerators and hardware features and can still be open-source because we don’t have know how exactly this Java Card OS works so it’s not fully open-source, we’re just open-sourcing everything we can. In the ColdCard, they can’t use the elliptic curve cryptography on the secure key storage element, but in other secure elements yes you can run ECDSA and other elliptic curve cryptography.
My design choices for my hardware wallet
I wanted to talk about how we designed our hardware wallet and get your feedback about whether this makes sense or not and how we can improve, especially Bryan and M. I also want to make sure that I don’t build something very usable. After that, I think we can, if you guys have your laptops with you, then we can setup the development environment for tomorrow so that we can even give the boards to try out in the evening and take them home. If you just promise not to steal it, you can take some home if you want to, if you’re actually going to try it. Note that I will be disturbing you all the time tomorrow, so tonight is your chance to look at this alone. Tomorrow then we can work on some crazy hardware wallets.
What we decided to do is we have some hardware partners that can manufacture custom chips for us. We can take the components of the normal microcontrollers and put them in a nice way into a single package. So what components do hardware wallets normally have? The ones that also have a secure element, at least. So we decided first to go open-source. We’re not going to work on a bare metal secure element and a closed-source OS that we can’t open-source due to NDAs. So we are using a Java Card OS and even though we don’t know how it works, it seems to work so it should be pretty secure hopefully. Then to write on top of that, we’re writing a bitcoin applet that works with the secure element. We can only put in there stuff that we sign and that we upload using our administration keys. This means that we can develop and upload software, and then you can suggest certain changes that we can enable for upload. It requires certain communication with us first. I can’t give the keys to anyone else, because if they get leaked then we’re in trouble with the government because they are worried about criminals that will compromise super secure communication channels or use it to organize their illegal activities. This is unfortunately the state of the industry. We wanted to develop an open-source secure element, but for now we can just make a hardware wallet perhaps more secure and a bit more flexible.
So we are using the Java Card smartcard, and then we have two other microcontrollers. We also have a somewhat large display to show all the information about the transaction and to format it nicely and to enable this QR code airgap we need to be able to display pretty large QR codes. We have to use another general purpose microcontroller because only they can handle large screens at the moment. Then we have a third microcontroller that does all the dirty work that is not security-critical like the communication over USB, talking to the SD cards, processing images from the camera to read the QR codes and things like that. This makes for complete physical isolation of the large codebase that is not security-critical and handling all of the user data and the data from the cold computer. We also have another microcontroller that is dedicated to driving the display so that you can have a somewhat trusted display. All of these microcontrollers are packed into the same package. Inside, we have layered semiconductor devices in the package, and they are layered in a secured-sandwhich structure. The top one is the secure element, and the two others are underneath. So in theory, heat from one chip in the package can be detected in the other, but the smartcard presumably has a lot of work done on power analysis and sidechannel prevention.
Even if the attacker gets access to this chip and decaps it, he will first hit the secure element which has all of these anti-tampering mechanisms like watchdogs and voltage detection and memory mapping and other stuff, and it shares this capability with other chips. They obviously share the same voltage supply, so first you gain a little bit of security on the secure element with the other microcontrollers. Even if the attacker tries to get into the memory of the not very secure microcontrollers, the secure element is in the way and it is hard to get underneath it. The previous customers they made this for was for satellites, and in that case you have issues with radiation and stuff. For us this helped because it means you cannot, first, no electromagnetic radiation goes from the chip to the outside so this eliminates some sidechannel attacks, and secondly limited electromagnetic radiation gets into the chip. And as I said, they are all in the same package. In our development boards, they are not in the same package because we don’t have the money to develop the chip but we will start soonish. Still, it has all of this hardware already.
The normal microcontrollers have these debug interfaces. Even if they are disabled with the security bits, the attacker can still do a lot of race condition stuff and actually even re-enable it. So we included a fuse in there that physically breaks the connection from the JTAG interface to the outside world. So just having the chip, the attacker is not able to use the JTAG interface. This is a nice thing that is normally not available. On the developer board, we expose a bunch of connections for development purposes, but in the final product the only connections will be the display, touch screen, and for the camera we haven’t decided which of them we want to use. Normally the camera is used to store the QR code and it is obviously communication related and should be on the communication microcontroller. We can take a picture of dice as user-defined entropy.
We have a completely airgapped code that works with QR codes to scan transactions and QR codes to transmit signatures. We call this the M feature because he’s the one that suggested this. It’s so nice and fluent how it works that I have this nice video I can show you. So first we scan the QR code of the money we want to send to; the watchonly wallet on the phone knows all the UTXOs and it prepares the unsigned transactions and shows this to the hardware wallet. Next, on the hardware wallet we scan the QR code. Now we see information about the transaction on the hardware wallet, that we can sign, and then we get the signed transaction back. We then scan it with the watchonly wallet, and then we broadcast it. The flow is pretty convenient.
This is uni-directional data flow. It only goes in one direction. It’s highly controlled data flow. It is also limited in terms of the data you can pass back and forth. This is both a good thing and a bad thing. For a large transaction, it might be a problem. For small data, this is great. We haven’t tried animated QR codes yet. I was able to do PSBT with a few inputs and outputs, so it was pretty large. With partially-signed bitcoin transactions and legacy inputs, then your data is going to blow up in size pretty fast. Before segwit, you had to put a lot of information into the hashing function to derive the sighash value. Now with segwit, if the wallet lies about the amounts, then it will just generate an invalid signature. In order to calculate the fee for the hardware wallet, I have to pass the whole previous transaction, and it can be huge. Maybe you get the coins from the exchange, and the exchange might create a big transaction with thousands of outputs and you would have to pass all of it to the hardware wallet. If you are using legacy addresses, you will probably have trouble with QR codes and then you will need to do animations. For segwit transactions and reasonable number of inputs and outputs, you’re fine. You could just say, don’t use legacy anymore, and sweep those coins. The only reasonable attack vector there is if you’re a mining pool and you’re going to trick you into broadcasting that and rob you, but outside it hurts you but doesn’t profit the attacker so it doesn’t really have incentive. You can also show a warning and saying if you want to use the fees, then use bech32 or at least check it here. You can show them the fee on the hot machine, but that’s probably compromised.
With the airgapped mode, you have cold storage and it’s an airgap and it’s reasonably secure. Nothing is perfect, there will be bugs and attacks on our hardware wallet as well. We just hope to make less mistakes than what we see at the moment. Also, another thing I didn’t talk about is the …. within smartcards, we have to reuse the Java Card OS just because applets have to be written in java. Then we decided to go with embedded rust, and even though it’s a little harder to develop and not many people know rust, this part is really security critical and we don’t want to shoot ourselves in the foot with mistakes there. Also, it prevents a lot of isolation and best practices from the security world. Third, we open to the developers and it is running micropython. So this means that if you want custom functionality on the hardware wallet, like a custom communication scheme like bluetooth which we don’t want but if you want it then you’re welcome to do it yourself. Then you write a python script that handles this communication type, and then just use it. Another way to do it is that, if you’re using a particular custom script that we’re not aware of, and we’re showing this transaction in an ugly way that is maybe hard to read, then maybe what you can do is add some metadata to send it to the other microcontroller to display you something. It will still mark it as not super trusted because it’s coming from this python app, but if you’re trusting the developers of the app, then you can make a few choices. But at least you can see some additional information about this transaction if our stuff wasn’t able to parse it; like if it’s a coinjoin transaction that is increasing your anonymity set by 50 or whatever- you still see the inputs and outputs, plus the extra information normally. So this might help the user experience.
Besides from the airgapped mode, there is another completely different use case where you use this as a hot wallet like for a lightning hardware wallet. You keep the wallet connected to the computer, and the connected computer runs a watchonly lightning wallet, and then communicates with the hardware wallet for signatures on transactions that strictly increase the balane of your channel. Then, you could be in the loop for any transactions reducing your balance. Note still that this is not an airgapped mode, but it’s a different security mode. You probably want most of your funds in cold storage, and then some amount can be in this hot wallet hardware wallet device. Also, one of the problems with coinjoin is that it can take some time like a few minutes, especially if you need to retry multiple times, which is sort of like a hot wallet.
You probably don’t want to carry your hardware wallet around all the time, or go home to press a button to confirm your lightning payment or something. So what you can do is setup a phone with an app that is paired to the hardware wallet, so the hardware wallet is aware of the app and the app stores some secret to authenticate itself and then you can set a limit in the morning for your phone. So the hardware wallet should authorize payments up to a certain amount if it’s coming from this secure app. Even more, you can set particular permissions to the mobile app. Like, the exchange wallet should be able to ask the hardware wallet for an invoice but only an invoice to pay you. Same with bitcoin addresses, it can only ask for bitcoin addresses for a particular path. You can make it more flexible and get better user experience if you want to. The hardware wallet is connected to the internet, and the requests are forwarded through the cloud in this scheme.
The first thing that we are releasing is the developer board and the secure element. Another thing I want to discuss is the API of the first version of the secure element. In particular, as developers what would you like it to have? I have a few ideas about what may be useful. Maybe you can think of something in addition.
Obviously, it should store the mnemonic, passwords, passphrases, and it should be able to do all the bip32 derivation calculations and store bip32 public keys. We also want ECDSA and standard elliptic curve signing that we’re using at the moment. Also, I want to include this anti-nonce attack mitigation protocol. We don’t want to trust the proprietary secure element; we want to be sure that it is not trying to leak our private keys using this chosen nonce attack. So we want to enforce this protocol. Also, we want to use Schnorr signatures in particular with Shamir secret sharing. This would allow you to take the Schnorr keys, and then get a signature out of it that uses the correct point. Key aggregation with Shamir, you need a fancy function to combine each of the points from the parties.
It makes sense to use Shamir here because you can do thresholds. With Musig you can do that too, but with Schnorr it’s just k-of-k. Verifiable Shamir secret sharing using pedersen commitments. Say we have 3 keys living on our hardware, and these other parts are on some other backup hardware elsewhere. These can all communicate with each other. Each one generates their own key, and then using pedersen commitments and some other fancy algorithm, they can be sure that each of them ends up with a share of some common secret but none of them know what the common secret is. So we have a virtual private key or full secret that is split up with the Shamir secret sharing scheme with all of these guys and none of them know the full secret. The only problem is how do you back it up? You can’t see a mnemonic corresponding to this. Nobody knows this key, so nobody can display it. So the only way to do it is to somehow- let’s say this guy controls the display, then it can opt to display his own private key, but then what about the others? They don’t want to communicate to this guy to show it because then they can reconstruct it…. so you could use something like the display that you attach to different devices to display this mnemonic, but then the display driver can steal all of them. Ideally the display driver is a very simple device that only has memory and a display. You could also use disposable hardware to generate the private key, but then how do you recover it?
Another idea is seedless backups such that– if one of the chips breaks, if you’re not using 5-of-5 but say 3-of-5 then you could still make these guys communicate with each other, re-negotiate on the same key, generate a new shard for the new member and then replace all the old parts of this Shamir secret sharing scheme with the new one. Instead of the old polynomial, you choose the new polynomial and there’s a way such that each of these devices can switch to the new key and instead of compromising one we get the new member. This is also useful if one of the shards or keys gets compromised or lost, as long as you have enough keys to reconstruct it.
For signing, you don’t need to reassemble the Shamir secret share private key because it’s Schnorr. So the signatures are partially generated, and then they can be combined together into the correct final signature without reassembling the private key on a single machine.
Say you are doing SSS over a master private key. With each shard, we generate a partial signature over a transaction. A Schnorr signature is the sum of this random point plus the hash times the private key, and it’s linear. We can apply the same function to recombine the signature parts. We can apply the same function to s1, s2 and s3 and then you get the full signature S this way without ever combining the parts of the keys into the full key.
The multisignature is nice when you’re not the only owner of the private keys, like escrow with your friends and family or whatever. The Shamir Secret Sharing scheme with Schnorr is great if you are the only owner of the key, so you only need the pieces of the key. There’s a paper I can give you that explains how the shards are generated, or if the virtual master private key is generated on a single machine. Multisig is better for commercial custody, and Shamir is better for self-custody and self cold storage. Classic multisignature will still be available with Schnorr, you don’t have to use the key combination you would still use the CHECKMULTISIG. I think you can still use it. ((Nope, you can’t- see the “Design” section of bip-tapscript or CHECKDLSADD.)) From a mining perspective, CHECKMULTISIG makes it more expensive to validate that transaction because it has many signatures.
I was thinking about using miniscript policies to unlock the secure element. To unlock the secure element, you could just use a PIN code or you could use it in a way where you need signatures from other devices or one-time codes from some other authentication mechanism. We needed to implement miniscript anyway. We’re not restricted to bitcoin sigop limits or anything here; so the secure element should be able to verify this miniscript script with whatever authentication keys or passwords you are using. It can even be CHECKMULTISIG with the 15 key limit removed.
I will send Bryan the paper on linear secret sharing for Schnorr threshold signatures, where each shard can be used to generate partial signatures that can later be recombined. Maybe pedersen’s paper on verifiable secret sharing from 1999. And then there’s a response to that paper where you can fix how one party can bias the public key, which biasing the public key doesn’t matter but whatever. GJKR'99 section 4 has it. It’s not Shamir secret sharing scheme if you don’t reassemble the private key; it’s just a threshold signature scheme that happens to use linear secret sharing. Calling it something else is dangerous because it might encourage people to implement SSSS where the key can be recovered.
Q: What if you got rid of the secure element, and make the storage ephemeral and wipe it on shutdown? Basically what tails does. The user has to enter their mnemonic and passphrase. You can even save the mnemonic and just require a passphrase. Would it be easier and cheaper if we get rid of the secure element?
A: Well, what about an evil maid attack? He uploads certain firmware to your microcontroller. How do you verify he didn’t take the password?
Q: It is possible, but this evil maid has to come back and get access again in the future. But in the mean time, you could destroy it, and take it apart and confirm and install software each time.
A: I really want a disposable hardware wallet. As long as the signature is valid, that is all you need. You’re going to destroy the hardware device after using it.
Q: If you’re using this approach without a secure element, what about a hot wallet situation like for lightning?
A: If they don’t have access to the hardware wallet, then it is fine. But if they do have access, then it will be even worse in the scenario without the secure element. It is using the private keys for the cryptographic operations, and if it’s on the normal microcontroller then you can observe power consumption and extract the keys. It’s pretty hard to get rid of this. Trezor is still vulnerable to this problem. Ledger guys discovered a sidechannel attack when you derive a public key from your private key you leak some information about your private key. They are working on fixing this, but basically to derive a public key you need to unlock the device and this means you already know the PIN code so it’s not an issue for them. But in automatic mode, if your device is locked but still doing cryptography on a microcontroller then it is still an issue. I would prefer to only do cryptography operations on a secure element. If we implement something that can store the keys or erase the keys as well, and it can do cryptographic operations without sidechannels, then I think you can move to a normal developer board or an extended microcontroller and do everything there already. I think it’s not purely a constraint, it’s more like– it has some limitations because we can’t connect the display to the secure element, but it’s tradeoffs that we’re thinking about. For disposable, I think it’s perfectly fine to use the— make a very cheap disposable thing. The microcontrollers used in Trezor cost like $2 or something like that. So we can just have a bunch of them, buy them in bulk on digikey or something by the thousands and then you put them on the chip and you need to solder a bit. Ideally you want a chip with a DIP package or a socket and you just put the controller there. It would be nice to try it out.
Q: If you are worried about an evil maid attack, then you could use a tamper-evident bag. The evil maid could replace your hardware wallet; but in theory you would know because of the tamper-evident bag. You can use glitter, take a picture of it, and store that, and when you go back to your device you check your glitter or something. Or maybe it has an internet connection and if it’s ever tampered with, then it says hey it was disconnected and I don’t trust it anymore.
These fingerprint scanners on laptops are completely stupid. Besides, an easy place to find those fingerprints is on the keyboard itself ((laughter)). You should be encrypting your hard drive with a very long passphrase that you type in.
With statechains, you can transfer the private key to someone else, and then you enforce that only the other person can make a signature. Ruben came up with an interesting construction where on top of this you can do lightning transactions where you only transfer part of this money, and you can do rebalancing and stuff. But it requires Schnorr signatures, blind signatures for Schnorr, and if it does happen well it won’t be for the moment.
How we can help with this is that, we can provide the functionality on the secure element that extracts the key and then– such that you are sure that the private key is moved. You need to trust the manufacturer still, but you can diverisificate the trust of it, so that you don’t have to fully trust this federation that is enforcing this policy.