From 52d69ed4eefa2df7e7c45ef39c22ee26093ec743 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Feb 2018 15:19:47 +0100 Subject: [PATCH] CHG: refactor CRC16 algos. This is a big change, most likely some parts broke, hard to test it all. --- armsrc/Makefile | 5 +- armsrc/Standalone/hf_colin.c | 2 +- armsrc/apps.h | 4 +- armsrc/desfire_crypto.c | 7 +- armsrc/iclass.c | 178 ++++++++++++-------------- armsrc/iso14443a.c | 70 ++++++----- armsrc/iso14443a.h | 11 +- armsrc/iso14443b.c | 80 +++++------- armsrc/iso14443b.h | 11 +- armsrc/iso15693.c | 15 ++- armsrc/mifarecmd.c | 4 +- armsrc/mifaredesfire.c | 6 +- armsrc/mifareutil.c | 16 +-- client/Makefile | 2 - client/cmdanalyse.c | 237 ++++++++++++++--------------------- client/cmdanalyse.h | 4 +- client/cmdhf.c | 71 +++-------- client/cmdhf14a.c | 4 +- client/cmdhf14b.c | 4 +- client/cmdhf14b.h | 2 +- client/cmdhf15.c | 56 +++++---- client/cmdhf15.h | 2 +- client/cmdhffelica.c | 52 +++----- client/cmdhftopaz.c | 117 +++++------------ client/cmdhftopaz.h | 14 +++ client/mifarehost.h | 2 +- client/scripting.c | 12 +- client/scripting.h | 2 - client/util.c | 8 ++ common/crc16.c | 103 +++++++++------ common/crc16.h | 37 +++--- common/iso14443crc.c | 3 +- common/iso14443crc.h | 7 -- common/iso15693tools.c | 27 +--- common/iso15693tools.h | 11 +- 35 files changed, 512 insertions(+), 674 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index de607faf8..b2de878c8 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -44,13 +44,12 @@ APP_CFLAGS = -DWITH_CRC \ SRC_LCD = fonts.c LCD.c SRC_LF = lfops.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c SRC_ISO15693 = iso15693.c iso15693tools.c -#SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c epa.c mifaresim.c -#SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresniff.c +#SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c SRC_ISO14443b = iso14443b.c SRC_FELICA = felica.c SRC_CRAPTO1 = crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c -SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c +SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipher.c SRC_LEGIC = legicrf.c legic_prng.c SRC_FLASH = flash.c diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index d58881c1b..098ef8f44 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -737,7 +737,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data }; memcpy(d_block, datain, 16); - AppendCrc14443a(d_block, 16); + AddCrc14A(d_block, 16); ReaderTransmit(d_block, sizeof(d_block), NULL); if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) { // if (MF_DBGLEVEL >= 1) diff --git a/armsrc/apps.h b/armsrc/apps.h index 48263dfd5..6d60a8cc3 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -113,7 +113,6 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks); void RAMFUNC SniffIso14443b(void); void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]); void SendRawCommand14443B_Ex(UsbCommand *c); -void AppendCrc14443b(uint8_t* data, int len); void ClearFpgaShiftingRegisters(void); // iso14443a.h @@ -205,12 +204,11 @@ void RAMFUNC SniffIClass(void); void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void ReaderIClass(uint8_t arg0); void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC); -void IClass_iso14443A_GetPublic(uint8_t arg0); void iClass_Authentication(uint8_t *MAC); void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain); void iClass_WriteBlock(uint8_t blockNo, uint8_t *data); void iClass_ReadBlk(uint8_t blockNo); -bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata); +bool iClass_ReadBlock(uint8_t blockNo, uint8_t *data, uint8_t datalen); void iClass_Dump(uint8_t blockno, uint8_t numblks); void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data); void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType); diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index fdb067711..f9c6dd2ed 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -258,7 +258,7 @@ void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes // ... CRC ... switch (DESFIRE (tag)->authentication_scheme) { case AS_LEGACY: - AppendCrc14443a(res + offset, *nbytes - offset); + AddCrc14A(res + offset, *nbytes - offset); *nbytes += 2; break; case AS_NEW: @@ -445,9 +445,8 @@ void* mifare_cryto_postprocess_data (desfiretag_t tag, void *data, size_t *nbyte uint32_t crc; switch (DESFIRE (tag)->authentication_scheme) { case AS_LEGACY: - end_crc_pos = crc_pos + 2; - AppendCrc14443a (res, end_crc_pos); - + AddCrc14A(res, end_crc_pos); + end_crc_pos = crc_pos + 2; // diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 12aa4bb19..c8eb791b9 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -41,8 +41,6 @@ // Needed for CRC in emulation mode; // same construction as in ISO 14443; // different initial value (CRC_ICLASS) -#include "iso14443crc.h" -#include "iso15693tools.h" #include "crc16.h" #include "protocols.h" #include "optimized_cipher.h" @@ -66,6 +64,8 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf); #define ICLASS_BUFFER_SIZE 32 #endif +#define AddCrc(data, len) compute_crc(CRC_ICLASS, (data), (len), (data)+(len), (data)+(len)+1) + //----------------------------------------------------------------------------- // The software UART that receives commands from the reader, and its state // variables. @@ -981,8 +981,9 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) // only, since we are receiving, not transmitting). // Signal field is off with the appropriate LED LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); uart_init(received); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -1222,9 +1223,6 @@ out: switch_off(); BigBuf_free_keep_EM(); } -void AppendCrc(uint8_t* data, int len) { - ComputeCrc14443(CRC_ICLASS, data, len, data+len, data+len+1); -} /** * @brief Does the actual simulation @@ -1252,9 +1250,9 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { rotateCSN(csn_data, anticoll_data); // Compute CRC on both CSNs - ComputeCrc14443(CRC_ICLASS, anticoll_data, 8, &anticoll_data[8], &anticoll_data[9]); - ComputeCrc14443(CRC_ICLASS, csn_data, 8, &csn_data[8], &csn_data[9]); - + AddCrc(anticoll_data, 8); + AddCrc(csn_data, 8); + uint8_t diversified_key[8] = { 0 }; // e-Purse uint8_t card_challenge_data[8] = { 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; @@ -1300,7 +1298,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { uint8_t *resp_conf = BigBuf_malloc(28); int resp_conf_len; uint8_t conf_data[10] = {0x12,0xFF,0xFF,0xFF,0x7F,0x1F,0xFF,0x3C,0x00,0x00}; - ComputeCrc14443(CRC_ICLASS, conf_data, 8, &conf_data[8], &conf_data[9]); + AddCrc(conf_data, 8); // e-Purse // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit) @@ -1311,7 +1309,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { uint8_t *resp_aia = BigBuf_malloc(28); int resp_aia_len; uint8_t aia_data[10] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00}; - ComputeCrc14443(CRC_ICLASS, aia_data, 8, &aia_data[8], &aia_data[9]); + AddCrc(aia_data, 8); // receive command uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); @@ -1387,7 +1385,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { LED_A_ON(); bool buttonPressed = false; - uint16_t response_delay = 1; + while (!exitLoop) { WDT_HIT(); @@ -1403,7 +1401,6 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { r2t_etime = ((GetCountSspClk() - time_0) << 4 ) - r2t_stime; // 330us normal wait, adjusted for our execution - response_delay = 230; LED_C_ON(); //Signal tracer @@ -1413,28 +1410,57 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { trace_data = sof_data; trace_data_size = sizeof(sof_data); // adjusted for 330 + (160*num of slot) - response_delay = 330 + 160 * 1; - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 1) { // 0x0C - // Reader asks for anticollission CSN - modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2; - trace_data = anticoll_data; - trace_data_size = sizeof(anticoll_data); goto send; + } else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C + if (len == 1) { + // Reader asks for anticollission CSN + modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2; + trace_data = anticoll_data; + trace_data_size = sizeof(anticoll_data); + goto send; + } + if (len == 4){ + // block0,1,2,5 is always readable. + switch (receivedCmd[1]){ + case 0: // csn (0c 00) + modulated_response = resp_csn; modulated_response_size = resp_csn_len; + trace_data = csn_data; + trace_data_size = sizeof(csn_data); + break; + case 1: // configuration (0c 01) + modulated_response = resp_conf; modulated_response_size = resp_conf_len; + trace_data = conf_data; + trace_data_size = sizeof(conf_data); + break; + case 2: // e-purse (0c 02) + modulated_response = resp_cc; modulated_response_size = resp_cc_len; + trace_data = card_challenge_data; + trace_data_size = sizeof(card_challenge_data); + break; + case 5:// Application Issuer Area (0c 05) + modulated_response = resp_aia; modulated_response_size = resp_aia_len; + trace_data = aia_data; + trace_data_size = sizeof(aia_data); + break; + default: break; + } + goto send; + } + } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 // Reader selects anticollission CSN. // Tag sends the corresponding real CSN modulated_response = resp_csn; modulated_response_size = resp_csn_len; //order = 3; trace_data = csn_data; trace_data_size = sizeof(csn_data); - goto send; + goto send; } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88 // Read e-purse (88 02) modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; trace_data = card_challenge_data; trace_data_size = sizeof(card_challenge_data); LED_B_ON(); - goto send; + goto send; } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18 // Read e-purse (18 02) modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; @@ -1454,8 +1480,6 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { memcpy(data_response, ToSend, ToSendMax); modulated_response = data_response; modulated_response_size = ToSendMax; - response_delay = 0;//We need to hurry here... - //exitLoop = true; } else { // Not fullsim, we don't respond // We do not know what to answer, so lets keep quiet @@ -1484,41 +1508,12 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { trace_data = NULL; trace_data_size = 0; goto send; - // sim 2 / 4, - } else if (simulationMode == MODE_EXIT_AFTER_MAC && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){ // 0x0C - // block0,1,2,5 is always readable. - uint16_t blk = receivedCmd[1]; - switch (blk){ - case 0: // csn (0c 00) - modulated_response = resp_csn; modulated_response_size = resp_csn_len; - trace_data = csn_data; - trace_data_size = sizeof(csn_data); - break; - case 1: // configuration (0c 01) - modulated_response = resp_conf; modulated_response_size = resp_conf_len; - trace_data = conf_data; - trace_data_size = sizeof(conf_data); - break; - case 2: // e-purse (0c 02) - modulated_response = resp_cc; modulated_response_size = resp_cc_len; - trace_data = card_challenge_data; - trace_data_size = sizeof(card_challenge_data); - break; - case 5:// Application Issuer Area (0c 05) - modulated_response = resp_aia; modulated_response_size = resp_aia_len; - trace_data = aia_data; - trace_data_size = sizeof(aia_data); - break; - default: break; - } - goto send; } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){ // 0x0C //Read block uint16_t blk = receivedCmd[1]; //Take the data... memcpy(data_generic_trace, emulator+(blk << 3),8); - //Add crc - AppendCrc(data_generic_trace, 8); + AddCrc(data_generic_trace, 8); trace_data = data_generic_trace; trace_data_size = 10; CodeIClassTagAnswer(trace_data , trace_data_size); @@ -1535,8 +1530,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { //Take the data... memcpy(data_generic_trace, receivedCmd+2, 8); - //Add crc - AppendCrc(data_generic_trace, 8); + AddCrc(data_generic_trace, 8); trace_data = data_generic_trace; trace_data_size = 10; CodeIClassTagAnswer(trace_data, trace_data_size); @@ -1544,7 +1538,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { memcpy(data_response, ToSend, ToSendMax); modulated_response = data_response; modulated_response_size = ToSendMax; - response_delay = 4600 * 1.5; // tPROG 4-15ms +// response_delay = 4600 * 1.5; // tPROG 4-15ms goto send; // } else if(receivedCmd[0] == ICLASS_CMD_PAGESEL) { // 0x84 //Pagesel @@ -1565,14 +1559,14 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { trace_data = NULL; trace_data_size = 0; } - + send: /** A legit tag has about 330us delay between reader EOT and tag SOF. **/ if (modulated_response_size > 0) { t2r_stime = (GetCountSspClk() - time_0) << 4; - SendIClassAnswer(modulated_response, modulated_response_size, response_delay); + SendIClassAnswer(modulated_response, modulated_response_size, 0); t2r_etime = ((GetCountSspClk() - time_0) << 4 ) - t2r_stime; } @@ -1597,8 +1591,8 @@ send: * @param delay */ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { - int i = 0; // d = 0; - uint8_t b = 0; + int i = 0; + volatile uint8_t b = 0; FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K_8BIT); AT91C_BASE_SSC->SSC_THR = 0x00; @@ -1630,7 +1624,7 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) { int c = 0; - volatile uint32_t r; + volatile uint32_t b; bool firstpart = true; uint8_t sendbyte; @@ -1665,7 +1659,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int } if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - r = AT91C_BASE_SSC->SSC_RHR; (void)r; + b = AT91C_BASE_SSC->SSC_RHR; (void)b; } } @@ -1829,8 +1823,6 @@ void setupIclassReader() { // Signal field is on with the appropriate LED FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); SpinDelay(300); - - init_table(CRC_15_ICLASS); // Start the timer StartCountSspClk(); @@ -1843,6 +1835,8 @@ bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* re ReaderTransmitIClass(command, cmdsize); + //iceman - if received size is bigger than expected, we smash the stack here + // since its called with fixed sized arrays if (expected_size == ReaderReceiveIClass(resp)) return true; } @@ -2057,14 +2051,12 @@ void ReaderIClass(uint8_t arg0) { // turn off afterwards void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { - uint16_t crc = 0; uint8_t cardsize = 0; uint8_t mem = 0; uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 }; uint8_t card_data[USB_CMD_DATA_SIZE] = {0}; uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; - uint8_t tmp[] = {1}; static struct memory_t{ int k16; @@ -2092,10 +2084,8 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { } //first get configuration block (block 1) - crc = crc16_iclass( tmp , 1); read[1] = 1; - read[2] = crc >> 8; - read[3] = crc & 0xff; + AddCrc( read+1, 1 ); if (!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 5)) { DbpString("Dump config (block 1) failed"); @@ -2121,11 +2111,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { for ( uint16_t block=0; block < cardsize; block++) { read[1] = block; - //crc = block_crc_LUT[block]; - tmp[0] = block & 0xFF; - crc = crc16_iclass( tmp , 1); - read[2] = crc >> 8; - read[3] = crc & 0xff; + AddCrc( read+1, 1 ); if (sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 5)) { Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x", @@ -2296,30 +2282,29 @@ out: LED_C_OFF(); } -bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata) { - uint8_t readcmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00}; //0x88, 0x00 // can i use 0C? - uint16_t crc = crc16_iclass(readcmd+1, 1); - readcmd[2] = crc >> 8; - readcmd[3] = crc & 0xff; - uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; - - bool isOK = sendCmdGetResponseWithRetries(readcmd, sizeof(readcmd), resp, 10, 5); - memcpy(readdata, resp, sizeof(resp)); +// Tries to read block. +// retries 5times. +bool iClass_ReadBlock(uint8_t blockNo, uint8_t *data, uint8_t len) { + //uint8_t resp[] = BigBuf_malloc(len); + uint8_t resp[20]; + uint8_t cmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00}; //0x88, 0x00 // can i use 0C? + AddCrc( cmd+1, 1 ); + bool isOK = sendCmdGetResponseWithRetries(cmd, sizeof(cmd), resp, len, 5); + memcpy(data, resp, len); return isOK; } // turn off afterwards void iClass_ReadBlk(uint8_t blockno) { - uint8_t readblockdata[] = {0,0,0,0,0,0,0,0,0,0}; - bool isOK = false; - isOK = iClass_ReadBlock(blockno, readblockdata); - cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8); + uint8_t data[] = {0,0,0,0,0,0,0,0,0,0}; + bool isOK = iClass_ReadBlock(blockno, data, sizeof(data)); + cmd_send(CMD_ACK, isOK, 0, 0, data, 8); switch_off(); } // turn off afterwards void iClass_Dump(uint8_t blockno, uint8_t numblks) { - uint8_t readblockdata[] = {0,0,0,0,0,0,0,0,0,0}; + uint8_t blockdata[] = {0,0,0,0,0,0,0,0,0,0}; bool isOK = false; uint8_t blkCnt = 0; @@ -2334,17 +2319,17 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { memset(dataout, 0xFF, 255*8); for (;blkCnt < numblks; blkCnt++) { - isOK = iClass_ReadBlock(blockno + blkCnt, readblockdata); + isOK = iClass_ReadBlock(blockno + blkCnt, blockdata, sizeof(blockdata)); // 0xBB is the internal debug separator byte.. - if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0xBB || readblockdata[2] == 0xBB)) { //try again - isOK = iClass_ReadBlock(blockno + blkCnt, readblockdata); + if (!isOK || (blockdata[0] == 0xBB || blockdata[7] == 0xBB || blockdata[2] == 0xBB)) { //try again + isOK = iClass_ReadBlock(blockno + blkCnt, blockdata, sizeof(blockdata)); if (!isOK) { Dbprintf("Block %02X failed to read", blkCnt + blockno); break; } } - memcpy(dataout + (blkCnt * 8), readblockdata, 8); + memcpy(dataout + (blkCnt * 8), blockdata, 8); } //return pointer to dump memory in arg3 cmd_send(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0); @@ -2353,12 +2338,11 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { } bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) { + + uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(write+2, data, 12); // data + mac - uint16_t crc = crc16_iclass(write+1, 13); - write[14] = crc >> 8; - write[15] = crc & 0xff; - uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; + AddCrc(write+1, 13); bool isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); if (isOK) { //if reader responded correctly diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 4ee2c5055..0dda14de5 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -152,9 +152,6 @@ void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par) { par[paritybyte_cnt] = parityBits; } -void AppendCrc14443a(uint8_t* data, int len) { - ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); -} //============================================================================= // ISO 14443 Type A - Miller decoder @@ -887,7 +884,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { // PACK response8[0] = 0x80; response8[1] = 0x80; - ComputeCrc14443(CRC_14443_A, response8, 2, &response8[2], &response8[3]); + compute_crc(CRC_14443_A, response8, 2, &response8[2], &response8[3]); // uid not supplied then get from emulator memory if (data[0]==0) { uint16_t start = 4 * (0+12); @@ -944,12 +941,12 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { // Prepare the mandatory SAK (for 4 and 7 byte UID) uint8_t response3[3] = {sak, 0x00, 0x00}; - ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]); + compute_crc(CRC_14443_A, response3, 1, &response3[1], &response3[2]); // Prepare the optional second SAK (for 7 byte UID), drop the cascade bit uint8_t response3a[3] = {0x00}; response3a[0] = sak & 0xFB; - ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); + compute_crc(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); // Tag NONCE. uint8_t response5[4]; @@ -959,7 +956,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1 // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us) // TC(1) = 0x02: CID supported, NAD not supported - ComputeCrc14443(CRC_14443_A, response6, 4, &response6[4], &response6[5]); + compute_crc(CRC_14443_A, response6, 4, &response6[4], &response6[5]); // Prepare GET_VERSION (different for UL EV-1 / NTAG) // uint8_t response7_EV1[] = {0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x0b, 0x03, 0xfd, 0xf7}; //EV1 48bytes VERSION. @@ -1058,14 +1055,14 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { uint16_t start = 4 * (block+12); uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; emlGetMemBt( emdata, start, 16); - AppendCrc14443a(emdata, 16); + AddCrc14A(emdata, 16); EmSendCmd(emdata, sizeof(emdata)); // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below p_response = NULL; } else { // all other tags (16 byte block tags) uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; emlGetMemBt( emdata, block, 16); - AppendCrc14443a(emdata, 16); + AddCrc14A(emdata, 16); EmSendCmd(emdata, sizeof(emdata)); // EmSendCmd(data+(4*receivedCmd[1]),16); // Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]); @@ -1078,7 +1075,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { int start = (receivedCmd[1]+12) * 4; int len = (receivedCmd[2] - receivedCmd[1] + 1) * 4; emlGetMemBt( emdata, start, len); - AppendCrc14443a(emdata, len); + AddCrc14A(emdata, len); EmSendCmd(emdata, len+2); p_response = NULL; } else if (receivedCmd[0] == MIFARE_ULEV1_READSIG && tagType == 7) { // Received a READ SIGNATURE -- @@ -1086,7 +1083,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { uint16_t start = 4 * 4; uint8_t emdata[34]; emlGetMemBt( emdata, start, 32); - AppendCrc14443a(emdata, 32); + AddCrc14A(emdata, 32); EmSendCmd(emdata, sizeof(emdata)); p_response = NULL; } else if (receivedCmd[0] == MIFARE_ULEV1_READ_CNT && tagType == 7) { // Received a READ COUNTER -- @@ -1098,7 +1095,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { } else { uint8_t cmd[] = {0x00,0x00,0x00,0x14,0xa5}; num_to_bytes(counters[index], 3, cmd); - AppendCrc14443a(cmd, sizeof(cmd)-2); + AddCrc14A(cmd, sizeof(cmd)-2); EmSendCmd(cmd,sizeof(cmd)); } p_response = NULL; @@ -1135,7 +1132,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { EmSendCmd(nack,sizeof(nack)); } else { emlGetMemBt( emdata, 10+index, 1); - AppendCrc14443a(emdata, sizeof(emdata)-2); + AddCrc14A(emdata, sizeof(emdata)-2); EmSendCmd(emdata, sizeof(emdata)); } p_response = NULL; @@ -1146,7 +1143,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { if ( tagType == 7 ) { // IF NTAG /EV1 0x60 == GET_VERSION, not a authentication request. uint8_t emdata[10]; emlGetMemBt( emdata, 0, 8 ); - AppendCrc14443a(emdata, sizeof(emdata)-2); + AddCrc14A(emdata, sizeof(emdata)-2); EmSendCmd(emdata, sizeof(emdata)); p_response = NULL; } else { @@ -1242,7 +1239,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { uint16_t start = 13; // first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00] uint8_t emdata[4]; emlGetMemBt( emdata, start, 2); - AppendCrc14443a(emdata, 2); + AddCrc14A(emdata, 2); EmSendCmd(emdata, sizeof(emdata)); p_response = NULL; uint32_t pwd = bytes_to_num(receivedCmd+1,4); @@ -1308,7 +1305,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { dynamic_response_info.response[1] = receivedCmd[1]; // Add CRC bytes, always used in ISO 14443A-4 compliant cards - AppendCrc14443a(dynamic_response_info.response, dynamic_response_info.response_n); + AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n); dynamic_response_info.response_n += 2; if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) { @@ -1420,12 +1417,16 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing // clear TXRDY AT91C_BASE_SSC->SSC_THR = SEC_Y; + volatile uint8_t b; uint16_t c = 0; while (c < len) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = cmd[c]; - c++; + AT91C_BASE_SSC->SSC_THR = cmd[c++]; } + //iceman test + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; + } } NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); @@ -1586,7 +1587,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) { } int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) { - uint8_t b; + volatile uint8_t b; uint16_t i = 0; uint32_t ThisTransferTime; bool correctionNeeded; @@ -1631,7 +1632,10 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) { AT91C_BASE_SSC->SSC_THR = resp[i++]; FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; } - + + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; + } if(BUTTON_PRESS()) break; } @@ -1943,7 +1947,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_card, uint32_ sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC - AppendCrc14443a(sel_uid, 7); // calculate and add CRC + AddCrc14A(sel_uid, 7); // calculate and add CRC ReaderTransmit(sel_uid, sizeof(sel_uid), NULL); // Receive the SAK @@ -1980,7 +1984,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_card, uint32_ // RATS, Request for answer to select if ( !no_rats ) { - AppendCrc14443a(rats, 2); + AddCrc14A(rats, 2); ReaderTransmit(rats, sizeof(rats), NULL); len = ReaderReceive(resp, resp_par); @@ -2032,7 +2036,7 @@ int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) { //sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC - AppendCrc14443a(sel_uid, 7); // calculate and add CRC + AddCrc14A(sel_uid, 7); // calculate and add CRC ReaderTransmit(sel_uid, sizeof(sel_uid), NULL); // Receive the SAK @@ -2112,7 +2116,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) { // put block number into the PCB real_cmd[0] |= iso14_pcb_blocknum; memcpy(real_cmd + 1, cmd, cmd_len); - AppendCrc14443a(real_cmd, cmd_len + 1); + AddCrc14A(real_cmd, cmd_len + 1); ReaderTransmit(real_cmd, cmd_len + 3, NULL); @@ -2131,7 +2135,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) { // byte1 - WTXM [1..59]. command FWT=FWT*WTXM data_bytes[1] = data_bytes[1] & 0x3f; // 2 high bits mandatory set to 0b // now need to fix CRC. - AppendCrc14443a(data_bytes, len - 2); + AddCrc14A(data_bytes, len - 2); // transmit S-Block ReaderTransmit(data_bytes, len, NULL); // retrieve the result again (with increased timeout) @@ -2152,7 +2156,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) { } // crc check - if (len >=3 && !CheckCrc14443(CRC_14443_A, data_bytes, len)) { + if (len >=3 && !check_crc(CRC_14443_A, data_bytes, len)) { return -1; } @@ -2221,9 +2225,9 @@ void ReaderIso14443a(UsbCommand *c) { // Don't append crc on empty bytearray... if ( len > 0 ) { if ((param & ISO14A_TOPAZMODE)) - AppendCrc14443b(cmd, len); + AddCrc14B(cmd, len); else - AppendCrc14443a(cmd, len); + AddCrc14A(cmd, len); len += 2; if (lenbits) lenbits += 16; @@ -2344,7 +2348,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) { static uint8_t par_low = 0; static uint8_t mf_nr_ar3 = 0; - AppendCrc14443a(mf_auth, 2); + AddCrc14A(mf_auth, 2); if (first_try) { sync_time = GetCountSspClk() & 0xfffffff8; @@ -2921,9 +2925,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * break; } // calc some crcs - ComputeCrc14443(CRC_14443_A, sak_4, 1, &sak_4[1], &sak_4[2]); - ComputeCrc14443(CRC_14443_A, sak_7, 1, &sak_7[1], &sak_7[2]); - ComputeCrc14443(CRC_14443_A, sak_10, 1, &sak_10[1], &sak_10[2]); + compute_crc(CRC_14443_A, sak_4, 1, &sak_4[1], &sak_4[2]); + compute_crc(CRC_14443_A, sak_7, 1, &sak_7[1], &sak_7[2]); + compute_crc(CRC_14443_A, sak_10, 1, &sak_10[1], &sak_10[2]); // We need to listen to the high-frequency, peak-detected path. iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); @@ -3247,7 +3251,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * if (MF_DBGLEVEL >= 4) Dbprintf("Reader reading block %d (0x%02x)", receivedCmd[1], receivedCmd[1]); emlGetMem(response, receivedCmd[1], 1); - AppendCrc14443a(response, 16); + AddCrc14A(response, 16); mf_crypto1_encrypt(pcs, response, 18, response_par); EmSendCmdPar(response, 18, response_par); numReads++; diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 0a2a889a3..eea82c248 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -22,7 +22,7 @@ extern "C" { #include "apps.h" #include "util.h" #include "string.h" -#include "iso14443crc.h" +#include "crc16.h" #include "mifaresniff.h" #include "crapto1/crapto1.h" #include "mifareutil.h" @@ -85,8 +85,15 @@ typedef struct { uint8_t *parity; } tUart; +#ifndef AddCrc14A +# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) +#endif + +#ifndef AddCrc14B +# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) +#endif + extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); -extern void AppendCrc14443a(uint8_t *data, int len); extern tDemod* GetDemod(void); extern void DemodReset(void); diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index c6e74b014..e679323eb 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -169,10 +169,6 @@ static void iso14b_set_maxframesize(uint16_t size) { if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax); } -void AppendCrc14443b(uint8_t* data, int len) { - ComputeCrc14443(CRC_14443_B, data, len, data+len, data+len+1); -} - //----------------------------------------------------------------------------- // Code up a string of octets at layer 2 (including CRC, we don't generate // that here) so that they can be transmitted to the reader. Doesn't transmit @@ -457,7 +453,11 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) { AT91C_BASE_SSC->SSC_THR = 0xFF; ++c; } - } + + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; + } + } */ // Now run a `software UART' on the stream of incoming samples. @@ -588,9 +588,8 @@ void SimulateIso14443bTag(uint32_t pupi) { // ...PUPI/UID supplied from user. Adjust ATQB response accordingly if ( pupi > 0 ) { - uint8_t len = sizeof(respATQB); num_to_bytes(pupi, 4, respATQB+1); - ComputeCrc14443(CRC_14443_B, respATQB, 12, &respATQB[len-2], &respATQB[len-1]); + AddCrc14B(respATQB, 12); } // prepare "ATQB" tag answer (encoded): @@ -685,10 +684,9 @@ void SimulateIso14443bTag(uint32_t pupi) { Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsReceived); // CRC Check - uint8_t b1, b2; if (len >= 3){ // if crc exists - ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2); - if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) + + if (!check_crc(CRC_14443_B, receivedCmd, len)) DbpString("+++CRC fail"); else DbpString("CRC passes"); @@ -1042,10 +1040,10 @@ static void TransmitFor14443b_AsReader(void) { // Send frame loop for(c = 0; c < ToSendMax;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = ToSend[c++]; } - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = AT91C_BASE_SSC->SSC_RHR; (void)b; } } @@ -1156,7 +1154,7 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) { * TODO: check CRC and preamble */ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response) { - uint8_t crc[2] = {0x00, 0x00}; + uint8_t message_frame[message_length + 4]; // PCB message_frame[0] = 0x0A | pcb_blocknum; @@ -1166,7 +1164,7 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r // INF memcpy(message_frame + 2, message, message_length); // EDC (CRC) - ComputeCrc14443(CRC_14443_B, message_frame, message_length + 2, &message_frame[message_length + 2], &message_frame[message_length + 3]); + AddCrc14B(message_frame, message_length + 2); // send CodeAndTransmit14443bAsReader(message_frame, message_length + 4); //no // get response @@ -1175,8 +1173,7 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r return 0; // VALIDATE CRC - ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]); - if ( crc[0] != Demod.output[Demod.len-2] || crc[1] != Demod.output[Demod.len-1] ) + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) return 0; // copy response contents @@ -1194,8 +1191,6 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) { static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b }; // SELECT command (with space for CRC) uint8_t select_srx[] = { ISO14443B_SELECT, 0x00, 0x00, 0x00}; - // temp to calc crc. - uint8_t crc[2] = {0x00, 0x00}; CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx)); GetTagSamplesFor14443bDemod(); //no @@ -1207,15 +1202,15 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) { select_srx[1] = Demod.output[0]; - ComputeCrc14443(CRC_14443_B, select_srx, 2, &select_srx[2], &select_srx[3]); + AddCrc14B(select_srx, 2); + CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx)); GetTagSamplesFor14443bDemod(); //no if (Demod.len != 3) return 2; // Check the CRC of the answer: - ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2 , &crc[0], &crc[1]); - if(crc[0] != Demod.output[1] || crc[1] != Demod.output[2]) return 3; + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) return 3; // Check response from the tag: should be the same UID as the command we just sent: if (select_srx[1] != Demod.output[0]) return 1; @@ -1223,15 +1218,14 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) { // First get the tag's UID: select_srx[0] = ISO14443B_GET_UID; - ComputeCrc14443(CRC_14443_B, select_srx, 1 , &select_srx[1], &select_srx[2]); + AddCrc14B(select_srx, 1); CodeAndTransmit14443bAsReader(select_srx, 3); // Only first three bytes for this one GetTagSamplesFor14443bDemod(); //no if (Demod.len != 10) return 2; - // The check the CRC of the answer - ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]); - if(crc[0] != Demod.output[8] || crc[1] != Demod.output[9]) return 3; + // The check the CRC of the answer + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) return 3; if (card) { card->uidlen = 8; @@ -1252,9 +1246,6 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) { static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 }; // ATTRIB command (with space for CRC) uint8_t attrib[] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}; - - // temp to calc crc. - uint8_t crc[2] = {0x00, 0x00}; // first, wake up the tag CodeAndTransmit14443bAsReader(wupb, sizeof(wupb)); @@ -1264,8 +1255,7 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) { if (Demod.len < 14) return 2; // VALIDATE CRC - ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]); - if ( crc[0] != Demod.output[12] || crc[1] != Demod.output[13] ) + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) return 3; if (card) { @@ -1279,7 +1269,7 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) { // copy the protocol info from ATQB (Protocol Info -> Protocol_Type) into ATTRIB (Param 3) attrib[7] = Demod.output[10] & 0x0F; - ComputeCrc14443(CRC_14443_B, attrib, 9, attrib + 9, attrib + 10); + AddCrc14B(attrib, 9); CodeAndTransmit14443bAsReader(attrib, sizeof(attrib)); GetTagSamplesFor14443bDemod();//select_card @@ -1288,8 +1278,7 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) { if(Demod.len < 3) return 2; // VALIDATE CRC - ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]); - if ( crc[0] != Demod.output[1] || crc[1] != Demod.output[2] ) + if (!check_crc(CRC_14443_B, Demod.output, Demod.len) ) return 3; if (card) { @@ -1374,7 +1363,7 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) { // Signal field is on with the appropriate LED LED_D_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); - SpinDelay(20); + SpinDelay(100); uint8_t i = 0x00; @@ -1396,7 +1385,7 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) { DbpString("[!] SELECT tag:"); cmd1[0] = ISO14443B_SELECT; // 0x0E is SELECT cmd1[1] = Demod.output[0]; - ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); + AddCrc14B(cmd1, 2); CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); //no GetTagSamplesFor14443bDemod(); //no if (Demod.len != 3) { @@ -1405,8 +1394,8 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) { return; } // Check the CRC of the answer: - ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]); - if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) { + + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) { DbpString("[!] CRC Error reading select response."); set_tracing(false); return; @@ -1421,7 +1410,7 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) { // Tag is now selected, // First get the tag's UID: cmd1[0] = ISO14443B_GET_UID; - ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]); + AddCrc14B(cmd1, 1); CodeAndTransmit14443bAsReader(cmd1, 3); // no -- Only first three bytes for this one GetTagSamplesFor14443bDemod(); //no if (Demod.len != 10) { @@ -1430,8 +1419,8 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) { return; } // The check the CRC of the answer (use cmd1 as temporary variable): - ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]); - if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) { + + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) { Dbprintf("[!] CRC Error reading block! Expected: %04x got: %04x", (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]); // Do not return;, let's go on... (we should retry, maybe ?) } @@ -1451,7 +1440,7 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) { i = 0xff; } cmd1[1] = i; - ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); + AddCrc14B(cmd1, 2); CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); //no GetTagSamplesFor14443bDemod(); //no @@ -1460,8 +1449,8 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) { return; } // The check the CRC of the answer (use cmd1 as temporary variable): - ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]); - if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) { + + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) { Dbprintf("[!] CRC Error reading block! Expected: %04x got: %04x", (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]); // Do not return;, let's go on... (we should retry, maybe ?) @@ -1640,8 +1629,7 @@ void iso14b_set_trigger(bool enable) { * none * */ -void SendRawCommand14443B_Ex(UsbCommand *c) -{ +void SendRawCommand14443B_Ex(UsbCommand *c) { iso14b_command_t param = c->arg[0]; size_t len = c->arg[1] & 0xffff; uint8_t *cmd = c->d.asBytes; @@ -1687,7 +1675,7 @@ void SendRawCommand14443B_Ex(UsbCommand *c) if ((param & ISO14B_RAW) == ISO14B_RAW) { if((param & ISO14B_APPEND_CRC) == ISO14B_APPEND_CRC) { - AppendCrc14443b(cmd, len); + AddCrc14B(cmd, len); len += 2; } diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index 00f6615d7..84765537a 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -22,11 +22,18 @@ extern "C" { #include "apps.h" #include "util.h" #include "string.h" -#include "iso14443crc.h" +#include "crc16.h" #include "mifare.h" #include "protocols.h" -extern void AppendCrc14443b(uint8_t *data, int len); +#ifndef AddCrc14A +# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) +#endif + +#ifndef AddCrc14B +# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) +#endif + extern void SendRawCommand14443B_Ex(UsbCommand *c); extern void iso14443b_setup(); extern uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 8e7bddf67..79fcea774 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -81,9 +81,10 @@ #define Logic1 Iso15693Logic1 #define FrameEOF Iso15693FrameEOF -#define Crc(data,datalen) Iso15693Crc((data), (datalen)) -#define AddCrc(data,datalen) Iso15693AddCrc((data), (datalen)) -#define CheckCrc(data,datalen) Iso15693CheckCrc((data), (datalen)) +#define Crc(data, len) crc(CRC_15693, (data), (len)) +#define CheckCrc(data, len) check_crc(CRC_15693, (data), (len)) +#define AddCrc(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1) + #define sprintUID(target,uid) Iso15693sprintUID((target), (uid)) static void BuildIdentifyRequest(uint8_t *cmdout); @@ -839,7 +840,7 @@ void DbdecodeIso15693Answer(int len, uint8_t *d) { strncat(status ,"No error ", DBD15STATLEN); } - if (CheckCrc(d,len)) + if (CheckCrc(d, len)) strncat(status, "[+] crc OK", DBD15STATLEN); else strncat(status, "[!] crc fail", DBD15STATLEN); @@ -1015,7 +1016,8 @@ void BruteforceIso15693Afi(uint32_t speed) { data[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1; data[1] = ISO15_CMD_INVENTORY; data[2] = 0; // mask length - datalen = AddCrc(data, 3); + AddCrc(data, 3); + datalen += 2; recvlen = SendDataTag(data, datalen, false, speed, buf); @@ -1033,7 +1035,8 @@ void BruteforceIso15693Afi(uint32_t speed) { for (uint16_t i = 0; i < 256; i++) { data[2] = i & 0xFF; - datalen = AddCrc(data, 4); + AddCrc(data, 4); + datalen += 2; recvlen = SendDataTag(data, datalen, false, speed, buf); WDT_HIT(); if (recvlen >= 12) { diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 695684b2e..e242aa03a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -676,7 +676,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t * // Transmit MIFARE_CLASSIC_AUTH uint8_t dcmd[4] = {0x60 + (keyType & 0x01), blockNo, 0x00, 0x00}; - AppendCrc14443a(dcmd, 2); + AddCrc14A(dcmd, 2); ReaderTransmit(dcmd, sizeof(dcmd), NULL); int len = ReaderReceive(answer, par); @@ -1721,7 +1721,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){ } memcpy(data, datain, 16); - AppendCrc14443a(data, 16); + AddCrc14A(data, 16); ReaderTransmit(data, sizeof(data), NULL); if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) { diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index d5ec4e42e..ffbe380ec 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -334,7 +334,7 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain memcpy(buff1,newKey, 8); memcpy(buff2,newKey + 8, 8); - ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second); + compute_crc(CRC_14443_A, newKey, 16, &first, &second); memcpy(buff3, &first, 1); memcpy(buff3 + 1, &second, 1); @@ -376,7 +376,7 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain memcpy(buff1,newKey, 8); memcpy(buff2,newKey + 8, 8); - ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second); + compute_crc(CRC_14443_A, newKey, 16, &first, &second); memcpy(buff3, &first, 1); memcpy(buff3 + 1, &second, 1); @@ -546,7 +546,7 @@ size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){ cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards memcpy(cmd+2, datain, len); - AppendCrc14443a(cmd, len+2); + AddCrc14A(cmd, len+2); memcpy(dataout, cmd, cmdlen); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 4d16c4e16..afb9fdd8c 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -62,7 +62,7 @@ int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answe uint8_t dcmd[data_size+3]; dcmd[0] = cmd; memcpy(dcmd+1, data, data_size); - AppendCrc14443a(dcmd, data_size+1); + AddCrc14A(dcmd, data_size+1); ReaderTransmit(dcmd, sizeof(dcmd), timing); int len = ReaderReceive(answer, answer_parity); if(!len) { @@ -78,7 +78,7 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t dcmd[4] = {cmd, data, 0x00, 0x00}; uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t par[1] = {0x00}; // 1 Byte parity is enough here - AppendCrc14443a(dcmd, 2); + AddCrc14A(dcmd, 2); memcpy(ecmd, dcmd, sizeof(dcmd)); if (crypted) { @@ -213,7 +213,7 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo } memcpy(bt, receivedAnswer + 16, 2); - AppendCrc14443a(receivedAnswer, 16); + AddCrc14A(receivedAnswer, 16); if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Cmd CRC response error."); return 3; @@ -351,7 +351,7 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) { } memcpy(bt, receivedAnswer + 16, 2); - AppendCrc14443a(receivedAnswer, 16); + AddCrc14A(receivedAnswer, 16); if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error."); return 3; @@ -381,7 +381,7 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl } memcpy(d_block, blockData, 16); - AppendCrc14443a(d_block, 16); + AddCrc14A(d_block, 16); // crypto for (pos = 0; pos < 18; pos++) { @@ -424,7 +424,7 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { } memcpy(d_block, blockData, 16); - AppendCrc14443a(d_block, 16); + AddCrc14A(d_block, 16); ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); @@ -586,7 +586,7 @@ void emlClearMem(void) { // Mifare desfire commands int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[5] = {cmd, data[0], data[1], 0x00, 0x00}; - AppendCrc14443a(dcmd, 3); + AddCrc14A(dcmd, 3); ReaderTransmit(dcmd, sizeof(dcmd), NULL); int len = ReaderReceive(answer, answer_parity); @@ -601,7 +601,7 @@ int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t c uint8_t dcmd[20] = {0x00}; dcmd[0] = cmd; memcpy(dcmd+1,data,17); - AppendCrc14443a(dcmd, 18); + AddCrc14A(dcmd, 18); ReaderTransmit(dcmd, sizeof(dcmd), NULL); int len = ReaderReceive(answer, answer_parity); diff --git a/client/Makefile b/client/Makefile index f0075f560..f069e38ab 100644 --- a/client/Makefile +++ b/client/Makefile @@ -110,7 +110,6 @@ CMDSRCS = crapto1/crapto1.c \ crc.c \ crc16.c \ crc64.c \ - iso14443crc.c \ legic_prng.c \ iso15693tools.c \ prng.c \ @@ -191,7 +190,6 @@ CMDSRCS = crapto1/crapto1.c \ reveng/poly.c \ reveng/getopt.c \ bucketsort.c -# radixsort.c \ cpu_arch = $(shell uname -m) ifneq ($(findstring 86, $(cpu_arch)), ) diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 7cab35499..0f9eb4420 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -8,8 +8,6 @@ // Analyse bytes commands //----------------------------------------------------------------------------- #include "cmdanalyse.h" -#include "iso15693tools.h" -#include "util_posix.h" // msclock static int CmdHelp(const char *Cmd); @@ -287,7 +285,6 @@ int CmdAnalyseCRC(const char *Cmd) { init_table(CRC_FELICA); PrintAndLog("FeliCa | %X ", crc16_xmodem(data, len)); - return 0; PrintAndLog("\nTests of reflection. Current methods in source code"); PrintAndLog(" reflect(0x3e23L,3) is %04X == 0x3e26", reflect(0x3e23L,3) ); PrintAndLog(" reflect8(0x80) is %02X == 0x01", reflect8(0x80)); @@ -297,7 +294,7 @@ int CmdAnalyseCRC(const char *Cmd) { // uint8_t b1, b2; - PrintAndLog("\nTests with '123456789' string"); + printf("\n\nStandard test with 31 32 33 34 35 36 37 38 39 '123456789'\n\n"); uint8_t dataStr[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 }; legic8 = CRC8Legic(dataStr, sizeof(dataStr)); @@ -310,52 +307,41 @@ int CmdAnalyseCRC(const char *Cmd) { printf("-------------------------------------\n"); printf("CRC16 based\n\n"); - init_table(CRC_DNP); - PrintAndLog("DNP | %X (EA82 expected)", crc16_dnp(dataStr, sizeof(dataStr))); - - init_table(CRC_CCITT); - PrintAndLog("CCITT | %X (29B1 expected)", crc16_ccitt(dataStr, sizeof(dataStr))); - - init_table(CRC_FELICA); - PrintAndLog("FeliCa | %X (31C3 expected)", crc16_xmodem( dataStr, sizeof(dataStr))); - //uint8_t poll[10] = { 0xb2,0x4d,0x06,0x00,0xff,0xff,0x00,0x00,0x09,0x21}; - uint8_t poll[] = {0xb2,0x4d,0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80, - 0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f}; - PrintAndLog("FeliCa | %X (B37F expected)", crc16_xmodem( poll+2, sizeof(poll)-4)); - PrintAndLog("FeliCa | %X (0000 expected)", crc16_xmodem( poll+2, sizeof(poll)-2)); - printf("-------------------------------------\n"); - printf("\n\n"); + // input from commandline + PrintAndLog("CCITT | %X (29B1 expected)", crc(CRC_CCITT, dataStr, sizeof(dataStr))); + uint8_t poll[] = {0xb2,0x4d,0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80, 0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f}; + PrintAndLog("FeliCa | %X (B37F expected)", crc(CRC_FELICA, poll+2, sizeof(poll)-4)); + PrintAndLog("FeliCa | %X (0000 expected)", crc(CRC_FELICA, poll+2, sizeof(poll)-2)); + + uint8_t sel_corr[] = { 0x40, 0xe1, 0xe1, 0xff, 0xfe, 0x5f, 0x02, 0x3c, 0x43, 0x01}; + PrintAndLog("iCLASS | %04x (0143 expected)", crc(CRC_ICLASS, sel_corr, sizeof(sel_corr)-2)); + printf("---------------------------------------------------------------\n\n\n"); // ISO14443 crc A - - // table test. - init_table(CRC_14A); - uint16_t crcA = crc16_a(dataStr, sizeof(dataStr)); - ComputeCrc14443(CRC_14443_A, dataStr, sizeof(dataStr), &b1, &b2); + compute_crc(CRC_14443_A, dataStr, sizeof(dataStr), &b1, &b2); uint16_t crcAA = b1 << 8 | b2; - printf("ISO14443 crc A | %04x == %04x (BF05 expected)\n", crcA, crcAA); + printf("ISO14443 crc A | %04x or %04x (BF05 expected)\n", crcAA, crc(CRC_14443_A, dataStr, sizeof(dataStr)) ); // ISO14443 crc B - init_table(CRC_14B); - uint16_t crcB = crc16_x25(dataStr, sizeof(dataStr)); - ComputeCrc14443(CRC_14443_B, dataStr, sizeof(dataStr), &b1, &b2); + compute_crc(CRC_14443_B, dataStr, sizeof(dataStr), &b1, &b2); uint16_t crcBB = b1 << 8 | b2; - printf("ISO14443 crc B | %04x == %04x (906E expected)\n", crcB, crcBB); + printf("ISO14443 crc B | %04x or %04x (906E expected)\n", crcBB, crc(CRC_14443_B, dataStr, sizeof(dataStr)) ); // ISO15693 crc (x.25) - init_table(CRC_15); - uint16_t x25 = crc16_x25(dataStr, sizeof(dataStr)); - uint16_t iso = Iso15693Crc(dataStr, sizeof(dataStr)); - printf("ISO15693 crc X25 | %04x == %04x (906E expected)\n", iso, x25 ); + compute_crc(CRC_15693, dataStr, sizeof(dataStr), &b1, &b2); + uint16_t crcCC = b1 << 8 | b2; + printf("ISO15693 crc X25| %04x or %04x (906E expected)\n", crcCC, crc(CRC_15693, dataStr, sizeof(dataStr)) ); // ICLASS - init_table(CRC_15_ICLASS); - uint16_t iclass_new = crc16_iclass(dataStr, sizeof(dataStr)); - ComputeCrc14443(CRC_ICLASS, dataStr, sizeof(dataStr), &b1, &b2); - uint16_t crcCC = b1 << 8 | b2; - printf("ICLASS crc | %04x == %04x \n", crcCC, iclass_new); + compute_crc(CRC_ICLASS, dataStr, sizeof(dataStr), &b1, &b2); + uint16_t crcDD = b1 << 8 | b2; + printf("ICLASS crc | %04x or %04x\n", crcDD, crc(CRC_ICLASS, dataStr, sizeof(dataStr)) ); + // FeliCa + compute_crc(CRC_FELICA, dataStr, sizeof(dataStr), &b1, &b2); + uint16_t crcEE = b1 << 8 | b2; + printf("FeliCa | %04x or %04x (31C3 expected)\n", crcEE, crc(CRC_FELICA, dataStr, sizeof(dataStr))); free(data); return 0; @@ -468,113 +454,72 @@ int CmdAnalyseTEASelfTest(const char *Cmd){ int CmdAnalyseA(const char *Cmd){ + uint8_t syncBit = 99; + // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from + // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111) + // we therefore look for a ...xx1111 11111111 00x11111xxxxxx... pattern + // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's) + # define SYNC_16BIT 0x4DB2 + #define FELICA_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000 - PrintAndLog("ISO 15693 - x25 - Residue %04x ( %0xF0B8 expected) ", ISO15_CRC_CHECK); - - uint8_t b1, b2; - - // 14 a - uint8_t halt[] = {0x50 , 0x00, 0x57, 0xcd }; //halt w crc - uint8_t atqs[] = {0x09, 0x78, 0x00, 0x92, 0x02, 0x54, 0x13, 0x02, 0x04, 0x2d, 0xe8 }; // atqs w crc - ComputeCrc14443(CRC_14443_A, halt, sizeof(halt), &b1, &b2); - printf("14a crc halt == 0 [%s]\n", (b1==0 && b2==0) ? "YES": "NO" ); - ComputeCrc14443(CRC_14443_A, atqs, sizeof(atqs), &b1, &b2); - printf("14a crc ATQS == 0 [%s]\n", (b1==0 && b2==0) ? "YES": "NO" ); + uint32_t shiftReg = SYNC_16BIT; + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 0))); + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 1))); + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 2))); + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 3))); + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 4))); + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 5))); + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 6))); + printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 7))); - // 14b - uint8_t u14b[] = {0x05,0x00,0x08,0x39,0x73}; - ComputeCrc14443(CRC_14443_B, u14b, sizeof(u14b), &b1, &b2); - printf("14b crc u14b == 0 [%s] %02x %02x\n", (b1==0 && b2==0) ? "YES": "NO" , b1,b2); - ComputeCrc14443(CRC_14443_B, u14b, sizeof(u14b)-2, &b1, &b2); - printf("14b crc u14b == 0 [%s] %02x %02x\n", (b1==0 && b2==0) ? "YES": "NO" , b1,b2); + for ( uint8_t i=0; i<32; i++){ + if ((shiftReg & (SYNC_16BIT >> 0)) == SYNC_16BIT >> 0) syncBit = 7; + else if ((shiftReg & (SYNC_16BIT >> 1)) == SYNC_16BIT >> 1) syncBit = 6; + else if ((shiftReg & (SYNC_16BIT >> 2)) == SYNC_16BIT >> 2) syncBit = 5; + else if ((shiftReg & (SYNC_16BIT >> 3)) == SYNC_16BIT >> 3) syncBit = 4; + else if ((shiftReg & (SYNC_16BIT >> 4)) == SYNC_16BIT >> 4) syncBit = 3; + else if ((shiftReg & (SYNC_16BIT >> 5)) == SYNC_16BIT >> 5) syncBit = 2; + else if ((shiftReg & (SYNC_16BIT >> 6)) == SYNC_16BIT >> 6) syncBit = 1; + else if ((shiftReg & (SYNC_16BIT >> 7)) == SYNC_16BIT >> 7) syncBit = 0; - printf("x25 or 14b command %04X == (3973)\n", crc16_x25(u14b, sizeof(u14b)-2)); - printf("x25 or 14b command %04X == (0)\n", crc16_x25(u14b, sizeof(u14b))); - - printf("\n\n"); + printf("ShiftReg is [%04x] | SyncBit is [%u]\n", shiftReg, syncBit); + shiftReg = shiftReg << 1 | ( shiftReg & 0x8000 ) >> 15; + } +/* +pm3 --> da hex2bin 4db2 0100110110110010 +pm3 --> da hex2bin 926d9 10010010011011011001 +*/ return 0; - - time_t t; - srand((unsigned) time(&t)); - uint64_t t1 = msclock(); - // test CRC-A etc - for (int foo=0; foo < 10000000; foo++) { - crc16_a(atqs, sizeof(atqs)); - atqs[1] = rand(); - atqs[2] = rand(); - atqs[3] = rand(); - atqs[4] = rand(); - } - t1 = msclock() - t1; printf("ticks crc_a %" PRIu64 "\n", t1); - - t1 = msclock(); - for (int foo=0; foo < 10000000; foo++) { - ComputeCrc14443(CRC_14443_A, atqs, sizeof(atqs), &b1, &b2); - atqs[1] = rand(); - atqs[2] = rand(); - atqs[3] = rand(); - atqs[4] = rand(); } - t1 = msclock() - t1; printf("ticks curr CRC-a %" PRIu64 "\n", t1); - - - // test ISO15693 crc - t1 = msclock(); - for (int foo=0; foo < 10000000; foo++) { - crc16_x25(atqs, sizeof(atqs)); - atqs[1] = rand(); - atqs[2] = rand(); - atqs[3] = rand(); - atqs[4] = rand(); - } - t1 = msclock() - t1; printf("ticks x25 %" PRIu64 "\n", t1); - - t1 = msclock(); - for (int foo=0; foo < 10000000; foo++) { - Iso15693Crc(atqs, sizeof(atqs)); - atqs[1] = rand(); - atqs[2] = rand(); - atqs[3] = rand(); - atqs[4] = rand(); } - t1 = msclock() - t1; printf("ticks curr iso15 (x25) %" PRIu64 "\n", t1); - //return 0; + // 14443-A + uint8_t u14_c[] = {0x09, 0x78, 0x00, 0x92, 0x02, 0x54, 0x13, 0x02, 0x04, 0x2d, 0xe8 }; // atqs w crc + uint8_t u14_w[] = {0x09, 0x78, 0x00, 0x92, 0x02, 0x54, 0x13, 0x02, 0x04, 0x2d, 0xe7 }; // atqs w crc + printf("14a check wrong crc | %s\n", (check_crc(CRC_14443_A, u14_w, sizeof(u14_w))) ? "YES": "NO" ); + printf("14a check correct crc | %s\n", (check_crc(CRC_14443_A, u14_c, sizeof(u14_c))) ? "YES": "NO" ); - // 16bit test - uint8_t md; - uint32_t mb, mc; + // 14443-B + uint8_t u14b[] = {0x05,0x00,0x08,0x39,0x73}; + printf("14b check crc | %s\n", (check_crc(CRC_14443_B, u14b, sizeof(u14b))) ? "YES": "NO"); - // reflect - t1 = msclock(); - for (int foo=0; foo < 10000000; foo++) { - mb = rand(); - reflect(mb, 16); - } - t1 = msclock() - t1; printf("ticks reflect %" PRIu64 "\n", t1); + // 15693 test + uint8_t u15_c[] = {0x05,0x00,0x08,0x39,0x73}; // correct + uint8_t u15_w[] = {0x05,0x00,0x08,0x39,0x72}; // wrong + printf("15 check wrong crc | %s\n", (check_crc(CRC_15693, u15_w, sizeof(u15_w))) ? "YES": "NO"); + printf("15 check correct crc | %s\n", (check_crc(CRC_15693, u15_c, sizeof(u15_c))) ? "YES": "NO"); + + // iCLASS test - wrong crc , swapped bytes. + uint8_t iclass_w[] = { 0x40, 0xe1, 0xe1, 0xff, 0xfe, 0x5f, 0x02, 0x3c, 0x01, 0x43}; + uint8_t iclass_c[] = { 0x40, 0xe1, 0xe1, 0xff, 0xfe, 0x5f, 0x02, 0x3c, 0x43, 0x01}; + printf("iCLASS check wrong crc | %s\n", (check_crc(CRC_ICLASS, iclass_w, sizeof(iclass_w))) ? "YES": "NO"); + printf("iCLASS check correct crc | %s\n", (check_crc(CRC_ICLASS, iclass_c, sizeof(iclass_c))) ? "YES": "NO"); - // reflect16 - t1 = msclock(); - for (int foo=0; foo < 10000000; foo++) { - mc = rand(); - reflect16(mc); - } - t1 = msclock() - t1; printf("ticks reflect16 %" PRIu64 "\n", t1); - //--------------------------------------------------------- + // FeliCa test + uint8_t felica_w[] = {0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80, 0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7e}; + uint8_t felica_c[] = {0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80, 0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f}; + printf("FeliCa check wrong crc | %s\n", (check_crc(CRC_FELICA, felica_w, sizeof(felica_w))) ? "YES": "NO"); + printf("FeliCa check correct crc | %s\n", (check_crc(CRC_FELICA, felica_c, sizeof(felica_c))) ? "YES": "NO"); - // reflect - t1 = msclock(); - for (int foo=0; foo < 10000000; foo++) { - md = rand(); - reflect(md, 8); - } - t1 = msclock() - t1; printf("ticks reflect _8_ %" PRIu64 "\n", t1); - - // reflect8 - t1 = msclock(); - for (int foo=0; foo < 10000000; foo++) { - md = rand(); - reflect8(md); - } - t1 = msclock() - t1; printf("ticks reflect8 %" PRIu64 "\n", t1); + printf("\n\n"); return 0; /* @@ -876,19 +821,19 @@ int CmdAnalyseHid(const char *Cmd){ void generate4bNUID(uint8_t *uid, uint8_t *nuid){ uint16_t crc; - uint8_t first, second; + uint8_t b1, b2; - ComputeCrc14443(CRC_14443_A, uid, 3, &first, &second); - nuid[0] |= (second & 0xE0) | 0xF; - nuid[1] = first; + compute_crc(CRC_14443_A, uid, 3, &b1, &b2); + nuid[0] |= (b2 & 0xE0) | 0xF; + nuid[1] = b1; - crc = first; - crc |= second << 8; + crc = b1; + crc |= b2 << 8; - UpdateCrc14443(uid[3], &crc); - UpdateCrc14443(uid[4], &crc); - UpdateCrc14443(uid[5], &crc); - UpdateCrc14443(uid[6], &crc); + crc = update_crc16(uid[3], crc); + crc = update_crc16(uid[4], crc); + crc = update_crc16(uid[5], crc); + crc = update_crc16(uid[6], crc); nuid[2] = (crc >> 8) & 0xFF ; nuid[3] = crc & 0xFF; diff --git a/client/cmdanalyse.h b/client/cmdanalyse.h index 53f984792..f834c717d 100644 --- a/client/cmdanalyse.h +++ b/client/cmdanalyse.h @@ -19,13 +19,13 @@ #include "ui.h" // PrintAndLog #include "util.h" #include "crc.h" -#include "iso15693tools.h" // -#include "iso14443crc.h" // crc 14a #include "crc16.h" // crc16 ccitt #include "tea.h" #include "legic_prng.h" #include "loclass/elite_crack.h" #include "mfkey.h" //nonce2key +#include "util_posix.h" // msclock + int usage_analyse_lcr(void); int usage_analyse_checksum(void); diff --git a/client/cmdhf.c b/client/cmdhf.c index e273e11ba..935dfca7e 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -420,42 +420,27 @@ void annotateFelica(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){ * 2 : Not crc-command */ -uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* data, uint8_t len) -{ - uint8_t b1,b2; - - if(len <= 2) return 2; - - if(isResponse & (len < 6)) return 2; - - ComputeCrc14443(CRC_14443_A, data, len-2, &b1, &b2); - if (b1 != data[len-2] || b2 != data[len-1]) - return 0; - - return 1; +uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* d, uint8_t n) { + if (n < 3) return 2; + if (isResponse & (n < 6)) return 2; + return check_crc(CRC_14443_A, d, n); } /** - * @brief iso14443B_CRC_check Checks CRC in command or response - * @param isResponse + * @brief iso14443B_CRC_check Checks CRC * @param data * @param len * @return 0 : CRC-command, CRC not ok * 1 : CRC-command, CRC ok * 2 : Not crc-command */ -uint8_t iso14443B_CRC_check(bool isResponse, uint8_t* data, uint8_t len) -{ - uint8_t b1,b2; +uint8_t iso14443B_CRC_check(uint8_t* d, uint8_t n) { + return check_crc(CRC_14443_B, d, n); +} - if(len <= 2) return 2; - - ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2); - if(b1 != data[len-2] || b2 != data[len-1]) - return 0; - - return 1; +uint8_t iso15693_CRC_check(uint8_t* d, uint8_t n) { + return check_crc(CRC_15693, d, n); } /** @@ -467,13 +452,13 @@ uint8_t iso14443B_CRC_check(bool isResponse, uint8_t* data, uint8_t len) * 1 : CRC-command, CRC ok * 2 : Not crc-command */ -uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len) +uint8_t iclass_CRC_check(bool isResponse, uint8_t* d, uint8_t n) { - if(len < 4) return 2;//CRC commands (and responses) are all at least 4 bytes - - uint8_t b1, b2; + //CRC commands (and responses) are all at least 4 bytes + if (n < 4) return 2; //Commands to tag + //Don't include the command byte if (!isResponse) { /** These commands should have CRC. Total length leftmost @@ -484,10 +469,8 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len) 4 PAGESEL **/ //Covers three of them - if(len == 4 || len == 12) { - //Don't include the command byte - ComputeCrc14443(CRC_ICLASS, (data+1), len-3, &b1, &b2); - return b1 == data[len -2] && b2 == data[len-1]; + if (n == 4 || n == 12) { + return check_crc( CRC_ICLASS, d+1, n-1); } return 2; } @@ -512,23 +495,9 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len) In conclusion, without looking at the command; any response of length 10 or 34 should have CRC **/ - if(len != 10 && len != 34) return true; + if (n != 10 && n != 34) return true; - ComputeCrc14443(CRC_ICLASS, data, len-2, &b1, &b2); - return b1 == data[len -2] && b2 == data[len-1]; -} -// CRC Iso15693Crc(data,datalen) -uint8_t iso15693_CRC_check(bool isResponse, uint8_t* data, uint8_t len) { - if ( len <= 3) return 2; - - uint16_t crc = Iso15693Crc(data, len-2); - uint8_t b1 = crc & 0xFF; - uint8_t b2 = ((crc >> 8) & 0xFF); - - if ( b1 != data[len-2] || b2 != data[len-1] ) - return 0; - - return 1; + return check_crc( CRC_ICLASS, d, n); } bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen) @@ -640,14 +609,14 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui case ISO_14443B: case TOPAZ: case FELICA: - crcStatus = iso14443B_CRC_check(isResponse, frame, data_len); + crcStatus = iso14443B_CRC_check(frame, data_len); break; case ISO_14443A: case MFDES: crcStatus = iso14443A_CRC_check(isResponse, frame, data_len); break; case ISO_15693: - crcStatus = iso15693_CRC_check(isResponse, frame, data_len); + crcStatus = iso15693_CRC_check(frame, data_len); break; default: break; diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index eed98bf80..c0994e736 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -914,9 +914,9 @@ int CmdHF14ACmdRaw(const char *cmd) { if (crc && datalen>0 && datalen= 3 ) { - ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2); - crc = ( data[len-2] == b1 && data[len-1] == b2); + crc = check_crc(CRC_14443_B, data, len); PrintAndLog("[LEN %u] %s[%02X %02X] %s", len, diff --git a/client/cmdhf14b.h b/client/cmdhf14b.h index 4642339b1..6db0528f3 100644 --- a/client/cmdhf14b.h +++ b/client/cmdhf14b.h @@ -15,7 +15,7 @@ #include #include #include -#include "iso14443crc.h" +#include "crc16.h" #include "proxmark3.h" #include "data.h" #include "graph.h" diff --git a/client/cmdhf15.c b/client/cmdhf15.c index fa12dee42..c4222e0d8 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -2,6 +2,7 @@ // Copyright (C) 2010 iZsh // Modified 2010-2012 by // Modified 2012 by +// Modfified 2018 by // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -28,8 +29,10 @@ #define Logic1 Iso15693Logic1 #define FrameEOF Iso15693FrameEOF -#define Crc(data, len) Iso15693Crc((data), (len)) -#define AddCrc(data, len) Iso15693AddCrc((data), (len)) +#define Crc(data, len) crc(CRC_15693, (data), (len)) +#define CheckCrc(data, len) check_crc(CRC_15693, (data), (len)) +#define AddCrc(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1) + #define sprintUID(target, uid) Iso15693sprintUID((target), (uid)) // structure and database for uid -> tagtype lookups @@ -195,7 +198,8 @@ int getUID(uint8_t *buf) { c.d.asBytes[1] = ISO15_CMD_INVENTORY; c.d.asBytes[2] = 0; // mask length - c.arg[0] = AddCrc(c.d.asBytes, 3); + AddCrc(c.d.asBytes, 3); + c.arg[0] = 5; // len uint8_t retry; @@ -208,7 +212,7 @@ int getUID(uint8_t *buf) { if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { uint8_t resplen = resp.arg[0]; - if (resplen >= 12 && ISO15_CRC_CHECK == Crc(resp.d.asBytes, 12)) { + if (resplen >= 12 && CheckCrc(resp.d.asBytes, 12)) { memcpy(buf, resp.d.asBytes + 2, 8); return 1; } @@ -460,7 +464,7 @@ int CmdHF15Demod(const char *Cmd) { for (i = 0; i < k; i++) PrintAndLog("# %2d: %02x ", i, outBuf[i]); - PrintAndLog("CRC %04x", Iso15693Crc(outBuf, k - 2)); + PrintAndLog("CRC %04x", Crc(outBuf, k - 2)); return 0; } @@ -492,7 +496,6 @@ int CmdHF15Info(const char *Cmd) { uint8_t *recv; UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv? uint8_t *req = c.d.asBytes; - int reqlen = 0; char cmdbuf[100]; char *cmd = cmdbuf; @@ -501,8 +504,8 @@ int CmdHF15Info(const char *Cmd) { if ( !prepareHF15Cmd(&cmd, &c, ISO15_CMD_SYSINFO) ) return 0; - reqlen = AddCrc(req, c.arg[0]); - c.arg[0] = reqlen; + AddCrc(req, c.arg[0]); + c.arg[0] += 2; //PrintAndLog("cmd %s", sprint_hex(c.d.asBytes, reqlen) ); @@ -686,7 +689,7 @@ int CmdHF15Dump(const char*Cmd) { PrintAndLog("Reading memory from tag UID %s", sprintUID(NULL, uid)); - int reqlen = 0, blocknum = 0; + int blocknum = 0; uint8_t *recv = NULL; // memory. @@ -707,8 +710,8 @@ int CmdHF15Dump(const char*Cmd) { for (int retry = 0; retry < 5; retry++) { req[10] = blocknum; - reqlen = AddCrc(req, 11); - c.arg[0] = reqlen; + AddCrc(req, 11); + c.arg[0] = 13; clearCommandBuffer(); SendCommand(&c); @@ -723,7 +726,7 @@ int CmdHF15Dump(const char*Cmd) { recv = resp.d.asBytes; - if ( ISO15_CRC_CHECK != Crc(recv, len) ) { + if ( !CheckCrc(recv, len) ) { PrintAndLog("crc fail"); continue; } @@ -827,9 +830,13 @@ int CmdHF15Raw(const char *Cmd) { PrintAndLog("Invalid char on input"); return 0; } - if (crc) datalen = AddCrc(data, datalen); - c.arg[0] = datalen; + if (crc) { + AddCrc(data, datalen); + c.arg[0] = datalen+2; + } else { + c.arg[0] = datalen; + } c.arg[1] = fast; c.arg[2] = reply; memcpy(c.d.asBytes, data, datalen); @@ -972,8 +979,8 @@ int CmdHF15Readmulti(const char *Cmd) { req[reqlen++] = pagenum; req[reqlen++] = pagecount; - reqlen = AddCrc(req, reqlen); - c.arg[0] = reqlen; + AddCrc(req, reqlen); + c.arg[0] = reqlen+2; clearCommandBuffer(); SendCommand(&c); @@ -991,7 +998,7 @@ int CmdHF15Readmulti(const char *Cmd) { recv = resp.d.asBytes; - if (ISO15_CRC_CHECK != Crc(recv, status)) { + if (!CheckCrc(recv, status)) { PrintAndLog("CRC failed"); return 2; } @@ -1051,9 +1058,9 @@ int CmdHF15Read(const char *Cmd) { req[reqlen++] = (uint8_t)blocknum; - reqlen = AddCrc(req, reqlen); + AddCrc(req, reqlen); - c.arg[0] = reqlen; + c.arg[0] = reqlen+2; clearCommandBuffer(); SendCommand(&c); @@ -1071,7 +1078,7 @@ int CmdHF15Read(const char *Cmd) { recv = resp.d.asBytes; - if (ISO15_CRC_CHECK != Crc(recv, status)) { + if ( !CheckCrc(recv, status) ) { PrintAndLog("CRC failed"); return 2; } @@ -1134,8 +1141,8 @@ int CmdHF15Write(const char *Cmd) { req[reqlen++]=temp & 0xff; cmd2+=2; } - reqlen = AddCrc(req,reqlen); - c.arg[0] = reqlen; + AddCrc(req, reqlen); + c.arg[0] = reqlen+2; PrintAndLog("iso15693 writing to page %02d (0x&02X) | data ", pagenum, pagenum); @@ -1155,7 +1162,7 @@ int CmdHF15Write(const char *Cmd) { recv = resp.d.asBytes; - if (ISO15_CRC_CHECK != Crc(recv, status)) { + if ( !CheckCrc(recv, status) ) { PrintAndLog("CRC failed"); return 2; } @@ -1188,7 +1195,8 @@ int CmdHF15Select(const char *Cmd) { //Select (usage: 2025+8bytes UID+2bytes ISO15693-CRC - can be used in addressed form only!) [NO NEED FOR OPTION FLAG] // len - c.arg[0] = AddCrc(c.d.asBytes, 10); + AddCrc(c.d.asBytes, 10); + c.arg[0] = 12; clearCommandBuffer(); SendCommand(&c); diff --git a/client/cmdhf15.h b/client/cmdhf15.h index fa6082676..2d55f3553 100644 --- a/client/cmdhf15.h +++ b/client/cmdhf15.h @@ -22,7 +22,7 @@ #include "ui.h" #include "util.h" #include "cmdparser.h" -#include "iso15693tools.h" // iso15 crc +#include "crc16.h" // iso15 crc #include "cmdmain.h" #include "cmddata.h" // getsamples #include "loclass/fileutils.h" // savefileEML diff --git a/client/cmdhffelica.c b/client/cmdhffelica.c index ba3960489..f03d287f3 100644 --- a/client/cmdhffelica.c +++ b/client/cmdhffelica.c @@ -23,7 +23,6 @@ int usage_hf_felica_sim(void) { PrintAndLog(" hf felica sim t 1 "); return 0; } - int usage_hf_felica_sniff(void){ PrintAndLog("It get data from the field and saves it into command buffer."); PrintAndLog("Buffer accessible from command 'hf list felica'"); @@ -55,15 +54,13 @@ int usage_hf_felica_dumplite(void) { return 0; } int usage_hf_felica_raw(void){ - PrintAndLog("Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] [-t] [-b] <0A 0B 0C ... hex>"); + PrintAndLog("Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>"); PrintAndLog(" -h this help"); PrintAndLog(" -r do not read response"); PrintAndLog(" -c calculate and append CRC"); PrintAndLog(" -p leave the signal field ON after receive"); PrintAndLog(" -a active signal field ON without select"); PrintAndLog(" -s active signal field ON with select"); - PrintAndLog(" -b number of bits to send. Useful for send partial byte"); - PrintAndLog(" -t timeout in ms"); return 0; } @@ -107,13 +104,13 @@ int CmdHFFelicaReader(const char *Cmd) { break; } case 0: { - PrintAndLog("FeliCa Card found"); + PrintAndLog("FeliCa Card"); PrintAndLog("IDm %s", sprint_hex(card.IDm, sizeof(card.IDm))); PrintAndLog(" - CODE %s", sprint_hex(card.code, sizeof(card.code))); - PrintAndLog(" - NFCUID1 %s", sprint_hex(card.uid, sizeof(card.uid))); + PrintAndLog(" - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid))); - PrintAndLog("PMm %s", sprint_hex(card.PMm, sizeof(card.PMm))); + PrintAndLog("Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm))); PrintAndLog(" - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode))); PrintAndLog(" - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt))); @@ -244,6 +241,7 @@ int CmdHFFelicaSimLite(const char *Cmd) { static void printSep() { PrintAndLog("------------------------------------------------------------------------------------"); } + uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace,uint16_t tracelen) { if (tracepos+19 >= tracelen) return tracelen; @@ -417,8 +415,6 @@ int CmdHFFelicaCmdRaw(const char *cmd) { bool active = false; bool active_select = false; uint16_t numbits = 0; - bool bTimeout = false; - uint32_t timeout = 0; char buf[5]=""; int i = 0; uint8_t data[USB_CMD_DATA_SIZE]; @@ -459,14 +455,6 @@ int CmdHFFelicaCmdRaw(const char *cmd) { while(cmd[i]!=' ' && cmd[i]!='\0') { i++; } i-=2; break; - case 't': - bTimeout = true; - sscanf(cmd+i+2, "%d", &temp); - timeout = temp; - i+=3; - while(cmd[i]!=' ' && cmd[i]!='\0') { i++; } - i-=2; - break; default: return usage_hf_felica_raw(); } @@ -496,35 +484,25 @@ int CmdHFFelicaCmdRaw(const char *cmd) { return 0; } - if (crc && datalen>0 && datalen0 && datalen < sizeof(data)-2) { + uint8_t b1, b2; + compute_crc(CRC_FELICA, data, datalen, &b1, &b2); + data[datalen++] = b1; + data[datalen++] = b2; } if (active || active_select) { - c.arg[0] |= ISO14A_CONNECT; + c.arg[0] |= FELICA_CONNECT; if(active) - c.arg[0] |= ISO14A_NO_SELECT; + c.arg[0] |= FELICA_NO_SELECT; } - if (bTimeout){ - #define MAX_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s - c.arg[0] |= ISO14A_SET_TIMEOUT; - if(timeout > MAX_TIMEOUT) { - timeout = MAX_TIMEOUT; - PrintAndLog("Set timeout to 40542 seconds (11.26 hours). The max we can wait for response"); - } - c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) - } - if (power) { - c.arg[0] |= ISO14A_NO_DISCONNECT; + c.arg[0] |= FELICA_NO_DISCONNECT; } - if (datalen>0) { - c.arg[0] |= ISO14A_RAW; + if (datalen > 0) { + c.arg[0] |= FELICA_RAW; } // Max buffer is USB_CMD_DATA_SIZE diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index f4d8927d5..6228a6f7a 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -7,21 +7,8 @@ //----------------------------------------------------------------------------- // High frequency Topaz (NFC Type 1) commands //----------------------------------------------------------------------------- - -#include -#include -#include -#include -#include "cmdmain.h" -#include "cmdparser.h" #include "cmdhftopaz.h" -#include "cmdhf14a.h" -#include "ui.h" -#include "mifare.h" -#include "proxmark3.h" -#include "iso14443crc.h" -#include "protocols.h" -#include "cmdhf.h" + #define TOPAZ_STATIC_MEMORY (0x0f * 8) // 15 blocks with 8 Bytes each // a struct to describe a memory area which contains lock bits and the corresponding lockable memory area @@ -43,24 +30,18 @@ static struct { dynamic_lock_area_t *dynamic_lock_areas; // lock area descriptors } topaz_tag; - -static void topaz_switch_on_field(void) -{ +static void topaz_switch_on_field(void) { UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, 0, 0}}; SendCommand(&c); } - -static void topaz_switch_off_field(void) -{ +static void topaz_switch_off_field(void) { UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; SendCommand(&c); } - // send a raw topaz command, returns the length of the response (0 in case of error) -static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response) -{ +static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response) { UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0}}; memcpy(c.d.asBytes, cmd, len); SendCommand(&c); @@ -77,13 +58,12 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response) // calculate CRC bytes and send topaz command, returns the length of the response (0 in case of error) -static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) -{ +static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) { if (len > 1) { - uint8_t first, second; - ComputeCrc14443(CRC_14443_B, cmd, len-2, &first, &second); - cmd[len-2] = first; - cmd[len-1] = second; + uint8_t b1, b2; + compute_crc(CRC_14443_B, cmd, len-2, &b1, &b2); + cmd[len-2] = b1; + cmd[len-1] = b2; } return topaz_send_cmd_raw(cmd, len, response); @@ -91,8 +71,7 @@ static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) // select a topaz tag. Send WUPA and RID. -static int topaz_select(uint8_t *atqa, uint8_t *rid_response) -{ +static int topaz_select(uint8_t *atqa, uint8_t *rid_response) { // ToDo: implement anticollision uint8_t wupa_cmd[] = {TOPAZ_WUPA}; @@ -115,8 +94,7 @@ static int topaz_select(uint8_t *atqa, uint8_t *rid_response) // read all of the static memory of a selected Topaz tag. -static int topaz_rall(uint8_t *uid, uint8_t *response) -{ +static int topaz_rall(uint8_t *uid, uint8_t *response) { uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(&rall_cmd[3], uid, 4); @@ -141,16 +119,12 @@ static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data) topaz_switch_off_field(); return -1; // READ8 failed } - memcpy(block_data, &read8_response[1], 8); - return 0; } - // read a segment (16 blocks = 128 Bytes) of a selected Topaz tag. Works only for tags with dynamic memory. -static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data) -{ +static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data) { uint8_t rseg_cmd[] = {TOPAZ_RSEG, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t rseg_response[131]; @@ -160,18 +134,13 @@ static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data topaz_switch_off_field(); return -1; // RSEG failed } - memcpy(segment_data, &rseg_response[1], 128); - return 0; } - // search for the lock area descriptor for the lockable area including byteno -static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) -{ - dynamic_lock_area_t *lock_area; - +static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) { + dynamic_lock_area_t *lock_area; lock_area = topaz_tag.dynamic_lock_areas; while (lock_area != NULL) { @@ -181,14 +150,11 @@ static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) return lock_area; } } - return NULL; } - // check if a memory byte is locked. -static bool topaz_byte_is_locked(uint16_t byteno) -{ +static bool topaz_byte_is_locked(uint16_t byteno) { uint8_t *lockbits; uint16_t locked_bytes_per_bit; dynamic_lock_area_t *lock_area; @@ -217,9 +183,8 @@ static bool topaz_byte_is_locked(uint16_t byteno) // read and print the Capability Container -static int topaz_print_CC(uint8_t *data) -{ - if(data[0] != 0xe1) { +static int topaz_print_CC(uint8_t *data) { + if (data[0] != 0xe1) { topaz_tag.size = TOPAZ_STATIC_MEMORY; return -1; // no NDEF message } @@ -239,8 +204,7 @@ static int topaz_print_CC(uint8_t *data) // return type, length and value of a TLV, starting at memory position *TLV_ptr -static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) -{ +static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) { *TLV_length = 0; *TLV_value = NULL; @@ -274,8 +238,7 @@ static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, // lock area TLVs contain no information on the start of the respective lockable area. Lockable areas // do not include the lock bits and reserved memory. We therefore need to adjust the start of the // respective lockable areas accordingly -static void adjust_lock_areas(uint16_t block_start, uint16_t block_size) -{ +static void adjust_lock_areas(uint16_t block_start, uint16_t block_size) { dynamic_lock_area_t *lock_area = topaz_tag.dynamic_lock_areas; while (lock_area != NULL) { if (lock_area->first_locked_byte <= block_start) { @@ -287,8 +250,7 @@ static void adjust_lock_areas(uint16_t block_start, uint16_t block_size) // read and print the lock area and reserved memory TLVs -static void topaz_print_control_TLVs(uint8_t *memory) -{ +static void topaz_print_control_TLVs(uint8_t *memory) { uint8_t *TLV_ptr = memory; uint8_t TLV_type = 0; uint16_t TLV_length; @@ -297,7 +259,7 @@ static void topaz_print_control_TLVs(uint8_t *memory) bool reserved_memory_control_TLV_present = false; uint16_t next_lockable_byte = 0x0f * 8; // first byte after static memory area - while(*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) { + while (*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) { // all Lock Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV) get_TLV(&TLV_ptr, &TLV_type, &TLV_length, &TLV_value); if (TLV_type == 0x01) { // a Lock Control TLV @@ -360,32 +322,28 @@ static void topaz_print_control_TLVs(uint8_t *memory) } } - // read all of the dynamic memory -static int topaz_read_dynamic_data(void) -{ +static int topaz_read_dynamic_data(void){ // first read the remaining block of segment 0 - if(topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) { + if (topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) { PrintAndLog("Error while reading dynamic memory block %02x. Aborting...", 0x0f); return -1; } // read the remaining segments uint8_t max_segment = topaz_tag.size / 128 - 1; - for(uint8_t segment = 1; segment <= max_segment; segment++) { - if(topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment-1)*128+8]) == -1) { + for (uint8_t segment = 1; segment <= max_segment; segment++) { + if (topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment-1)*128+8]) == -1) { PrintAndLog("Error while reading dynamic memory block %02x. Aborting...", 0x0f); return -1; } - } - - return 0; + } + return 0; } // read and print the dynamic memory -static void topaz_print_dynamic_data(void) -{ +static void topaz_print_dynamic_data(void) { if (topaz_tag.size > TOPAZ_STATIC_MEMORY) { PrintAndLog("Dynamic Data blocks:"); if (topaz_read_dynamic_data() == 0) { @@ -405,22 +363,16 @@ static void topaz_print_dynamic_data(void) } } - -static void topaz_print_lifecycle_state(uint8_t *data) -{ +static void topaz_print_lifecycle_state(uint8_t *data) { // to be done } - -static void topaz_print_NDEF(uint8_t *data) -{ +static void topaz_print_NDEF(uint8_t *data) { // to be done. } - -// read a Topaz tag and print some usefull information -int CmdHFTopazReader(const char *Cmd) -{ +// read a Topaz tag and print some useful information +int CmdHFTopazReader(const char *Cmd) { int status; uint8_t atqa[2]; uint8_t rid_response[8]; @@ -463,7 +415,7 @@ int CmdHFTopazReader(const char *Cmd) status = topaz_rall(uid_echo, rall_response); - if(status == -1) { + if (status == -1) { PrintAndLog("Error: tag didn't answer to RALL"); topaz_switch_off_field(); return -1; @@ -553,8 +505,7 @@ int CmdHFTopazList(const char *Cmd) { static int CmdHelp(const char *Cmd); -static command_t CommandTable[] = -{ +static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"reader", CmdHFTopazReader, 0, "Act like a Topaz reader"}, {"sim", CmdHFTopazSim, 0, " -- Simulate Topaz tag"}, diff --git a/client/cmdhftopaz.h b/client/cmdhftopaz.h index 754f44070..e6ba1bdcb 100644 --- a/client/cmdhftopaz.h +++ b/client/cmdhftopaz.h @@ -11,6 +11,20 @@ #ifndef CMDHFTOPAZ_H__ #define CMDHFTOPAZ_H__ +#include +#include +#include +#include +#include "cmdmain.h" +#include "cmdparser.h" +#include "cmdhf14a.h" +#include "ui.h" +#include "mifare.h" +#include "proxmark3.h" +#include "crc16.h" +#include "protocols.h" +#include "cmdhf.h" + extern int CmdHFTopaz(const char *Cmd); extern int CmdHFTopazReader(const char *Cmd); extern int CmdHFTopazSim(const char *Cmd); diff --git a/client/mifarehost.h b/client/mifarehost.h index 4b8a9fd44..aa2b54843 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -23,7 +23,7 @@ #include "data.h" #include "util.h" #include "crapto1/crapto1.h" -#include "iso14443crc.h" +#include "crc16.h" #include "protocols.h" #include "mifare.h" #include "mfkey.h" diff --git a/client/scripting.c b/client/scripting.c index 629497adf..38ddc350d 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -227,21 +227,14 @@ static int l_CmdConsole(lua_State *L) { } static int l_iso15693_crc(lua_State *L) { - // uint16_t Iso15693Crc(uint8_t *v, int n); size_t size; const char *v = luaL_checklstring(L, 1, &size); // iceman, should be size / 2 ?!? - uint16_t retval = Iso15693Crc((uint8_t *) v, size); - lua_pushunsigned(L, retval); + lua_pushunsigned(L, crc( CRC_15693, (uint8_t *) v, size)); return 1; } static int l_iso14443b_crc(lua_State *L) { - /* void ComputeCrc14443(int CrcType, - const unsigned char *Data, int Length, - unsigned char *TransmitFirst, - unsigned char *TransmitSecond) - */ uint32_t tmp; unsigned char buf[USB_CMD_DATA_SIZE] = {0x00}; size_t size = 0; @@ -253,7 +246,7 @@ static int l_iso14443b_crc(lua_State *L) { } size /= 2; - ComputeCrc14443(CRC_14443_B, buf, size, &buf[size], &buf[size+1]); + compute_crc(CRC_14443_B, buf, size, &buf[size], &buf[size+1]); lua_pushlstring(L, (const char *)&buf, size+2); return 1; } @@ -397,6 +390,7 @@ static int l_crc16(lua_State *L) { size_t size; const char *p_str = luaL_checklstring(L, 1, &size); + //iceman tochange uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size); lua_pushunsigned(L, retval); return 1; diff --git a/client/scripting.h b/client/scripting.h index 2f0e9b5b7..feb611549 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -19,8 +19,6 @@ #include "cmdmain.h" #include "util.h" #include "mifarehost.h" -#include "iso15693tools.h" -#include "iso14443crc.h" #include "crc.h" #include "crc16.h" #include "crc64.h" diff --git a/client/util.c b/client/util.c index 55f9ed1d4..35cd0cba0 100644 --- a/client/util.c +++ b/client/util.c @@ -729,6 +729,14 @@ void rol(uint8_t *data, const size_t len){ data[len-1] = first; } +/* +uint8_t pw_rev_A(uint8_t b) { + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + return b; +} +*/ uint8_t reflect8(uint8_t b) { return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; } diff --git a/common/crc16.c b/common/crc16.c index e539f7472..8110d8045 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -24,14 +24,14 @@ void init_table(CrcType_t ct) { crc_type = ct; switch (ct) { - case CRC_14A: - case CRC_14B: - case CRC_15: - case CRC_15_ICLASS: generate_table(CRC16_POLY_CCITT, true); break; + case CRC_14443_A: + case CRC_14443_B: + case CRC_15693: + case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break; case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break; case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break; - case CRC_DNP: generate_table(CRC16_POLY_DNP, true); break; case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break; + case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break; default: crc_table_init = false; crc_type = CRC_NONE; @@ -97,7 +97,7 @@ uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bo return crc; } -// bit looped solution +// bit looped solution TODO REMOVED uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) { uint16_t i, v, tmp = 0; @@ -148,40 +148,88 @@ uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t pol void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) { - // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes) - if ( n < 3 ) return; + // can't calc a crc on less than 1 byte + if ( n == 0 ) return; init_table(ct); uint16_t crc = 0; switch (ct) { - case CRC_14A: crc = crc16_a(d, n); break; - case CRC_14B: - case CRC_15: crc = crc16_x25(d, n); break; - case CRC_15_ICLASS: crc = crc16_iclass(d, n); break; + case CRC_14443_A: crc = crc16_a(d, n); break; + case CRC_14443_B: + case CRC_15693: crc = crc16_x25(d, n); break; + case CRC_ICLASS: crc = crc16_iclass(d, n); break; case CRC_FELICA:crc = crc16_xmodem(d, n); break; //case CRC_LEGIC: - case CRC_DNP: crc = crc16_dnp(d, n); break; case CRC_CCITT: crc = crc16_ccitt(d, n); break; + case CRC_KERMIT: crc = crc16_kermit(d, n); break; default: break; } *first = (crc & 0xFF); *second = ((crc >> 8) & 0xFF); } +uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) { -//poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE" + // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes) + if ( n < 3 ) return 0; + + init_table(ct); + switch (ct) { + case CRC_14443_A: return crc16_a(d, n); + case CRC_14443_B: + case CRC_15693: return crc16_x25(d, n); + case CRC_ICLASS: return crc16_iclass(d, n); + case CRC_FELICA: return crc16_xmodem(d, n); + //case CRC_LEGIC: + case CRC_CCITT: return crc16_ccitt(d, n); + case CRC_KERMIT: return crc16_kermit(d, n); + default: break; + } + return 0; +} + +// check CRC +// ct crc type +// d buffer with data +// n length (including crc) +// +// This function uses the message + crc bytes in order to compare the "residue" afterwards. +// crc16 algos like CRC-A become 0x000 +// while CRC-15693 become 0x0F47 +// If calculated with crc bytes, the residue should be 0xF0B8 +bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { + + // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes) + if ( n < 3 ) return false; + + init_table(ct); + + switch (ct) { + case CRC_14443_A: return (crc16_a(d, n) == 0); + case CRC_14443_B: return (crc16_x25(d, n) == X25_CRC_CHECK); + case CRC_15693: return (crc16_x25(d, n) == X25_CRC_CHECK); + case CRC_ICLASS: return (crc16_iclass(d, n) == 0); + case CRC_FELICA: return (crc16_xmodem(d, n) == 0); + //case CRC_LEGIC: + case CRC_CCITT: return (crc16_ccitt(d, n) == 0); + default: break; + } + return false; +} + +// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE" uint16_t crc16_ccitt(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0xffff, false, false); } // FDX-B ISO11784/85) uses KERMIT -//poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT" +// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT" uint16_t crc16_kermit(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0x0000, true, true); } // FeliCa uses XMODEM -//poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM" +// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM" uint16_t crc16_xmodem(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0x0000, false, false); } @@ -190,14 +238,14 @@ uint16_t crc16_xmodem(uint8_t const *d, size_t n) { // ISO 15693, // ISO 14443 CRC-B // ISO/IEC 13239 (formerly ISO/IEC 3309) -//poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25" +// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25" uint16_t crc16_x25(uint8_t const *d, size_t n) { uint16_t crc = crc16_fast(d, n, 0xffff, true, true); crc = ~crc; return crc; } -// CRC-A (14443-3) -//poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A" +// CRC-A (14443-3) +// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A" uint16_t crc16_a(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0xC6C6, true, true); } @@ -216,20 +264,3 @@ uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) { uint16_t initial = uidcrc << 8 | uidcrc; return crc16_fast(d, n, initial, true, true); } - -// poly=0x3d65 init=0x0000 refin=true refout=true xorout=0xffff check=0xea82 name="CRC-16/DNP" -uint16_t crc16_dnp(uint8_t const *d, size_t n) { - uint16_t crc = crc16_fast(d, n, 0, true, true); - crc = ~crc; - return crc; -} - -// -----------------CHECK functions. -bool check_crc16_ccitt(uint8_t const *d, size_t n) { - if (n < 3) return false; - - uint16_t crc = crc16_ccitt(d, n - 2); - if ((( crc & 0xff ) == d[n-2]) && (( crc >> 8 ) == d[n-1])) - return true; - return false; -} \ No newline at end of file diff --git a/common/crc16.h b/common/crc16.h index a4face22d..e4c3abac2 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -16,47 +16,47 @@ #define CRC16_POLY_LEGIC 0xc6c6 //0x6363 #define CRC16_POLY_DNP 0x3d65 +#define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc + typedef enum { CRC_NONE, - CRC_14A, - CRC_14B, - CRC_15, - CRC_15_ICLASS, + CRC_14443_A, + CRC_14443_B, + CRC_15693, + CRC_ICLASS, CRC_FELICA, CRC_LEGIC, - CRC_DNP, CRC_CCITT, + CRC_KERMIT, } CrcType_t; uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ); uint16_t update_crc16(uint16_t crc, uint8_t c); uint16_t crc16(uint8_t const *message, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout); -// +uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n); void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second); +bool check_crc(CrcType_t ct, const uint8_t *d, size_t n); -// Calculate CRC-16/CCITT-FALSE checksum +// Calculate CRC-16/CCITT-FALSE uint16_t crc16_ccitt(uint8_t const *d, size_t n); -// Calculate CRC-16/KERMIT checksum +// Calculate CRC-16/KERMIT (FDX-B ISO11784/85) LF uint16_t crc16_kermit(uint8_t const *d, size_t n); -// Calculate CRC-16/XMODEM (FeliCa) checksum +// Calculate CRC-16/XMODEM (FeliCa) uint16_t crc16_xmodem(uint8_t const *d, size_t n); -// Calculate CRC-16/X25 (ISO15693, ISO14443 CRC-B,ISO/IEC 13239) checksum +// Calculate CRC-16/X25 (ISO15693, ISO14443 CRC-B,ISO/IEC 13239) uint16_t crc16_x25(uint8_t const *d, size_t n); -// Calculate CRC-16/CRC-A (ISO14443 CRC-A) checksum +// Calculate CRC-16/CRC-A (ISO14443 CRC-A) uint16_t crc16_a(uint8_t const *d, size_t n); -// Calculate CRC-16/iCLASS checksum +// Calculate CRC-16/iCLASS uint16_t crc16_iclass(uint8_t const *d, size_t n); -// Calculate CRC-16/DNP checksum -uint16_t crc16_dnp(uint8_t const *d, size_t n); - -// Calculate CRC-16/Legic checksum +// Calculate CRC-16/Legic // the initial_value is based on the previous legic_Crc8 of the UID. // ie: uidcrc = 0x78 then initial_value == 0x7878 uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc); @@ -67,7 +67,4 @@ void reset_table(void); void generate_table(uint16_t polynomial, bool refin); uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout); -//checks -bool check_crc16_ccitt(uint8_t const *d, size_t n); - -#endif +#endif \ No newline at end of file diff --git a/common/iso14443crc.c b/common/iso14443crc.c index a16d6cb34..01e77c855 100644 --- a/common/iso14443crc.c +++ b/common/iso14443crc.c @@ -8,6 +8,7 @@ #include "iso14443crc.h" + uint16_t UpdateCrc14443(uint8_t b, uint16_t *crc) { b = (b ^ (uint8_t)((*crc) & 0x00FF)); b = (b ^ (b << 4)); @@ -41,4 +42,4 @@ bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length) { if ((b1 == data[length - 2]) && (b2 == data[length - 1])) return true; return false; -} \ No newline at end of file +} diff --git a/common/iso14443crc.h b/common/iso14443crc.h index a9388d8cc..36c4be2f6 100644 --- a/common/iso14443crc.h +++ b/common/iso14443crc.h @@ -13,14 +13,7 @@ //----------------------------------------------------------------------------- // Routines to compute the CRCs (two different flavours, just for confusion) // required for ISO 14443, swiped directly from the spec. -//----------------------------------------------------------------------------- -#define CRC_14443_A 0x6363 /* ITU-V.41 */ -#define CRC_14443_B 0xFFFF /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ -#define CRC_ICLASS 0xE012 /* ICLASS PREFIX */ uint16_t UpdateCrc14443(uint8_t b, uint16_t *crc); -void ComputeCrc14443(uint16_t CrcType, const uint8_t *data, int length, - uint8_t *TransmitFirst, uint8_t *TransmitSecond); -bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length); #endif diff --git a/common/iso15693tools.c b/common/iso15693tools.c index 42937e5a8..1d959b143 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -3,35 +3,10 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// ISO15693 CRC & other commons +// ISO15693 other commons //----------------------------------------------------------------------------- #include "iso15693tools.h" -// The CRC as described in ISO 15693-Part 3-Annex C -uint16_t Iso15693Crc(uint8_t *d, size_t n){ - init_table(CRC_15); - return crc16_x25(d, n); -} - -// adds a CRC to a dataframe -// d[] iso15963 frame without crc -// n length without crc -// returns the new length of the dataframe. -int Iso15693AddCrc(uint8_t *d, size_t n) { - uint16_t crc = Iso15693Crc(d, n); - d[n] = crc & 0xff; - d[n+1] = crc >> 8; - return n + 2; -} - -// check the CRC as described in ISO 15693-Part 3-Annex C -// v buffer with data -// n length (including crc) -// If calculated with crc bytes, the residue should be 0xF0B8 -bool Iso15693CheckCrc(uint8_t *d, size_t n) { - return (Iso15693Crc(d, n) == ISO15_CRC_CHECK ); -} - int sprintf(char *str, const char *format, ...); // returns a string representation of the UID diff --git a/common/iso15693tools.h b/common/iso15693tools.h index ebb4f047a..4f3532a08 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -1,5 +1,6 @@ // ISO15693 commons // Adrian Dabrowski 2010 and others, GPLv2 +// Christian Herrmann 2018 #ifndef ISO15693_H__ #define ISO15693_H__ @@ -9,11 +10,6 @@ #include #include "crc16.h" -// ISO15693 CRC -#define ISO15_CRC_PRESET (uint16_t)0xFFFF -#define ISO15_CRC_POLY (uint16_t)0x8408 -#define ISO15_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc - // REQUEST FLAGS #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK) @@ -71,13 +67,8 @@ #define ISO15_CMD_SYSINFO 0x2B #define ISO15_CMD_SECSTATUS 0x2C - -uint16_t Iso15693Crc(uint8_t *d, size_t n); -int Iso15693AddCrc(uint8_t *d, size_t n); -bool Iso15693CheckCrc(uint8_t *d, size_t n); char* Iso15693sprintUID(char *target, uint8_t *uid); - //----------------------------------------------------------------------------- // Map a sequence of octets (~layer 2 command) into the set of bits to feed // to the FPGA, to transmit that command to the tag.