mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-30 11:39:14 -07:00
CHG: refactor CRC16 algos. This is a big change, most likely some parts broke, hard to test it all.
This commit is contained in:
parent
d2e9f4a743
commit
52d69ed4ee
35 changed files with 512 additions and 674 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
AddCrc14A(res, end_crc_pos);
|
||||
end_crc_pos = crc_pos + 2;
|
||||
AppendCrc14443a (res, end_crc_pos);
|
||||
|
||||
//
|
||||
|
||||
|
||||
|
|
160
armsrc/iclass.c
160
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,8 +1250,8 @@ 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
|
||||
|
@ -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,14 +1410,43 @@ 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
|
||||
} 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
|
||||
|
@ -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
|
||||
|
@ -1572,7 +1566,7 @@ send:
|
|||
**/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1830,8 +1824,6 @@ void setupIclassReader() {
|
|||
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
|
||||
|
|
|
@ -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,11 +1417,15 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1632,6 +1633,9 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
|
|||
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++;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,6 +453,10 @@ 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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -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;
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) return 3;
|
||||
|
||||
if (card) {
|
||||
card->uidlen = 8;
|
||||
|
@ -1253,9 +1247,6 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) {
|
|||
// 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));
|
||||
GetTagSamplesFor14443bDemod(); //select_card
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)), )
|
||||
|
|
|
@ -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)));
|
||||
// input from commandline
|
||||
PrintAndLog("CCITT | %X (29B1 expected)", crc(CRC_CCITT, 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");
|
||||
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);
|
||||
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)));
|
||||
|
||||
uint8_t 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;
|
||||
|
||||
// 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" );
|
||||
|
||||
// 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);
|
||||
|
||||
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);
|
||||
// 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" );
|
||||
|
||||
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);
|
||||
// 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");
|
||||
|
||||
// 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");
|
||||
|
||||
// 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);
|
||||
// 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");
|
||||
|
||||
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);
|
||||
// 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");
|
||||
|
||||
//return 0;
|
||||
|
||||
// 16bit test
|
||||
uint8_t md;
|
||||
uint32_t mb, mc;
|
||||
|
||||
// reflect
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
mb = rand();
|
||||
reflect(mb, 16);
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks reflect %" PRIu64 "\n", t1);
|
||||
|
||||
// reflect16
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
mc = rand();
|
||||
reflect16(mc);
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks reflect16 %" PRIu64 "\n", t1);
|
||||
//---------------------------------------------------------
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -914,9 +914,9 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
|||
if (crc && datalen>0 && datalen<sizeof(data)-2) {
|
||||
uint8_t first, second;
|
||||
if (topazmode) {
|
||||
ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
|
||||
compute_crc(CRC_14443_B, data, datalen, &first, &second);
|
||||
} else {
|
||||
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
|
||||
compute_crc(CRC_14443_A, data, datalen, &first, &second);
|
||||
}
|
||||
data[datalen++] = first;
|
||||
data[datalen++] = second;
|
||||
|
|
|
@ -806,7 +806,6 @@ int srix4kValid(const char *Cmd){
|
|||
bool waitCmd14b(bool verbose) {
|
||||
|
||||
bool crc = false;
|
||||
uint8_t b1 = 0, b2 = 0;
|
||||
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
|
||||
uint8_t status = 0;
|
||||
uint16_t len = 0;
|
||||
|
@ -823,8 +822,7 @@ bool waitCmd14b(bool verbose) {
|
|||
|
||||
if (verbose) {
|
||||
if ( len >= 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,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "iso14443crc.h"
|
||||
#include "crc16.h"
|
||||
#include "proxmark3.h"
|
||||
#include "data.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||
// Modified 2010-2012 by <adrian -at- atrox.at>
|
||||
// Modified 2012 by <vsza at vsza.hu>
|
||||
// Modfified 2018 by <iceman>
|
||||
//
|
||||
// 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);
|
||||
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] <milliseconds> [-b] <number of bits> <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 && datalen<sizeof(data)-2) {
|
||||
uint8_t first, second;
|
||||
ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
|
||||
data[datalen++] = first;
|
||||
data[datalen++] = second;
|
||||
if (crc && datalen>0 && 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;
|
||||
}
|
||||
|
||||
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)
|
||||
c.arg[0] |= FELICA_NO_SELECT;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -7,21 +7,8 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// High frequency Topaz (NFC Type 1) commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// 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, "<UID> -- Simulate Topaz tag"},
|
||||
|
|
|
@ -11,6 +11,20 @@
|
|||
#ifndef CMDHFTOPAZ_H__
|
||||
#define CMDHFTOPAZ_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
101
common/crc16.c
101
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"
|
||||
// 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;
|
||||
}
|
|
@ -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
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue