Trusted Execution Environments (TEEs) offer quite an attractive feature set for Bitcoin: a secure operating system, running inside your smartphone, immune to malware thanks to hardware isolation features.
Imagine just downloading a virtualized Hardware Wallet, running with a security level close to a dedicated external device.
Ideally, the TEE offers a Trusted User Interface: a privileged access to the display and touch events that cannot be observed or modified. This sounds perfect both to enter a PIN to access the wallet and to confirm a Bitcoin transaction after checking it.
However in reality there are no magic bullets and getting the best out of TUI takes careful design. Without a specific hardware marker (like a ‘secure mode’ light) on the device we need to find ways of proving to the user that they are using a trusted display. Moreover, while recent devices increasingly feature a working Trusted UI, many older devices do not and if we want to operate on a broad range of devices we need to be able to cope without.
We can mitigate this issue to create a “proven” Trusted UI. To do that, we challenge the user to verify that he is indeed operating within the Trusted UI by trying to capture the screen by all ways possible, checking that it fails, or checking a secret word exchanged previously. The user can then draw a specific pattern on the Trusted UI, which will be remembered and displayed each time the Trusted UI is necessary, thus closing the loop.
Another problem to overcome for best-possible user authentication with TEE is data replay. Hardware anti replay mechanisms for flash memory are not yet commonplace and there is usually no dedicated hardware storage area for the TEE, meaning that on most handsets it is not possible to implement local hardware-backed monotonic counters. It is important to recognise this when building secure systems and consider where your threats lie. Consider a PIN to control access to the wallet: you might like to implement a safeguard where the wallet is erased or locked after a number of incorrect attempts (‘N’). The TUI protects against malware either brute-force opening the wallet or maliciously deliberately locking it but what if the device is stolen and a physical attacker can manually brute-force the PIN? In this physical attack scenario, because the TEE cannot store non-volatile counters the attacker effectively gets infinite retries on the PIN by rebooting the device after every N-1 attempts. Sure this would be slow, but in some cases it may be worth it. We could try to address this by making the PIN longer and extending the brute force search space, but can we do something better/more elegant?
As we like to mitigate issues and make the best of what we have — let’s see how we can use the isolation features of most deployed TEEs and keep the user in charge of everything, the Bitcoin way.
There are two major threats we want to protect against : theft of the phone, and an all powerful malware observing all communication between the Android wallet and its associated TEE application, that could feed fake transactions and possibly confirm them. Being good paranoid Bitcoin users, we also consider that both could happen simultaneously — a targeted attack where some malware would be installed on the device, which is stolen later.
Theft of the phone is solved by having to enter a PIN. But, we cannot really prevent against brute force attacks if we don’t have a Trusted UI. We also do not want to enter a static PIN since if we are operating on a device that does not have a Trusted UI then that one can be observed and replayed. Let’s go for an OTP authentication, and an external monotonic counter implementation on a service dedicated to that.
To do that, we’ll first perform an ECDH key exchange with a disconnected computer and the TEE when the application is installed (checking that the TEE key is valid by using its attestation signature — preventing Man in the Middle attacks). During this personalization phase, the TEE will generate several keys and provide them to the disconnected computer : a key used to validate a signature on the external monotonic counters, a key used to transfer confidential information later, and the OATH key used for OTP.
It is now quite simple to implement a monotonic counter service — the TEE sends a challenge, and expects to retrieve the value of the counter and a signature of both the challenge and the value using the previously created key. The server, which can be hosted by the user if desired, simply increases the counter on each request. The user can print a few OTP codes and use them when necessary. The main downside of this method is that the smartphone must always be connected to a network to use the TEE, but it’s quite acceptable considered the level of protection achieved.
We can leverage on the other key when generating a new wallet deterministic mnemonic inside the TEE — it’s sent back encrypted to the user, and only decrypted on an offline computer if necessary.
Confirmation of the transaction without a Trusted UI is a bit trickier — we do not want to have something that can be observed easily or simulated by software. Let’s also consider that we can reliably disable the network connection at that time, to mitigate a remote human operator attack.
The easiest solution would be to whitelist addresses or BIP 70 certificates, making sure that only a few addresses or trusted providers can receive transactions. This is interesting, but not flexible enough, so let’s think about it a bit more.
Visual captchas come to mind — hard to solve by software, a confirmation image could include transaction details mixed with a visual clue that the user has to provide back to the TEE to confirm the transaction. However, the state of the art doesn’t look very promising — it’s quite hard to generate good visual captchas, and quite easy to break bad ones. So let’s think again.
So what about text to speech ? Not a lot of research has been done on that, but most solutions are way too big to fit our very limited footprint. However if we remember the good old days, computers could already sort of speak 30 years ago … and we can still use this today. Now we get a confirmation system that’s more acceptable (we can randomize the sentence a bit, change the voice on the fly). Sounds quite bad though, so we’ll let the readers guess which implementation it is and point us to a better one ☺
In conclusion, even if we operate on a device with severe limitations and no Trusted UI, we can still offer a very good protection of Bitcoin assets and keep the user in charge of everything on all deployed TEEs today.
Those were a very short summary of the development diaries of our first TEE application, which will be available as an open beta with limited slots for GreenBits, Mycelium, and any interested developer in the coming weeks. It uses our common Ledger API, so it’s quite easy to leverage for any use case you can have (regular wallet, multi signature …) — if you like to live on the bleeding edge of security, and have a Samsung phone, keep checking this page, or contact us.