This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] DLP-7970ABP:读取并更新HID iCLASS的内容

Guru**** 633105 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/other-wireless-group/other-wireless/f/other-wireless-technologies-forum/1096700/dlp-7970abp-read-and-update-contents-of-hid-iclass

部件号:DLP-7970ABP

您好,

我按照“PicolPass 32K(S) Card Operations with the TRF79xxA”的指南,得到了picopass的示例代码。c,我可以得到卡的UID,这意味着命令“ACTALL”和函数“CALCULATE CRC”是正确的。 稍后,我尝试使用"读取"命令读取内容。 我还可以获得块0的数据是UID。 我继续阅读下一个数据块,我获得以下数据:

选择命令Received bytes:0A
iCLASS UID:[D802E000F7FF12E0]

块00数据:[ D802E000F7FF12E026B8]
读取命令接收到字节:0A
块01数据:[12FFFFFFE97FFF3C9427]
读取命令接收到字节:0A
Block 02数据:[ FEFFFFFF557]
读取命令接收到字节:0A


当我尝试更新某些块时,我发现函数PicoloPass_update不完整。 所以我实施了这个功能。 但它不起作用。 我将在下面附上我的代码,以找出一些错误,或者我的iCLASS卡无法通过样本进行更新。

非常感谢您的回复。

              图形1:iCLASS wrte和read。                       图形2:iCLASS 其他块数据。

测试卡:

HID iCLASS测试卡
部件号2004PGGNN
格式:H1.0301万
F/C = 99
ID =1002

typedef联合

  UINT16_t值;
   结构
   
      UINT8_t低字节;
      UINT8_t高字节;
   };
} crc16_t;

#define CRC_POLYNOME 0x8408
#define CRC_PRESET_VALUE 0xE012
#define crc_check_value 0x0000

外部uint8_t g_TRF_buffer [NFC_FIFO大小];
静态易失性TRF_STATUS_t m_TRF_STATUS;

/**
*此函数计算uint8_t数组上的crc16
*以LSB为第一。
*
*@param Datag_TRF_buffer指向要计算crc16的数据的指针。
*@param SizeOfDatag_TRF_buffer数据的长度g_TRF_bufferfer (Datag_TRF_buffer)
*发生器polynom的@param polynom值。
*建议使用0x8408。
*@param initial_value crc16的初始值。
*建议为使用0xFFFF
*主机到读取器的通信。
*@返回计算的crc16
*/
uINT16_t GetCrc (uint8_t *pDatag_TRF_buffer,uint8_t g_TRF_bufferLen,uint16_t polynom,uint16_t initialValue)

  uINT16_t crc16 =初始值;
   UINT8_t字节计数器,位计数器;

   对于(byteCounter =0;byteCounter < g_TRF_bufferLen;byteCounter++)
   
      crc16 ^= pDatag_TRF_buffer[byteCounter];
      对于(bitCounter =0;bitCounter < 8;bitCounter++)
      
         如果((crc16和0x0001)== 0)
         
            crc16 >>=1;
         }
         否则
         
            crc16 =(crc16 >> 1)^ polynom;
         }
      }
   }
   RETURN (crc16);
}

//addr是要更新的块,p_block_data是要发送的数据,block_size是发送数据的大小,p_out数据存储更新的答复
uINT8_t iCLASS cmd_update (uint8_t addr,uint8_t* p_block_data,uint8_t block_size,uint8_t* p_out数据)

   //shell命令

   uINT8_t bTxbuffer [17];
   crc16_t crc16;
   UINT8_t ui8Offset = 0;
   uINT8_t输出数据长度;
   GUAP_DELAY (2);//延迟
   out数据长度= 0;

   bTxbuffer[ui8Offset++]= 0x8F;//重置FIFO
   bTxbuffer[ui8Offset++]= 0x90;//发送时不使用CRC
   bTxbuffer[ui8Offset+]= 0x3D;//从一维连续写入
   bTxbuffer[ui8Offset++]= 0x00;//传输字节长度的上半字节和中半字节
   bTxbuffer[ui8Offset++]= 0xC0;//传输字节长度的较小半字节和中断半字节

   bTxbuffer[ui8Offset+]= 0x27;//更新
   bTxbuffer[ui8Offset+]=地址;//块#addr.
   memcpy (&bTxbuffer[ui8Offset],p_block_data,block_size);//要写入标记的数据
   ui8Offset += block_size;

   crc16.value = GetCrc (&bTxbuffer[6],9,crc_POLYNOME,crc_preset_value);
   bTxbuffer[ui8Offset+]= crc16.lowByte;
   bTxbuffer[ui8Offset+]= crc16.highByte;

   TRF79xxA_writeRaw(bTxbuffer,ui8Offset);//发出read命令

   M_TRF_STATUS = TRF79xxA_waitRxData (30,20);// 30毫秒TX超时,20毫秒RX超时

   IF (m_TRF_STATUS == RX_COMPLETE)
   {//如果接收到g_TRF_Bbufferfer中的块数据
      UINT8_t g_TRF_BUFFER_Len = TRF79xxA_getRxBytesReceived();

      如果(0!= g_TRF_BUFFER_LEN && NULL!= p_out数据)
      
      out数据长度= g_TRF_BUFFER_len;
      memcpy (p_out数据,g_TRF_buffer,g_TRF_buffer_len);
      //响应将是写入块的内容(8字节)
      }
   }
   否则
   
      //清除所有IRQ
      TRF79xxA_resetIrqStatus();
   }
   返回out数据长度;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好Ken:

    目前我正在参加一项培训,将无法处理此帖子。 我明天会看,但由于我要追上其他职位,可能要1,2天才可以作出答复。 请耐心等待。

    此致,

    Andreas。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好Ken:

    命令顺序似乎很重要。 必须先执行ACS,然后需要选择,然后才能发送更新命令。 Update命令本身的实现看起来是合理的。

    此致,

    Andreas。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。


    您好,Andreas:

    我确实遵循ACS顺序以便获取UID。 此卡仅在命令正确时才会回复。
    是否有任何更新函数的原始数据(如附加图片)? 我在发送更新命令后无法获得任何响应。 谢谢。

    此致,

               测试示例
    肯尼亚

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Ken:

    在这里

    此致,

    Andreas。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Andreas:

    如果您在第一篇文章中回顾"Graph1:iCLASS wirte and Read"(图形1:iCLASS wirte和读取),我无法收到任何有关更新命令和CRC代码的信息。
    因为该示例不包括块数据 和CRC代码。
    我不知道为什么没有使用update命令的响应。 因此,如果我不在乎,就必须写入块数据。 仅使用强力测试CRC代码。 也许我可以得到一些回应。 我在读取命令时先尝试了此操作。 它的作用是显示CRC代码就像一个示例。 但是在暴力结束后,我仍然无法从更新命令获得任何响应。

    此致,
    肯尼亚

    暴力读取 成功 视频 (1分钟): https://youtu.be/Ik_GPUVMfNI

                5.13 强力 写入 失败。

                                  函数iCLASS _cmd_test c代码

    #define DEBUG_ICLASS_WRITE
    //#define DEBUG_ICLASS_READ
    
    
    void iclass_cmd_test()
    {
    #if defined DEBUG_ICLASS_WRITE
        //update test txbuffer
        uint8_t bTxbuffer[12] = {0x27, 0x03, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00};
        uint8_t m_bRxbuffer[8] = {0};
    #elif defined DEBUG_ICLASS_READ
        //read test txbuffer
        uint8_t bTxbuffer[4] = {0xAC, 0x00, 0x00, 0x00};
        uint8_t m_bRxbuffer[10] = {0};
    
    #endif
    
        uint8_t m_bForFlag = 0;
        uint8_t receive_length = 0;
        uint16_t i, j;
    
    //  read crc is 73 33, 73 = 115 , start from 115 and 0
        for(i = 0; i < 256; i++)
        {
            for(j = 0; j < 256; j++)
            {
    #if defined DEBUG_ICLASS_WRITE
                //update test txbuffer
                bTxbuffer[10] = (uint8_t)i;
                bTxbuffer[11] = (uint8_t)j;
    #elif defined DEBUG_ICLASS_READ
                //read test txbuffer
                bTxbuffer[2] = (uint8_t)i;  //change crc
                bTxbuffer[3] = (uint8_t)j;  //change crc
    #endif
    
    #if defined DEBUG_ICLASS_WRITE
                //update test txbuffer
                if (TRF79xxA_SendCmd(TRF79XXA_TRANSMIT_NO_CRC_CMD, bTxbuffer, 96, 30)) // 96 = 12 * 8 bits
    #elif defined DEBUG_ICLASS_READ
                //read test txbuffer
                if (TRF79xxA_SendCmd(TRF79XXA_TRANSMIT_NO_CRC_CMD, bTxbuffer, 32, 30)) // 32 = 4 * 8 bits
    #endif
                {
                    NDEF_PRINT_BYTE(i);
                    NDEF_PRINT_STRING("\n");
    
    #if defined DEBUG_ICLASS_WRITE
                //update test txbuffer
                    receive_length = TRF79xxA_ReceiveData(m_bRxbuffer, 8, 20);  // FF is timeout, 0x08 is good, only data 8
    #elif defined DEBUG_ICLASS_READ
                //read test txbuffer
                    receive_length = TRF79xxA_ReceiveData(m_bRxbuffer, 10, 20); // FF is timeout, 0x0A is good, data 8 + crc 2 = 10(A)
    #endif
                    if( 0 < receive_length && 0xFF != receive_length)
                    {
                        NDEF_PRINT_STRING("j: ");
                        NDEF_PRINT_BYTE(j);
                        NDEF_PRINT_STRING("\n");
                        DBG_PRINT_BYTE("receive_length:", receive_length);
                        NDEF_PRINT_STRING("find");
                        NDEF_PRINT_STRING("\n");
                        m_bForFlag = 1;
                        break;
                    }
                }
                Delay_Ms(2);  //delay
            }
            if(1 == m_bForFlag)
            {
                break;
            }
        }
        NDEF_PRINT_STRING("end\n");
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。


    您好,Andreas:

    我研究过这两份参考文件后,发觉没有密钥便不可能写一份资料。
    您的iCLASS步骤是正确的,但没有提到如何在相互验证中生成询问值。
    因为生成询问值需要密钥。 和写入命令必须在验证后发送。
    我认为这个问题已经结束了。再次感谢你的答复。

    此致,
    肯尼亚

    参考:

    1.拆卸iCLASS和iCLASS Elite
      www.cs.bham.ac.uk/.../dismantling.iClass.pdf
    2.公开iCLASS密钥多样化
      www.usenix.org/.../Garcia.pdf