Emulate Mifare Card with Android 4.4

Emulate Mifare card with Android 4.4

With host-based card emulation (HCE) in Android 4.4 you can only emulate the ISO/IEC 14443-4 protocol. More specifically you can only emulate application structures according to ISO/IEC 7816-4 (thus card emulation applications need to be selected though an AID). Moreover, the API doesn't give you any means to specify if card emulation should be done using Type A or Type B protocol.

So regarding emulation of various MIFARE protocols:

  • MIFARE Ultralight (and derivates) protocol operates on top of ISO/IEC 14443-3. It is not possible to emulate cards using such low layer protocols using Android HCE.
  • MIFARE Classic protocol partially operates on top of ISO/IEC 14443-3 (with some different framing). Thus, its also not possible to emulate MIFARE Classic using Android HCE.
  • MIFARE DESFire protocols operate on top of ISO/IEC 14443-4. There are three variants of the DESFire protocol:

    1. native protocol: As this protocol does not use APDUs according to ISO/IEC 7816-4 its not possible to emulate it using Android HCE.
    2. wrapped native protocol: This protocol uses APDUs according to ISO/IEC 7816-4, however, readers will typically not issue a SELECT command using the DESFire AID when starting to communicate with a card in wrapped native command mode. (Note: Newer reader implementations are more likely to issue a SELECT command that is compatible with Android HCE as this is also required for some of NXP's newer smartcard products with DESFire protocol emulation.)
    3. ISO protocol: This protocol is based on ISO/IEC 7816-4 and uses application selection by AID. Thus, it may be possible to emulate this protocol using Android HCE.

    Some readers may require certain parameter values in lower protocol layers (such as a specific UID cascade-level, a certain ATQA value, a certain SAK value, or a certain ATS). Android HCE does not have any means to set these values. See Editing Functionality of Host Card Emulation in Android for a possible approach to modify those values on certain rooted devices and my answer to Host-based Card Emulation with Fixed Card ID for a strategy to programatically change those values in a custom ROM.

A note on the HCE feature available in CyanogenMod from version 9.1 to version 10.2: This will emulate any ISO/IEC 14443-4 based protocol without the requirement for an application structure according to ISO/IEC 7816-4. You can even choose if you want to emulate Type A or Type B protocol. So it should be possible (though I haven't tested) to emulate any of the three DESFire protocols. However, even with the HCE feature of CyanogenMod it is not possible to emulate MIFARE Ultralight or Classic protocols. Moreover, it's also not possible to influence low-level protocol parameters such as a UID, ATQA, SAK, or ATS.

MIFARE Ultralight emulation on Android

It's simply not possible to emulate MIFARE Ultralight on top of Android HCE. Android HCE allows emulation of ISO/IEC 7816-4 APDU based applications on top of the ISO/IEC 14443-4 transport protocol only.

MIFARE Ultralight uses only lower protocol layers. Specifically, the Ultralight communication protocol sits directly on top of the framing defined in ISO/IEC 14443-3 Type A without the additional transport protocol. As a consequence, it's impossible to emulate that using a HCE service on Android.

This does not mean that the hardware is incapable of emulating the MIFARE Ultralight protocol. I've verified that at least Broadcom NFC controllers are capable of emulating that protocol. However, implementing that would require quite extensive modifications of the NFC stack and is, consequently, not possible on unmodified, of-the-shelf Android devices.

Also see Emulate Mifare card with Android 4.4

How can I act with Android app as MIFARE card?

The mifare.read_ndef() seems to expect a MIFARE Ultralight (or other Type 2 tag) containing an NDEF message. You simply can't emulate a MIFARE (Ultralight) tag with Android (see Emulate Mifare card with Android 4.4).

What you do on Android, when you use public NdefMessage CreateNdefMessage(NfcEvent e) {} (or actually SetNdefPushMessage*()), is that you define an NDEF message that should be transfered in peer-to-peer mode (using SNEP + LLCP + NFC-DEP). That's a completely different protocol stack than when you read (or emulate) a tag. Consequently, when you want to use peer-to-peer mode on Android, you will need to use a library that supports peer-to-peer mode (and SNEP) on the other end as well.



Related Topics



Leave a reply



Submit