[continued from part I]
Choosing between multiple routes
To complicate matters, an NFC controller can support multiple connections and switch between them. For example the PN544 was capable of supporting both the UICC and embedded-SE link. The currently active path is called the “card emulation route.” Until ISIS most Android devices hard-coded this to point to the embedded SE. In principle the setting can be toggled at any time; it is not baked into the controller firmware. But until recently Android NFC stack always issued the command to set the route to eSE during boot and did not provide a way to change that later. (Not that it mattered; on most devices there is no physical wire from UICC to NFC controller. Switching the route would have no effect. More recently the presence of that extra wiring is required for ISIS compatibility.) Conversely an early prototype ISIS device this blogger examined hard-wired the connection to the UICC, guaranteeing that Google Wallet could not run on the device even if the user managed to work around carrier restrictions.
Supporting multiple routes
The preceding discussion makes a simplifying assumption: while multiple secure elements may exist on the phone and attach to the NFC controller, only one of them will ever be used at a time. For example if the user has a payment application residing on the embedded SE and an identity application on the UICC, exactly one of them is externally accessible to an NFC reader at any given time. At best the user has access to some switch in the mobile operating system to toggle between these two options ahead of time, before the tap event.
Luckily one need not rely on such advance planning from the user. Modern NFC controllers have additional smarts to allow multiple card-emulation targets to coexist at the same time. The trick involves implementing the equivalent of content-inspection on incoming ISO7816 commands. Earlier we mentioned that the controller functions as a router, merely shuttling NFC traffic from another nearby peer to its ultimate destination. In reality modern controllers are not passive conduits; they peek at the messages flowing through and make decisions based on the payload.
Deep-packet-inspection, NFC style
That functionality is useful even when there is a single secure element in the picture. Here is a basic user-experience problem for tap-and-pay: when the user taps their device against a point-of-sale terminal and starts a payment event, it is often necessary for an Android application to intervene. For example the user may need to be prompted to enter their PIN if the operation was declined. After the transaction goes through, the application may want to display a confirmation. Minor problem: in card-emulation mode the host does not have any visibility into traffic being sent to the secure element. Incoming requests are delivered directly to the SE, where the responses also originate without ever bubbling up to the host. The user-interface for our hypothetical wallet application would have no idea that the user just tried to make a purchase.
Getting a handle on SE events
Luckily system designers anticipated that problem and introduced some notifications, which are in turn incorporate to the Android NFC stack in the form of notifications delivered to associated applications. Specific triggers include:
- RF field present— in other words, the phone is in proximity of an external reader
- RF field removed
- Application selected
The first two notifications may look promising, without requiring any traffic inspection. RF field presence is about registering the existence of a change in physical environment. If payments were the only application, that would have been sufficient signal to conclude that the user attempted a transaction. (Of course in retrospect that is exactly the only scenario Android eSE was used for on any large scale.) Imagine a more ambitious vision when the SE serves both payment and public-transit scenarios, each of with a corresponding Android user-mode application. Depending on whether the user tapped a cash register or turnstile in the subway, the system needs to wake up the correct app to present additional UI.
That calls for looking at the contents of incoming traffic. Per ISO7816 SELECT commands are used to activate applications. By looking at the application identifier or “AID” specified in that APDU we can determine what type of transaction an external reader attempted. That is effectively the third notification above: it contains the AID for the specific applet selected. (As an aside, on Android only privileged applications whitelisted for NFC-extras receive these intents.) This allows applications to bring up UI– for example PIN entry in the case of Google Wallet– only when they can be certain their own SE applets have been invoked, as opposed to just any random applet.
That was an example where the NFC controller is parsing the contents of a request APDU coming over NFC and bubbling-up a notification to the host. It is also one of the exceptions to a principle described in the first blog post: host does not have visibility into external NFC traffic addressed to the SE in card-emulation mode. (Incidentally Android source code has references to another notification called “APDU received” which promises to return the full contents of an incoming NFC request. It is not implemented, and in fact can not be implemented because most NFC controllers do not have such a capability.)
The next post will describe how this capability in the NFC controlled enables supporting multiple SE simultaneous, as well as allowing SE applications to coexist with host-card emulation.