Part III sketched the mechanics for host-based card emulation (HCE) in Android and how AID routing is used to create an open ecosystem for user-mode applications to offer NFC services. This post will look at some edge-cases of HCE and some differences from the embedded secure element.
A natural question is whether HCE is “equivalent” to embedded SE or UICC from a functional perspective. (It is clearly weaker in terms of security guarantees, a subject for the next post in this series.) There are two different interpretations of that criteria:
- Can any application implemented with hardware SE also work with HCE?
- Is it possible to distinguish externally whether HCE or hardware SE is in use?
In the first scenario we assume external NFC readers interacting with the device remain fixed. No changes are envisioned to the deployed readers while we switch the phone from using eSE to HCE. This is the model relevant for compatibility. In the second case the NFC reader is going out of its way to try to distinguish between hardware and software-backed implementations.
Short answer to #1 is yes in principle, but not the way it is currently implemented in Android due to some edge-cases. SELECT semantics in Android HCE are subtly incompatible with the way a Global Platform compliant card-manager behaves.
- If an application with given AID exists, card manager switches the active context to that one. This is outside the control of the currently selected application.
- If such an application does not exist, the SELECT command in its entirety is delivered to the currently active application. This is required because ISO7816 “overloads” SELECT command for simulating a file-system on smart cards. The command corresponds to “directory” traversal (eg change directory) as well as opening a “file” for reading, depending on the currently selected “file.”
The second part does not work with HCE in Android. SELECT routing is handled by the OS and for unknown AIDs a simple error is returned instead of giving the current application an opportunity to respond.
Another difference is that in Global Platform, an application can be installed as “default-selected” meaning that it is automatically activated when the chip is powered on. There is no SELECT required, readers can start sending application-specific commands right away. Several smart card standards including PIV mandate that cards are configured in this manner. Android HCE does not support this. Trying to interact with the phone in HCE mode as if the intended application was already activated (without an explicit SELECT containing the AID as hint to Android) is an error.
Neither of these are fundamental limitations. SELECT behavior can be changed and NFC stack can also define a notion of “default selected application,” along with conflict-resolution rules.
By similar reasoning, distinguishing HCE from hardware SE is trivial in the current Android incarnation: try to select the card manager, either by using its explicit AID (slightly different for each manufacturer such as NXP vs Oberthur) or with empty SELECT per Global Platform. Hardware SE will return the response from the card manager describing its functionality, HCE mode will return an error.
But as noted above this is not a hard limitation. A “card manager” replacement complete with cryptographic keys, secure channels and lifecycle management (so it will appear to be bricked after too many failed authentication attempts) can be implemented at Android level, set as default selected application. To an observer looking only at the content of messages flowing over NFC, this emulation will behave identical to hardware SE.
Of course there are side-channels such as the timing of request/response pairs and other meta-data that can give away the source. For example if eSE supports extended-length APDUs (HCE in Kitkat does not) that discrepancy can be used, or the buffering behavior when reading large APDUs can be different since the host has lots of memory and won’t exhibit a sharp discontinuity when the data suddenly exceeds the size of the limited buffer in eSE.
Coexisting with hardware SE
Interesting enough, Kitkat still allows using the embedded-secure element alongside HCE, perhaps in a nod to backwards compatibility. This mode leverages the AID-routing feature built into the NFC controller, which allows picking a card-emulation route on-the-fly based on AIDs at the hardware level. (Same mechanism used to support applets on both UICC and eSE when multiple chips are connected to the controller.)
All AIDs for applications residing on the secure element need to be declared in the manifest. Android passes this information straight to the NFC controller; the routing decision is made at hardware level. SELECT commands for these applications will not make it to host operating system. NFC controller internally maintains a table of AIDs and associated routes. It is the responsibility of Android to populate that table based on information collected across all manifests. Any application not explicitly listed is sent up the default route.
There is a catch. NFC controllers have a limited amount of space available for maintaining such tables. The ideal scenario has most applications residing at the default route and not requiring a table-entry, with only a few exceptions listed for redirection. Seen in this light, decision to use HCE as default and embedded SE as the exception reaffirms the change in emphasis from relying on hardware SE towards host-based designs.