Host-Based Card Emulation with Fixed Card Id

Host-based Card Emulation with Fixed Card ID

This is (at least with the official API) not possible:

In the first part of the exchange the HCE device will present its UID; HCE devices should be assumed to have a random UID. This means that on every tap, the UID that is presented to the reader will be a randomly generated UID. Because of this, NFC readers should not depend on the UID of HCE devices as a form of authentication or identification.

(http://developer.android.com/guide/topics/connectivity/nfc/hce.html#ProtocolParams)

Write NFC-A host-based card emulation for CPR 40.30 reader

Android only supports emulation of ISO/IEC 7816-4 application structures on top of ISO-DEP (ISO/IEC 14443-4). The Android API does not provide any means to access emulation of lower protocol layers.

From the developer guide:

Specifically, Android 4.4 supports emulating cards that are based on the NFC-Forum ISO-DEP specification (based on ISO/IEC 14443-4) and process Application Protocol Data Units (APDUs) as defined in the ISO/IEC 7816-4 specification.

Note that the CPR 40.30 should support ISO-DEP too.

How to get AID for reader Host based card emulation

The AID is a "name" that you assign to your smartcard application (in the case of HCE: the Android app that emulates the card application). A reader application uses this "name" to address your card (HCE) application with a SELECT (by DF name/AID) APDU command (see ISO/IEC 7816-4). You can use any value you want as long as it conforms to ISO/IEC 7816-4.

In your specific case, the reader example application uses the AID F0010203040506

private static final byte[] AID_ANDROID = { (byte)0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

Therefore, to be interoperable with that example, you need to register your HCE service for the AID F0010203040506.

How do you assign and use an AID?

Typically, you first define a "name" for your HCE app:

<host-apdu-service ...>
<aid-group ...>
<aid-filter android:name="F0010203040506"/>
</aid-group>
</host-apdu-service>

Later, reader applications can use that name to select your HCE app and to then communicate with it (in Java e.g. using Java Smart Card IO):

Card card = ...;
CardChannel c = card.getBasicChannel();

// SELECT by AID (F0010203040506)
ResponseAPDU resp = c.transmit(new CommandAPDU(
0x00, 0xA4, 0x04, 0x00, new byte[] { (byte)0xF0, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06 }));
assert resp.getSW() == 0x9000;

// Send application-specific command (what such a command could look like depends on your application)
resp = c.transmit(new CommandAPDU(
0x80, 0x10, 0x00, 0x00, new byte[] { (byte)0x12, (byte)0x34 }));

How do you come up with a value for an AID?

This depends on your application scenario.

  • In your closed-loop scenario, where you are under full control of both the HCE side and the reader side, you can choose an arbitrary (note that there are some rules for AIDs) AID and assign it to your HCE app. You can later use that AID in your reader application to address the HCE app.

  • In real-world HCE scenarios, you often design your HCE app to interact with an existing reader infrastructure. Consequently, your HCE app will implement some given specification. In that case, such a specification will dictate the AID (or AIDs) that your HCE app needs to use in order to be discoverable by the existing reader infrastructure. An example for such a specification is the EMV specification for contactless payment systems.

Why are some HCE applications registered for multiple AIDs?

Sometimes there is the need that an application is addressable through multiple "names" (AIDs). Reasons could be:

  • An application provides multiple different interfaces (i.e. that have a different command set or provide different data).
  • There are existing readers that use (for some reason) different AIDs to address the same application.

How do you choose an AID?

The rules for smartcard application identifiers (AIDs) are defined in ISO/IEC 7816-4. An AID has at least 5 bytes and may consist of up to 16 bytes (see this answer on AID size restrictions). Based on the first 4 bits, AIDs are divided into different groups. The most relevant groups defined in ISO/IEC 7816-4 are:

  • AIDs starting with 'A': internationally registered AIDs
  • AIDs starting with 'D': nationally registered AIDs
  • AIDs starting with 'F': proprietary AIDs (no registration)

For (inter)nationally registered AIDs, the AID is split into two parts, a 5-byte mandatory RID (registered application provider identifier), and an optional PIX (proprietary application identifier extension) of up to 11 bytes.

For proprietary AIDs (F...), you can use any arbitrary value.

Why did the AID F00000000A0101 work while F0010203040506 did not work?

I don't know and you did not provide sufficient information to diagnose this. E.g. where there any messages in adb log when you tried to select F0010203040506?

Anyways, both AIDs are valid and should work. One possibility could be that you already had another HCE application installed on your device that registered for that AID. In that case, two applications would have listened for the same name which is not possible.

Samsung device nfc mode and host card emulation

My Samsung Device does not have 2 separate NFC modes but does have 2 different NFC capabilities - Emulation a Card or Reading/Writing to a Card. But these capabilities are not mutually exclusive they are enabled together.

It does have 2 locations where Card Emulation can happen, the first being in the NFC's Chip Secure Element (an independent CPU) or on the Host CPU (Hence the term Host Card Emulation).

All card emulation is about emulation of Type 4 NFC vards (Credit cards and similar cards)

Type 4 Nfc cards have an "Application Identifier" number or AID that identifies the format to the card.

Normally the Secure Element handles the AID's first that it has been configure to process before passing them on to the Host CPU. Normally the order of routing of AID's is seamless with Secure Element first, then Host CPU but Samsung does offer settings to change this order.

But

NfcAdapter.isEnabled() says

If this method returns false, the NFC hardware is guaranteed not to generate or respond to any NFC communication over its NFC radio.

My understanding is the UI setting that influences this status is basically a hardware power switch for the NFC chip, if this returns false the chip is turned off and won't do any NFC (Secure Emulation, Host Emulation or reading/writing)

So I would check NfcAdapter.isEnabled() before starting your HCE service.

Host-based Card Emulation, any guidance please?

Before CyanogenMod 11, CyanogenMod supported its own host-based card emulation functionality. You could register a foreground dispatch for the android.nfc.tech.IsoPcdA technology and could then emulate a smartcard by using the IsoPcdA.transceive() method. See Nikolay Elenkov's blog post on how to use this API.

However, browsing through the CyanogenMod 11 source (specifically tht of the NFC service) it seems that this functionality has been dropped in version 11 in favor of Android 4.4's official HCE API.

The official Android 4.4 HCE API permits apps to emulate a contactless smartcard (ISO 14443-4 + ISO 7816-4 APDUs) in an Android service. That service would handle all incoming command APDUs for an application and generate proper response APDUs. See the official API user guide for further information on how to register such a HCE service and this answer on how to handle incoming command APDUs within your HCE service.

Unfortunately this API is not available either on devices that use libnfc-nxp as the low-level NFC stack (see the empty implementation of routeAid() and enableRoutingToHost() in the CyanogenMod 11 source code).

So to summarize this, it seems as if it's currently not possible to do host-based card emulation on a Nexus S with CM 11.



Related Topics



Leave a reply



Submit