From 3ac22ee1cf91686111aea2a4bb85d9f2b94ec1fe Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 23 Jul 2015 01:12:02 -0400 Subject: [PATCH] use read instead of readcheck except to auth --- armsrc/appmain.c | 13 ++++-- armsrc/apps.h | 11 +++-- armsrc/iclass.c | 88 ++++++++++++++++++++---------------- client/cmdhficlass.c | 29 +++++++----- client/hid-flasher/usb_cmd.h | 1 + client/lualibs/commands.lua | 1 + include/usb_cmd.h | 1 + 7 files changed, 82 insertions(+), 62 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 3c22fbb1..994bfa6c 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1080,19 +1080,22 @@ void UsbPacketReceived(uint8_t *packet, int len) emlSet(c->d.asBytes,c->arg[0], c->arg[1]); break; case CMD_ICLASS_WRITEBLOCK: - iClass_WriteBlock(c->arg[0], c->arg[1], c->d.asBytes); + iClass_WriteBlock(c->arg[0], c->d.asBytes); + break; + case CMD_ICLASS_READCHECK: // auth step 1 + iClass_ReadCheck(c->arg[0], c->arg[1]); break; case CMD_ICLASS_READBLOCK: - iClass_ReadBlk(c->arg[0], c->arg[1]); + iClass_ReadBlk(c->arg[0]); break; - case CMD_ICLASS_AUTHENTICATION: + case CMD_ICLASS_AUTHENTICATION: //check iClass_Authentication(c->d.asBytes); break; case CMD_ICLASS_DUMP: - iClass_Dump(c->arg[0], c->arg[1], c->arg[2]); + iClass_Dump(c->arg[0], c->arg[1]); break; case CMD_ICLASS_CLONE: - iClass_Clone(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes); break; #endif diff --git a/armsrc/apps.h b/armsrc/apps.h index 868df266..63b2edc5 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -166,11 +166,12 @@ 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_WriteBlock(uint8_t blockNo, uint8_t keyType, uint8_t *data); -void iClass_ReadBlk(uint8_t blockNo, uint8_t keyType); -bool iClass_ReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *readdata); -void iClass_Dump(uint8_t blockno, uint8_t numblks, uint8_t keyType); -void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t keyType, uint8_t *data); +void iClass_WriteBlock(uint8_t blockNo, uint8_t *data); +void iClass_ReadBlk(uint8_t blockNo); +bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata); +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); // hitag2.h void SnoopHitag(uint32_t type); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 9a70c06b..4e4854ca 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1769,8 +1769,8 @@ void ReaderIClass(uint8_t arg0) { } LED_B_OFF(); } - cmd_send(CMD_ACK,0,0,0,card_data, 0); - LED_A_OFF(); + cmd_send(CMD_ACK,0,0,0,card_data, 0); + LED_A_OFF(); } void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { @@ -1911,51 +1911,63 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { LED_A_OFF(); } +void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType) { + uint8_t readcheck[] = { keyType, blockNo }; + uint8_t resp[] = {0,0,0,0,0,0,0,0}; + size_t isOK = 0; + isOK = sendCmdGetResponseWithRetries(readcheck, sizeof(readcheck), resp, sizeof(resp), 6); + cmd_send(CMD_ACK,isOK,0,0,0,0); +} + void iClass_Authentication(uint8_t *MAC) { - uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t resp[ICLASS_BUFFER_SIZE]; memcpy(check+5,MAC,4); bool isOK; - isOK = sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5); + isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); cmd_send(CMD_ACK,isOK,0,0,0,0); } -bool iClass_ReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *readdata) { - uint8_t readcmd[] = {keyType, blockNo}; //0x88, 0x00 - uint8_t resp[8]; - size_t isOK = 1; +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? + char bl = blockNo; + uint16_t rdCrc = iclass_crc16(&bl, 1); + readcmd[2] = rdCrc >> 8; + readcmd[3] = rdCrc & 0xff; + uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; + bool isOK = false; - readcmd[1] = blockNo; - isOK = sendCmdGetResponseWithRetries(readcmd, sizeof(readcmd),resp, 8, 5); - memcpy(readdata,resp,sizeof(resp)); + //readcmd[1] = blockNo; + isOK = sendCmdGetResponseWithRetries(readcmd, sizeof(readcmd), resp, 10, 10); + memcpy(readdata, resp, sizeof(resp)); return isOK; } -void iClass_ReadBlk(uint8_t blockno, uint8_t keyType) { - uint8_t readblockdata[8]; +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, keyType, readblockdata); - cmd_send(CMD_ACK,isOK,0,0,readblockdata,8); + isOK = iClass_ReadBlock(blockno, readblockdata); + cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8); } -void iClass_Dump(uint8_t blockno, uint8_t numblks, uint8_t keyType) { - uint8_t readblockdata[8]; +void iClass_Dump(uint8_t blockno, uint8_t numblks) { + uint8_t readblockdata[] = {0,0,0,0,0,0,0,0,0,0}; bool isOK = false; uint8_t blkCnt = 0; BigBuf_free(); uint8_t *dataout = BigBuf_malloc(255*8); - memset(dataout,0xFF,255*8); if (dataout == NULL){ Dbprintf("out of memory"); OnError(1); return; } + memset(dataout,0xFF,255*8); for (;blkCnt < numblks; blkCnt++) { - isOK = iClass_ReadBlock(blockno+blkCnt, keyType, readblockdata); - if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0x33 || readblockdata[2] == 0xBB)) { //try again - isOK = iClass_ReadBlock(blockno+blkCnt, keyType, readblockdata); + isOK = iClass_ReadBlock(blockno+blkCnt, readblockdata); + if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0xBB || readblockdata[2] == 0xBB)) { //try again + isOK = iClass_ReadBlock(blockno+blkCnt, readblockdata); if (!isOK) { Dbprintf("Block %02X failed to read", blkCnt+blockno); break; @@ -1970,30 +1982,26 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks, uint8_t keyType) { BigBuf_free(); } -bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t keyType, uint8_t *data) { - uint8_t write[] = { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t readblockdata[8]; - write[1] = blockNo; +bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) { + uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + //uint8_t readblockdata[10]; + //write[1] = blockNo; memcpy(write+2, data, 12); // data + mac - uint8_t resp[10]; + uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; bool isOK; - isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),5); - if (isOK) { - isOK = iClass_ReadBlock(blockNo, keyType, readblockdata); - //try again - if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0xBB || readblockdata[2] == 0xBB)) - isOK = iClass_ReadBlock(blockNo, keyType, readblockdata); - } + isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10); if (isOK) { - if (memcmp(write+2,readblockdata,sizeof(readblockdata)) != 0){ - isOK=false; + //Dbprintf("WriteResp: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]); + if (memcmp(write+2,resp,8)) { + //error try again + isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10); } } return isOK; } -void iClass_WriteBlock(uint8_t blockNo, uint8_t keyType, uint8_t *data) { - bool isOK = iClass_WriteBlock_ext(blockNo, keyType, data); +void iClass_WriteBlock(uint8_t blockNo, uint8_t *data) { + bool isOK = iClass_WriteBlock_ext(blockNo, data); if (isOK){ Dbprintf("Write block [%02x] successful",blockNo); } else { @@ -2002,17 +2010,17 @@ void iClass_WriteBlock(uint8_t blockNo, uint8_t keyType, uint8_t *data) { cmd_send(CMD_ACK,isOK,0,0,0,0); } -void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t keyType, uint8_t *data) { +void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) { int i; int written = 0; int total_block = (endblock - startblock) + 1; for (i = 0; i < total_block;i++){ // block number - if (iClass_WriteBlock_ext(i+startblock, keyType, data+(i*12))){ + if (iClass_WriteBlock_ext(i+startblock, data+(i*12))){ Dbprintf("Write block [%02x] successful",i + startblock); written++; } else { - if (iClass_WriteBlock_ext(i+startblock, keyType, data+(i*12))){ + if (iClass_WriteBlock_ext(i+startblock, data+(i*12))){ Dbprintf("Write block [%02x] successful",i + startblock); written++; } else { diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 605793a5..ace50698 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -472,7 +472,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v UsbCommand resp; UsbCommand c = {CMD_READER_ICLASS, {0}}; - c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_CC; + c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_ONE_TRY; if (use_credit_key) c.arg[0] |= FLAG_ICLASS_READER_CEDITKEY; @@ -651,6 +651,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLog("Command execute timeout"); + ul_switch_off_field(); return 0; } uint8_t readStatus = resp.arg[0] & 0xff; @@ -658,6 +659,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { if(readStatus == 0){ PrintAndLog("No tag found..."); + ul_switch_off_field(); return 0; } if( readStatus & (FLAG_ICLASS_READER_CSN|FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_CC)){ @@ -673,6 +675,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { } if (numblks > maxBlk) numblks = maxBlk; } + ul_switch_off_field(); // authenticate debit key and get div_key - later store in dump block 3 if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, false)){ //try twice - for some reason it sometimes fails the first time... @@ -683,17 +686,19 @@ int CmdHFiClassReader_Dump(const char *Cmd) { } // begin dump - UsbCommand w = {CMD_ICLASS_DUMP, {blockno, numblks-blockno+1, 0x88}}; + UsbCommand w = {CMD_ICLASS_DUMP, {blockno, numblks-blockno+1}}; clearCommandBuffer(); SendCommand(&w); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLog("Command execute time-out 1"); + ul_switch_off_field(); return 1; } uint32_t blocksRead = resp.arg[1]; uint8_t isOK = resp.arg[0] & 0xff; if (!isOK && !blocksRead) { PrintAndLog("Read Block Failed"); + ul_switch_off_field(); return 0; } uint32_t startindex = resp.arg[2]; @@ -724,17 +729,18 @@ int CmdHFiClassReader_Dump(const char *Cmd) { // setup dump and start w.arg[0] = blockno + blocksRead; w.arg[1] = maxBlk - (blockno + blocksRead); - w.arg[2] = 0x18; clearCommandBuffer(); SendCommand(&w); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLog("Command execute timeout 2"); + ul_switch_off_field(); return 0; } uint8_t isOK = resp.arg[0] & 0xff; blocksRead = resp.arg[1]; if (!isOK && !blocksRead) { PrintAndLog("Read Block Failed 2"); + ul_switch_off_field(); return 0; } @@ -776,16 +782,15 @@ int CmdHFiClassReader_Dump(const char *Cmd) { static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool verbose) { uint8_t MAC[4]={0x00,0x00,0x00,0x00}; uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t keyType = (use_credit_key) ? 0x18 : 0x88; if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, verbose)) return 0; UsbCommand resp; Calc_wb_mac(blockno,bldata,div_key,MAC); - UsbCommand w = {CMD_ICLASS_WRITEBLOCK, {blockno, keyType}}; + UsbCommand w = {CMD_ICLASS_WRITEBLOCK, {blockno}}; memcpy(w.d.asBytes, bldata, 8); - memcpy(w.d.asBytes + 8,MAC, 4); + memcpy(w.d.asBytes + 8, MAC, 4); clearCommandBuffer(); SendCommand(&w); @@ -800,7 +805,6 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c return 0; } PrintAndLog("Write Block Successful"); - return 1; } @@ -820,7 +824,7 @@ int usage_hf_iclass_writeblock(void) { int CmdHFiClass_WriteBlock(const char *Cmd) { uint8_t blockno=0; - uint8_t bldata[8]={0}; + uint8_t bldata[8]={0,0,0,0,0,0,0,0}; uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t keyNbr = 0; uint8_t dataLen = 0; @@ -891,8 +895,9 @@ int CmdHFiClass_WriteBlock(const char *Cmd) { } if (cmdp < 6) return usage_hf_iclass_writeblock(); - - return WriteBlock(blockno, bldata, KEY, use_credit_key, elite, true); + int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, true); + ul_switch_off_field(); + return ans; } int usage_hf_iclass_clone(void) { @@ -1027,7 +1032,7 @@ int CmdHFiClassCloneTag(const char *Cmd) { if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, true)) return 0; - UsbCommand w = {CMD_ICLASS_CLONE,{startblock,endblock,((use_credit_key) ? 0x18 : 0x88)}}; + UsbCommand w = {CMD_ICLASS_CLONE,{startblock,endblock}}; uint8_t *ptr; // calculate all mac for every the block we will write for (i = startblock; i <= endblock; i++){ @@ -1065,7 +1070,7 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, return 0; UsbCommand resp; - UsbCommand w = {CMD_ICLASS_READBLOCK, {blockno, keyType}}; + UsbCommand w = {CMD_ICLASS_READBLOCK, {blockno}}; clearCommandBuffer(); SendCommand(&w); if (!WaitForResponseTimeout(CMD_ACK,&resp,4500)) diff --git a/client/hid-flasher/usb_cmd.h b/client/hid-flasher/usb_cmd.h index e9474a77..2f521f62 100644 --- a/client/hid-flasher/usb_cmd.h +++ b/client/hid-flasher/usb_cmd.h @@ -115,6 +115,7 @@ typedef struct { #define CMD_WRITER_LEGIC_RF 0x0389 #define CMD_EPA_PACE_COLLECT_NONCE 0x038A +#define CMD_ICLASS_READCHECK 0x038F #define CMD_ICLASS_CLONE 0x0390 #define CMD_ICLASS_DUMP 0x0391 #define CMD_SNOOP_ICLASS 0x0392 diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index dab2e630..4e98bd28 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -87,6 +87,7 @@ local _commands = { CMD_EPA_PACE_COLLECT_NONCE = 0x038A, --//CMD_EPA_ = 0x038B, + CMD_ICLASS_READCHECK = 0x038F, CMD_ICLASS_CLONE = 0x0390, CMD_ICLASS_DUMP = 0x0391, CMD_SNOOP_ICLASS = 0x0392, diff --git a/include/usb_cmd.h b/include/usb_cmd.h index ef604102..3afed7c3 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -129,6 +129,7 @@ typedef struct{ #define CMD_EPA_PACE_COLLECT_NONCE 0x038A #define CMD_EPA_PACE_REPLAY 0x038B +#define CMD_ICLASS_READCHECK 0x038F #define CMD_ICLASS_CLONE 0x0390 #define CMD_ICLASS_DUMP 0x0391 #define CMD_SNOOP_ICLASS 0x0392 -- 2.39.2