Mifare Classic Authentication Failure on ST25R3916B
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:
- Ensure Activation State
Before sending authentication commands, we ensure the reader is in the RFAL_NFC_STATE_ACTIVATED state.
- 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.
