Skip to main content
Olivier Bontron
Associate II
October 2, 2019
Solved

NFC0541 read Mifare Classic 1K

  • October 2, 2019
  • 24 replies
  • 9773 views

I’m using NFC05A1 and the STMF4xx-Nucle-Polling project.

I’d like to interact with  a Mifare classic card 1K.

I am aware Stm won’t provide any code that would deal with encryption and this is not what I’m asking for.

The issue I encounter is about the first step after SELECT : this is a clear text message, starting with 30 then the sector number. What I expect is the card answering with a nonce.

The issue I encounter is I receive a ‘framing problem’ or ‘timeout’ error message.

Here are the first four requests, which are working fine I think, the fifth one does not.

* Request 1:

Answer to rfalISO14443ATransceiveShortFrame  (with RFAL_14443A_SHORTFRAME_CMD_REQA as a command) is : 04 00.

* Request 2:

Then there is another rfalISO14443ATransceiveShortFrame   instruction this time with RFAL_14443A_SHORTFRAME_CMD_WUPA

*Request 3:

Then a rfalNfcaSelReq  structure is set :

selReq (rfalNfcaSelReq  structure)

selReq.selCmd = 93

selReq.selPar =20

rfalNfcaTxRetry( ret, rfalISO14443ATransceiveAnticollisionFrame( (uint8_t*)&selReq, &bytesTxRx, &bitsTxRx, &bytesRx, RFAL_NFCA_FDTMIN ), ((devLimit==0)?RFAL_NFCA_N_RETRANS:0), RFAL_NFCA_T_RETRANS );

Request answer : the request result consists in

the card Uid  D0 74 CC A4, (correct uid)

and the bcc CC

*Request 4:

Then another request is a SELECT.

selReq.selCmd =93;

selReq.selPar= 70;

selReq.nfcid1[0]= D0

selReq.nfcid1[1]=74;

selReq.nfcid1[2]=CC;

selReq.nfcid1[3]=A4;

selReq.bcc=CC;

       rfalNfcaTxRetry( ret, rfalTransceiveBlockingTxRx( (uint8_t*)&selReq, sizeof(rfalNfcaSelReq), (uint8_t*)selRes, sizeof(rfalNfcaSelRes), &bytesRx, RFAL_TXRX_FLAGS_DEFAULT, RFAL_NFCA_FDTMIN ), ((devLimit==0)?RFAL_NFCA_N_RETRANS:0), RFAL_NFCA_T_RETRANS );

Its results can be found within selRes :

Sak:  08

So far, the device is a Mifare Classic (sak 08) , this device is device[0] and its uid is known.

*Request 5 : this is where there is an issue.

Ask the card to access sector 00.

As Mr Michael Roland suggested in this post :

https://stackoverflow.com/questions/56334836/is-there-any-function-for-reading-nfc-a-iso14443a-tag-with-x-nucleo-nfc05a1

lenTx = 0;

bufferTx[lenTx++] = 0x30;

bufferTx[lenTx++] = 0x00; // sector

lenRxMax = 16;

lenRx = 0;

status = rfalTransceiveBlockingTxRx(&bufferTx[0], lenTx, &bufferRx[0], lenRxMax, &lenRx, RFAL_TXRX_FLAGS_DEFAULT, rfalConvMsTo1fc(5));

Answer

status value :  9

Another attempt with different flags.

status = rfalTransceiveBlockingTxRx(&bufferTx[0], lenTx, &bufferRx[0], lenRxMax, &lenRx,

RFAL_TXRX_FLAGS_CRC_TX_AUTO | RFAL_TXRX_FLAGS_CRC_RX_REMV | RFAL_TXRX_FLAGS_NFCIP1_OFF | RFAL_TXRX_FLAGS_AGC_ON | RFAL_TXRX_FLAGS_PAR_RX_REMV | RFAL_TXRX_FLAGS_PAR_TX_AUTO | RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO, RFAL_NFCA_T_RETRANS);

Same answer

status value :  9

ERR_FRAMING                          = 9, /*!< Framing error */

I’ve added some logs within rfalTransceiveBlockingRx to have a look at the states :

platformLog("gRFAL.state %d\r\n", gRFAL.state);

do{

    rfalWorker();

    platformLog("gRFAL.TxRx.state %d\r\n", gRFAL.TxRx.state);

  }

Logs for the successful requests (REQA, SEL) are :

gRFAL.state 3

gRFAL.TxRx.state 83 (RFAL_TXRX_STATE_RX_WAIT_RXS)

gRFAL.TxRx.state 90 (RFAL_TXRX_STATE_RX_FAIL)

gRFAL.TxRx.state 0 (RFAL_TXRX_STATE_IDLE)

status is 0 ERR_NONE            

Logs for the last read request are :

gRFAL.state 3

gRFAL.TxRx.state 83(RFAL_TXRX_STATE_RX_WAIT_RXS)

gRFAL.TxRx.state 84 (RFAL_TXRX_STATE_RX_WAIT_RXE)

gRFAL.TxRx.state 84

gRFAL.TxRx.state 84

gRFAL.TxRx.state 84

gRFAL.TxRx.state 84

gRFAL.TxRx.state 84

gRFAL.TxRx.state 90(RFAL_TXRX_STATE_RX_FAIL)

gRFAL.TxRx.state 0(RFAL_TXRX_STATE_IDLE)

status is 9 ERR_FRAMING /*!< Framing error */

Many thanks in advance,

Olivier

    This topic has been closed for replies.
    Best answer by Olivier Bontron

    Dear Ulysses,

    Thank you so much for your invaluable answer.

    I went through your template and managed to get how you went from 'a2 0f' … to 'a2 1e' …

    Despite I’m not at ‘write’stage but still in the ‘authentication’ process, I guess the rationale is alike and if so the template you sent will definitely  help a lot.

    The answer the reader should send back to the card for authentication is made of :

    8 bytes + 1 parity bit on each byte + 2 bytes CRC (on these 8 bytes) + 1 parity bit on CRC bytes (as you said 'Also the CRC bytes again will have a parity'.).

    Once reshifted the way the template is, the size stays unchanged : it makes

    8 * 8 bits + 8 * 1 bit + 2 * 8 bits + 1 bit = 89 bits.

    This is the situation you described with the 36 bits example, which requires to be sent in raw mode, isn'it?

    Could you tell me how to opt for raw mode please ?

    Thanks in advance

    Olivier Bontron

    24 replies

    Olivier Bontron
    Associate II
    October 2, 2019

    Addendum

    With

        rfalNfcaTxRetry( ret, rfalTransceiveBlockingTxRx(&bufferTx[0], lenTx, &bufferRx[0], lenRxMax, &lenRx, RFAL_TXRX_FLAGS_CRC_TX_AUTO | RFAL_TXRX_FLAGS_CRC_RX_REMV | RFAL_TXRX_FLAGS_NFCIP1_OFF | RFAL_TXRX_FLAGS_AGC_ON | RFAL_TXRX_FLAGS_PAR_RX_REMV | RFAL_TXRX_FLAGS_PAR_TX_AUTO | RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO, RFAL_NFCA_T_RETRANS), ((devLimit==0)?RFAL_NFCA_N_RETRANS:0), RFAL_NFCA_T_RETRANS );

    instead of directly rfalTransceiveBlockingTxRx

    the result is now

    4 ERR_TIMEOUT

    Olivier

    Brian TIDAL
    Technical Moderator
    October 2, 2019

    Hi,

    0x30 00 is a READ block number 0 command. It is a memory read operation on this tag.

    Such tags require proprietary authentication before any memory operation except for some personalization (see datasheet from the manufacturer of these tags) . If you want to use such tags with the ST25R3911B reader, you will have to implement this proprietary authentication and the ciphering. See other posts on this topic in this forum. READ of the block 0 without authentication after selection is only possible with a specific personalization of such tag.

    I would rather recommend to use fully compliant tags from the ST25 family such as ST25TA (Type 4A Tags) or fully compliant Type 2 Tags (i.e. tags not requiring proprietary stuff).

    Rgds

    BT

    In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
    Olivier Bontron
    Associate II
    October 3, 2019

    Dear Brian,

    Thank you so much for your answer.

    I wish I could use fully compliant cards but I can’t!

    Thanks to correct me about the ‘30’ command.

    It seems 60 instead of 30 would be more appropriate :

    The error now is 21 which is a crc error.

    I’ll switch to manual CRC and try to append the CRC to the txBuffer.

    I hope I’ll get the expected answer in return : I expect a nonce which would mean the authentication process has begun.

    Thanks again,

    Best regards,

    Olivier Bontron

    Brian TIDAL
    Technical Moderator
    October 3, 2019

    Hi,

    I would suggest to post questions regarding tag commands to the tag manufacturer community. Anyway, as far as I know 0x60 is not a read command but a Authentication command.

    For your information, ERR_CRC means that the CRC of the rx frame is erroneous. It is not related to the tx frame.

    Rgds

    BT

    In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
    Olivier Bontron
    Associate II
    October 3, 2019

    Hi,

    Ok, I'll handle the tag commands separately, thanks anyway for having provided guidance about the '30' issue.

    TxBuf starts now with 60, 00 and then  I append manually the crc to the buffer. The flag is set to manual.

    The tag command looks now very similar to what I found from the manufacturer when it comes to authentication.

    At least, there is no CRC error any longer.

    Now the error is '4 timeout'.

    Before ending with a 4 timeout error, the logs tell :

    The gRFAL.TxRx.state is 83 RFAL_TXRX_STATE_RX_WAIT_RXS

    During rfalTransceiveRx, logs show that the case  RFAL_TXRX_STATE_RX_WAIT_RXS is processed,

    during which it turns out that this condition is met :

     if( (irqs & ST25R3911_IRQ_MASK_NRE) && !(irqs & ST25R3911_IRQ_MASK_RXS)){

    gRFAL.TxRx.status = ERR_TIMEOUT;

    gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;

    break;

    }

    It seems that's where the ERR_TIMEOUT comes from.

    Would you know how to interpret this condition (irqs & ST25R3911_IRQ_MASK_NRE) && !(irqs & ST25R3911_IRQ_MASK_RXS)

    and which corrective action to take ?

    Is there a manual I should read first

    Many thanks in advance.

    Olivier Bontron

    Ulysses HERNIOSUS
    Technical Moderator
    October 3, 2019

    Hi Olivier,

    timeout just means no response from the card. Absolutely normal if the card did not understand the reader request. For the previous content the card was replying = recognizing the command.

    If you read about the weaknesses of these cards you will learn why the responses will not be recognized as a valid frame by the reader when using default transceive flags.

    Regards, Ulysses

    Olivier Bontron
    Associate II
    October 4, 2019

    Hi Ulysses,

    Thanks.

    So I'll try to figure out why responses are not recognised as a valid frame and change the transceive flag consequently.

    Best regards

    Olivier

    Olivier Bontron
    Associate II
    October 3, 2019

    Addendum

    The logs tell irqs = 16384 or 0x00004000

    I have the ST25R3911B datasheet where terms like ST25R3911_IRQ_MASK_RXS can't be found, that's why I ask whether there is something else to read.

    Best regards

    Olivier

    Brian TIDAL
    Technical Moderator
    October 3, 2019

    Hi,

    ST25R3911_IRQ_MASK_RXS is the C macro to mask the I_rxs (start of receive) interrupt. Therefore ST25R3911_IRQ_MASK_RXS is not described in the Datasheet.

    It is likely that your frame waiting time (FWT) is too short. I guess you are using RFAL_NFCA_FDTMIN whereas the tag you are using may send its reply after tAck delay. Make sure to use rfalTransceiveBlockingTxRx with the appropriate FWT parameter in line with the maximun tAck value for each command (see the tag datasheet for the different max tAck value for different commands).

    Rgds

    BT

    In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
    Olivier Bontron
    Associate II
    October 4, 2019

    Dear Brian,

    That's right, I am using RFAL_NFCA_FDTMIN.

    I'll have a look at the tag datasheet.

    Thanks for your answer

    Best regards,

    Olivier

    Olivier Bontron
    Associate II
    October 8, 2019

    Hi Brian,

    Fwt : modified to rfalConvMsTo1fc(100) (N°1 below) and back to RFAL_NFCA_FDTMIN set to 16200 instead of 1620 (N°2 below).

    Flags : used these flags that are not default flags :

        status = rfalTransceiveBlockingTxRx(&bufferTx[0], lenTx, &bufferRx[0], lenRxMax, &lenRx, RFAL_TXRX_FLAGS_PAR_TX_AUTO | RFAL_TXRX_FLAGS_CRC_TX_AUTO | RFAL_TXRX_FLAGS_CRC_RX_REMV | RFAL_TXRX_FLAGS_PAR_RX_KEEP, rfalConvMsTo1fc(100));

        status = rfalTransceiveBlockingTxRx(&bufferTx[0], lenTx, &bufferRx[0], lenRxMax, &lenRx, RFAL_TXRX_FLAGS_PAR_TX_AUTO | RFAL_TXRX_FLAGS_CRC_TX_AUTO | RFAL_TXRX_FLAGS_CRC_RX_REMV | RFAL_TXRX_FLAGS_PAR_RX_KEEP, RFAL_NFCA_FDTMIN);

    In both cases, the log tells :

    ERR_INCOMPLETE_BYTE                  = 40, /*!< Incomplete byte rcvd        */

    The reason why I set the flag to RFAL_TXRX_FLAGS_CRC_RX_REMV is that the former Log was   ERR_CRC                              = 21, /*!< crc error */

    I already mentioned this log and you said in your former post that this error refered to Rx, not Tx, so I tried to sort this out this way.

    The situation now seems to be :

    If the RX CRC is being kept : error since it is a wrong CRC

    If the RX CRC is being removed (REMV) : error since byte is incomplete.

    It's not the only possible explanation, maybe another expected content like PAR is missing.

    Any thought?

    Best regards,

    Olivier