[continued from part III]
Continuing the security comparison between HCE and secure-element based NFC applications, this post expands on an earlier theme around attack-surface, focusing on one massive piece of vulnerable code: the Android operating system itself.
When root means game-over
Consider the following hypothetical: is it possible to build an EMV payment application that runs on Android and yet can resist attacks from a remote adversary who is running arbitrary code with root privileges? At first this seems theoretically impossible. Payments are authorized based on the possession of a cryptographic key only known to the legitimate card holder. The assumption is if you have possession of the key, by executing a protocol specified by EMV that calls for proving possession of that key without revealing it– you are authorized to spend the funds associated with that account. If our hypothetical adversary has achieved root privileges on the device, they have full access to memory and storage of every application running on that device. That includes the payment application wielding this secret. Even if that secret was protected by a PIN/passphrase (let’s suspend disbelief and assume users pick high-entropy secrets immune to guessing) that PIN/passphrase will be input via phone UI such as an on-screen keyboard at some point. Since we posit that our adversary is running with root privileges, she can watch this interaction and learn the passphrase. Alternatively she can simply wait until after the secret has been fully decrypted locally– necessary for the device to be able to perform the type of computations envisioned by EMV payment protocols– and capture it at that point. No secret managed completely by an Android application can be immune from an attacker with root privileges on that Android device. It’s only a matter of knowing when/where to look for that secret in the target application’s address space; this is security through obscurity at best.
Unless of course, the secret is not directly available to the mobile application either. Enter hardware secure elements. If secrets such as cryptographic keys are stored in the secure element and never available in the clear to the mobile application, even root-level compromise of Android does not help our adversary. The embedded secure element is its own mini-computer, with separate RAM, storage and embedded operating system with its own concept of access control. Being root on Android is meaningless to SE: it grants no special privileges. In much the same way that an HSM can isolate cryptographic keys by offering an interface to perform operations with the key without revealing the raw bits of the key, SE keeps Android at arms-length from secret material.
The astute reader might ask how these cryptographic secrets that enable payments reached the secure element in the first place. It is common for provisioning to take place over-the-air, as opposed to the much more impractical alternative of requiring physical presence, where the user must walk into a bank branch and present their phone. That implies that some bits are pushed over the network to the mobile application which relays them to the secure element. (Recall that the only direct network interface SE has access to is NFC which is only good over short distances. All other communication such as accessing the card-issuer API endpoint over the Internet must be pass through the host device.)
Does that create an opportunity for malware running with root privileges to capture the secret, for ever so briefly when it is passing through the Android application? Not if the provisioning system is properly designed. Recall that secure elements compliant with Global Platform standard are “personalized” with unique keys (colloquially known as card-manager keys) required to perform administrative operations. These keys are not known to the owner of the phone or even the operating system on the mobile device; they are managed by a third-party called “trusted services-manager” or TSM. When TSM is installing a payment application and configuring that application with its own set of secrets, the commands sent to the SE for performing those steps are encrypted. Global Platform specification defines a “secure messaging” protocol describing the exact steps for establishing an authenticated & encrypted link between TSM and secure element. This protocol, or more accurately series of protocols since there are multiple variants, is designed to ensure that even when TSM and SE are not in physical proximity, as in the case of provisioning a payment application over the Internet– the issuer can be assured that sensitive information such as payment keys are delivered only to the designated SE and not recoverable by anyone else. While it is true that the commands sent by TSM are visible to the host operating system, where they can be intercepted or even modified by our hypothetical adversary who has attained root privileges, the secure messaging protocol ensures that no useful information is learned by mounting such an attack.
Threat models: ideal vs as-implemented
So this is another fundamental difference between applications implemented in SE versus those relying on host-card emulation. For HCE applications, Android operating system is part of the trusted computing-base by necessity. Any vulnerability that allows defeating the isolation between different apps– such as local privilege escalation to root– is game-over for scenarios using host-card emulation without a hardware secure element. By contrast, SE based applications can in principle survive attacks in this very stringent threat model, where we posit a remote adversary (eg one who does not have physical possession of the phone but is running her choice of code on the device) has attained root privileges.
“In principle” is the operative phrase. While Global Platform protects secrets en route the secure element, there is a preceding step not covered by GP: authenticating the card-holder. Suppose the consumer is asked to enter the username and password for their online bank account into the Android application to verify their identity and request provisioning from that bank. That design is blatantly vulnerable to local malware on the device. Those bank account details could be captured and relayed to a remote attacker, who proceeds to repeat the exact same process on a device she controls, with the payment credentials being delivered to her secure element. She could even preempt the legitimate user, by provisioning first and instructing the malware to prevent the original card-holder from completing the task, lest the bank notice the anomaly of two different devices requesting cards in quick succession. Some form of out-of-band authentication is required to thwart this attack, such as logging into the bank website from a different machine to initiate the request. (Ironically calling the bank and answering questions will not work since the audio-stream from the phone is also available to the attacker.) But even in the basic scenario with weak provisioning, SE provides a useful guarantee: if the device is compromised by malware after payment credentials are provisioned, the credentials are safe.
There is one more subtle attack that does not rely on trying to extract secrets from the local device. Suppose the remote attacker with root privileges abandons their effort to extract secrets from SE but instead attempts to use the SE, exactly as it would have been invoked for a payment transaction? The next and final post in this series will look at how the integration of SE with NFC controller can frustrate such relay attacks, in stark contract from HCE applications which are necessarily vulnerable.