0
votes

I am working on NFC (Mifare classic tag). I want to know how to write data to the mi fare classic tag. I have empty Tag. Please tell the APDU commands which I need to use for mifare classic tag.

I am sending APDU commands as follows :

\x00','\xA4', '\x04', '\x00','\x07','\xd2','\x76','\x00','\x00','\x85','\x01','\x00

If I am using this apdu command s its not giving any success response (as every APDU commands will have 9000) its going into the else part. Please tell me the correct apdu commands. I am writing code into the C language. The reader I have is MFC 523. What are steps need to follow?

// code i am using its for the Mobile POS 

   int ret;
   sendtoUSB("going to the auth",17); // for display purpose 
   // for authentication we will use the basic  authentication between the reader and writer 
      Sys_ClearScreen();
      char cRecvBuf[128];
      int  i,j;      
      char cSendBuf[10]= {0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x05,0x60,0x01};     // authenticaton key 
      char msg[128];
      u32  rlen; // response length 
      Sys_PcdOpen();
      while(1)
      {
          sendtoUSB("in while",8);
          if(Sys_Kbhit()==KEY_CANCEL)
             break;

          ret = Sys_PiccPresent();

          // activation of the NFC
          ret = Sys_PiccActivate();


          uchar key[16]= {0xFF,0x82,0x20,0x01,0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF} ; //Load keys command 

          char cSendBuf[10]= {0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x05,0x60,0x01};   // authentication command 

          ret = Sys_PiccCommand(key,11,&rlen,cRecvBuf); // sending the command 
          sendtoUSB("In send cmd",11);

          sendtoUSB(key,strlen(key)); // here i am getting the key as i am sending 


          sendtoUSB(cRecvBuf,rlen);  // in recvbuf i am agetting as 6E00



          if(ret==0) // checking the returing value 
          {
              // its coming into the if also 
              sendtoUSB("sucess",6);
              if(rlen>=0)
              {
                 if((cRecvBuf[rlen-2]==0x90) && (cRecvBuf[rlen-1]==0x00)) // checking the 90 00 response 

                 {
                      // not coming here
                      sendtoUSB("in if",5); 
                    strcpy(msg, "ankita"); 
                    for(i=0;i<rlen-2;i++)
                      sprintf(msg+strlen(msg), "%02X", cRecvBuf[i]);

                    Sys_DisplayLine( 2, msg, 0, ALIGN_LEFT) ;

                 }
                 else
                 {
                     // its coming here 

                    sendtoUSB("In else",7);



                    sprintf(msg, "In else 02X%02X", cRecvBuf[rlen-2],cRecvBuf[rlen-1]);


                    Sys_DisplayLine( 2, msg, 1, ALIGN_CENTER) ;
                    sendtoUSB ("fail data",9);
                    sendtoUSB(cRecvBuf,rlen);
                    sendtoUSB(msg,strlen(msg));

                }
            }

        }
        Sys_PiccDeselect(RM_WAIT);
        break;
    }
    Sys_PcdClose();
    Sys_WaitReturn();

    Sys_Buzzer(KB_BEEP_DURATION);



}


// i am following the same steps for the authentication also


//open NFC
// check NFC is there or not 
//activate 
// send command 
2
What status word return from this command.Jitendra
@vikky thanku you so much vikky u give me reply...angel
@vikky i am getting the response as 6E00 class error i am gettingangel
@vikky please tell me what the mistake i am doing. i given authentication keys alsoangel
From where you get this command.Jitendra

2 Answers

1
votes

I think, there is problem in "Load Key command". Here I am posting the Load key command structure.

enter image description here

0
votes

Are you sending authentication ADPU command in this format? If not, then try the following. It is working for me in MIFARE Classic tags authentication.

GENERAL AUTHENTICATE command APDU

    CLA     INS     P1      P2      Lc      DATAin          Le
    0xFF    h86     00      00      05      seebelow        -
    (def.)  (for 
            authent-
            ication 
            cmmd)

            GENERAL AUTHENTICATE Data In bytes

    Byte 0          Byte 1          Byte2           Byte3           Byte4
    h01             h00             Block            key            key     
                                    number          location        index
                                                    or Key 
                                                    type 

The block number (BYTE 2) is the address on the card, where we try to be authenticated (block no.)

The key location or Key type (BYTE 3) must be either:

  • h60 for authentication using a CRYPTO1 “A” key (standard PC/SC-defined value),
  • h61 for authentication using a CRYPTO1 “B” key (standard PC/SC-defined value),

Same value as the P1 parameter used in the LOAD KEY instruction: h00 or h20 (SpringCard specific value).

The key index (byte 4) is defined as follow:

  • If key type (byte 3) is h60, use values h00 to h03 to select one of the “A” keys stored in reader's volatile memory, and values h20 to h2F to select one of the “A” keys stored in reader's non-volatile memory (if available).

  • If key type (byte 3) is h61, use values h00 to h03 to select one of the “B” keys stored in reader's volatile memory, and values h20 to h2F to select one of the “B” keys stored in reader's non-volatile memory (if available).


int PCSC_Mifare_Read (unsigned char *data, unsigned int read_size, unsigned char block_num)
{
  unsigned char TxBuffer[5]= {0xFF, 0xB0};
  unsigned char RxBuffer[42]= {0};
  int Response = -1;
  int SendLength = 0;
  unsigned long RecvLength = 0;

  if (data == NULL)
  {
        Debug(__func__,"Invalid Param");
    return Response;
  }

  if (0xFF > block_num)
  {
    TxBuffer[2] = 0x00;
    TxBuffer[3] = block_num;
  }
  else
  {
    /* If the block number is greater than 0xFF then store the block number's MSB in P1 field
       and LSB in P2 field of APDU*/
    TxBuffer[2] = (block_num % 0xFF);
    TxBuffer[3] = 0xFF;
  }

  TxBuffer[4] = read_size; //or 0x00 or 0x20 if card supports 32 BYTE data read

  SendLength = sizeof (TxBuffer);
  RecvLength = sizeof (RxBuffer);

  Response = SCardTransmit(hCard, pioSendPci, TxBuffer, SendLength,
                           &pioRecvPci, RxBuffer, &RecvLength);
  if (Response != SCARD_S_SUCCESS)
  {
    Debug (__func__,"SCardTransmit Failed: %s 0x%x",pcsc_stringify_error(Response), Response);
    return Response;
  }

  if ((RxBuffer[RecvLength-2] == 0x90) && (RxBuffer[RecvLength-1] == 0x00))
  {
    Debug (__func__,"Succeeded : %02x %02x",RxBuffer[RecvLength-2], RxBuffer[RecvLength-1]);

    if (RecvLength > 0x02)
    {
        memcpy (data, RxBuffer, (RecvLength-2));
                Debug(__func__,"Read passed");
    }
    else
    {
                Debug(__func__,"Read Failed");
                return -1;
    }
  }
  else
  {
     Debug(__func__,"Failed : %02x %02x",RxBuffer[RecvLength-2], RxBuffer[RecvLength-1]);
     return -1;
  }

  return Response;
}


int PCSC_Mifare_Write (unsigned char block_num, unsigned char *data,unsigned int size)
{
  unsigned char TxBuffer[21] = {0xFF, 0xD6};
  unsigned char RxBuffer[2] = {0};
  int Response = -1;
  int SendLength = 0;
  unsigned long RecvLength = 0;

  if (0xFF > block_num)
  {
    TxBuffer[2] = 0x00;
    TxBuffer[3] = block_num;
  }
  else
  {
    /* If the block number is greater than 0xFF then store the block number's MSB in P1 field
       and LSB in P2 field of APDU*/
    TxBuffer[2] = (block_num % 0xFF);
    TxBuffer[3] = 0xFF;
  }

  TxBuffer[4] = size; //This is the block size to be written

  //copy the 0x08 BYTE data to be writen to the card
  memcpy ((TxBuffer + 5), data, size);

  SendLength = 5+size;//sizeof (TxBuffer);
  RecvLength = sizeof (RxBuffer);

//  HexDump("PCSC_Mifare_Write", TxBuffer, SendLength);

  Response = SCardTransmit(hCard, pioSendPci, TxBuffer, SendLength,
                           &pioRecvPci, RxBuffer, &RecvLength);
  if (Response != SCARD_S_SUCCESS)
  {
    Debug (__func__,"SCardTransmit Failed: %s 0x%x",pcsc_stringify_error(Response), Response);
    return Response;
  }

  if ((RxBuffer[0] == 0x90) && (RxBuffer[1] == 0x00))
  {
    Debug (__func__,"Succeeded : %02x %02x",RxBuffer[0],RxBuffer[1]);
  }
  else
  {
    Debug (__func__,"Failed : %02x %02x",RxBuffer[0],RxBuffer[1]);
    return -1;
  }

  return Response;
}