Hi everyone,
Firstly I'm extremely sorry for hijacking this thread, but this appears to be where all the activity regarding NFC on Android is occuring, and so should reach the relevant audience. I've recently read through a lot of information regarding the implementation of NFC, Google Wallet, card emulation etc.. on the Galaxy S. I've tried to document all that I have learned below. It would be extremely helpful if people could read this, pull it apart, point out bits that are wrong etc.. Hopefully this can help other people who are trying to learn about the implementation, saving them some time. I've not discussed absolute specifics about protocols and whatever, but if I've mixed up terms (such as incorrectly mentioning the use of ADPUs), please correct them as well :) This documentation should hopefully prevent some repeated questions also... -------- Within the Nexus S is contained an NXP PN65N nfc ic, which is similar to a PN544, but with an internally connected SmartMX 'secure element'. The secure element (SE) is 'logically connected' to the PN544 via an NFC-WI interface. All of this is contained within the PN65N. The SE runs a JavaCard operating system. One Java application included on the SE is an implementation of the GlobalPlatform specs. Through communication to and from this app (using the correct keys), other javacard apps can be installed. (such as a Google wallet app). The SE is also configured to emulate a Mifare classic 4K card. Currently, the default keys allow read/write access to this emulated 'card'. The PN544 has 3 modes of operation. Reader/Writer mode, peer-to-peer mode, and card emulation mode. In card emulation mode, there two different 'sub-modes' of operation: 1. The PN544 acts as a dumb 'frontend' to the secure element. This allows contactless communication directly with the secure element using external reader/writers. At this point, the entire system is functionaly identical to a wireless JavaCard, which is capable of both emulating a normal Mifare 4K card, (ISO14443-3) and allowing access to javacard apps (using ADPUs) (ISO 14443-4). 2. The PN544 acts as a reader/writer, with the secure element appearing as an attached wireless card. This presents a similar situation as 1), but in reverse (the host can now communicate with the secure element, pretending it is a contactless javacard). The PN544 supports using 'emulation mode' with either a secure element (using the NFC-WI protocol), or a UICC (a.k.a SIM card), using an SWP bus. However, when using a UICC, sub-mode 2) is unavailable. Therefore, a host can only communicate (via the PN544) to the secure element. The word 'communication', in this context, means the ability to pass ADPUs back/forth from the host to the 'emulated' card (either SE or UICC). Typically this is not a problem, as the host can normally communicate (pass ADPUs) directly to the UICC via other channels. In Android, however, the RIL does not currently provide direct access to the SIM card, so ADPU exchange with the SIM card is not currently possible. Android currently contains official APIs to make use of the reader/writer and peer-to-peer modes of the PN544. The official NXP host stack also contains code to use the 'card emulation' mode also. The code used to be commented out, but later versions of Android have the code present. No public Java Android APIs currently exist to make use of this however. Google have preprogrammed the GlobalPlatform access keys, and so are in control of exactly what javacard apps are loaded onto the secure element. They are a 'TSM'. Google Wallet makes use of undocumented Java Android APIs to enable card emulation mode on the PN544. This is only possible because of the recently uncommented code within the native official NXP host stack code. Google Wallet also communicates with an installed javacard app, to setup 'whatever-it-is-the-credit-card-companies-need-on-the-card'. This is the same javacard app that is interacted with by external pay-terminal reader/writers. For a normal, un-rooted phone, communication with the secure element (using ADPUs) (a.k.a enabling card emulation mode 2) is only possible using an APK that has been signed with a special key, which Google hold. The Android OS verifies the keys before allowing use of some (currently undocumented) Java API.* Having an rooted phone allows bypassing of this restriction, such that any APK can successfully enable emulation mode, perform ADPU communication with the secure element, and thus interract with javacard apps (including the GlobalPlatform app). However, as we do not know the GlobalPlatform keys, we are unable to add/remove javacard apps from the secure element. 10 failed authentications with the GlobalPlatform app will cause a permenant lockout, preventing any future add/remove operations for javacard apps. Existing javacard apps will continue to work, however. ------- Now for things I'm not sure about: Does Google Wallet make use of native APIs or Java APIs to communicate to the secure element. I.e., is it talking to the NXP NFC stack directly, or through some Android-like API? People who are receiving the 'secure element not responding' error are presumably failing to authenticate with the Google Wallet javacard app which has been installed. However, people seem to be mentioning that this error means the SE is 'bricked', which I would interpret as the lockout from the GlobalPlatform app due to 10 failed auths. Anybody know exactly what is going on here? I think I read somewhere that the google wallet javacard app is only installed onto the SE after successful setup of the Google Wallet app. I.e. it is not factory installed. If so, how does secure communication occur with the GlobalPlatform app. Does Google Wallet perform this (I guess not, as we could find the keys from the APK). How do the GlobalPlatform keys get securely transmitted to the SE? With SIM cards I think binary SMSs are used to OTA chat with the radio interface, but obviously that can't happen here. Regards, xanium -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en