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

Reply via email to