cancel
Showing results for 
Search instead for 
Did you mean: 

NFC0541 read Mifare Classic 1K

Olivier Bontron
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions
Olivier Bontron
Associate III

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

View solution in original post

31 REPLIES 31
Olivier Bontron
Associate III

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
ST Employee

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 III

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
ST Employee

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 III

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
ST Employee

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 III

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
ST Employee

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 III

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