cancel
Showing results for 
Search instead for 
Did you mean: 

Mifare Classic Authentication Failure on ST25R3916B

AMCI
Associate

We are using an ST25R3916B  to read and write to both ST25TV512C tags and Mifare Classic 1K cards. While we have successfully communicated with ST25 tags, we are encountering issues at the authentication stage with Mifare Classic.

Steps We Are Following:

  1. Ensure Activation State

Before sending authentication commands, we ensure the reader is in the RFAL_NFC_STATE_ACTIVATED state.

  1. Send Authentication Command to Retrieve the 4-Byte Challenge

Mifare Classic authentication follows a challenge-response mechanism. To begin, we must send the authentication command and obtain a 4-byte random challenge from the card.

The command consists of:

  • Byte 0: Authentication command (0x60 for Key A, 0x61 for Key B).
  • Byte 1: Target block number.
  • Bytes 2-7: 6-byte key (Key A or Key B).
  • Bytes 8-11: Card UID (copied from the detected card structure).

uint8_t authCmd[12];

authCmd[0] = 0x60; // Authenticate using Key A

authCmd[1] = block; // Block number

memcpy(&authCmd[2], keyA, 6); // Copy the 6-byte key

memcpy(&authCmd[8], device.nfcid, device.nfcidLen); // Copy the UID

 

We then transmit this using rfalTransceiveBlockingTxRx():

status = driver.rfalTransceiveBlockingTxRx(

    authCmd,         // Transmit buffer

    sizeof(authCmd), // Transmit length

    response,        // Receive buffer

    sizeof(response), // Max receive length

    &responseLen,    // Actual response length

    RFAL_TXRX_FLAGS_DEFAULT,

    RFAL_FWT_NONE

);

  • If successful, the card should respond with a 4-byte challenge.
  • This challenge must be processed using the Mifare Classic 48-bit cipher to generate the authentication response.

Current Issue

In the code below, I attempt to send only 4 bytes for authentication, which includes CRC values (D1 and 3D) for 0x60 and 0x04:

uint8_t authCmd[4];

authCmd[0] = 0x60;  // Authentication command (Key A)

authCmd[1] = 0x04;  // Block number

authCmd[2] = 0xD1;  // CRC for 60 and 04

authCmd[3] = 0x3D;  // CRC

 

status = driver.rfalTransceiveBlockingTxRx(

    authCmd,         // Transmit buffer

    sizeof(authCmd), // Transmit length

    response,        // Receive buffer

    sizeof(response), // Max receive length

    &responseLen,    // Actual response length

    RFAL_TXRX_FLAGS_DEFAULT,

    RFAL_FWT_NONE

);

  • I receive ERR_IO (3), which is a generic I/O error.
  • Sometimes, I get ERR_TIMEOUT (4), but I believe ERR_IO is the root cause.

 

What I Need Help With

  • What RFAL calls should I use after reaching RFAL_NFC_STATE_ACTIVATED to retrieve the 4-byte challenge?
  • Am I correctly handling Mifare Classic authentication in RFAL?
  • Should I allow RFAL to handle CRC, or should I manually append it?
  • Any debugging suggestions for ERR_IO?

Any help would be greatly appreciated.

Thanks in advance.

 

This discussion is locked. Please start a new topic to ask your question.
12 REPLIES 12

Hi, 

please share traces! And I recommend to not use your own driver - even more hassle ahead.

Please start from something working. A first starter would be using one of our demos. Here a recipe:

On ST25R3916-DISCO GUI with STEVAL-25R3916B: ISO14443A tab: "Configuration" and "WUPA->Active". Should show the UID

Then switch to debug tab. There you can then execute

  • TxRxNBytes with CRC_TX_AUTO=PAR_TX_:AUTO=checked: 60 04. GUI will report a CRC error but bytes are there in firmware. Alternatively:
  • TxRxNBytes with CRC_TX_AUTO=PAR_TX_:AUTO=unchecked: 60 09 44 ef 01 with 4 bits in last byte and manual RX settings:cmd6004_exec.png
    This string is equivalent to the 60 04. CRC is d1 3d and with parity you get to this string.

BR, Ulysses

Hi Ulysses,

Thanks again for your earlier guidance. I wanted to follow up with some results:

  • Using the “WUPA → Active” flow in the ISO14443A tab, I successfully retrieved the UID from the tag:

UID: 4D 2C 05 10

  • The GUI reports that the transponder is not ISO/IEC 14443-4 compliant, which aligns with the tag being a MIFARE Classic or another ISO14443-A Level 1 type.

Following your advice, I attempted both REQA options in the Debug tab:

Option A: Auto CRC / Parity

  • 60 04
  • CRC_TX_AUTO and PAR_TX_AUTO checked
  • 4 bits in last tx byte
    • Result: Timeout

AMCI_0-1743779771434.png 

 

Option B: Manual CRC / Parity

  • 60 09 44 ef 01
  • CRC_RX_MANUAL, CRC_RX_KEEP, PAR_RX_KEEP checked
  • Auto TX options disabled
  • 4 bits in last tx byte
    • Result: Timeout

AMCI_1-1743779771436.png

 

So far, I have only seen a response from the tag when using the built-in WUPA → Active GUI flow. That works consistently and returns the correct UID.

Please let me know if you see anything off in the manual frame or have additional suggestions for debugging the REQA behavior from the Debug tab.

- AMCI

Hi,

please beware that for your target command to be accepted by the the card it needs to be in ACTIVE state. You need to go to ISO14443-A tab: Configuration + WUPA->Active. Then you can switch to Debug tab and execute one time a command as I had shown in my previous post.

You will not be able to repeat this command  or send the another command (even if not answered) - you need to go back to ISO14443-A tab and repeat the whole sequence.

With any unknown command the tag will fall out of its current state.

Of course if you receive a positive answer you could continue with the next well-formed command.

Not sure about your reference to REQA: This command (and WUPA) wakes a tag. It is not sufficient to move the tag into Active state. For the active state also the complete AC/Select procedure are required. This is what these buttons on ISO14443-A tab do.

BR, Ulysses