From: iceman1001 Date: Tue, 10 Feb 2015 20:53:16 +0000 (+0100) Subject: Merge branch 'master' of https://github.com/Proxmark/proxmark3 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/4ecde0e1ff60d5e3d217dc1e5ca12c78864804cc Merge branch 'master' of https://github.com/Proxmark/proxmark3 Conflicts: armsrc/appmain.c armsrc/iclass.c --- 4ecde0e1ff60d5e3d217dc1e5ca12c78864804cc diff --cc armsrc/appmain.c index 31e17e88,43f1df02..f19840b8 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@@ -21,9 -21,10 +21,9 @@@ #include #include "legicrf.h" -#include +#include "../include/hitag2.h" #include "lfsampling.h" - + #include "BigBuf.h" #ifdef WITH_LCD #include "LCD.h" #endif diff --cc armsrc/hitag2.c index f9005c71,4b173d6f..2d064565 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@@ -16,11 -16,12 +16,12 @@@ // (c) 2012 Roel Verdult //----------------------------------------------------------------------------- -#include "proxmark3.h" +#include "../include/proxmark3.h" #include "apps.h" #include "util.h" -#include "hitag2.h" +#include "../include/hitag2.h" #include "string.h" + #include "BigBuf.h" static bool bQuiet; diff --cc armsrc/iclass.c index c0edc1e0,41c9b8b5..67130804 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@@ -654,12 -652,11 +654,11 @@@ void RAMFUNC SnoopIClass(void // The DMA buffer, used to stream samples from the FPGA uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); - // reset traceLen to 0 - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); + set_tracing(TRUE); + clear_trace(); iso14a_set_trigger(FALSE); - int lastRxCounter; + int lastRxCounter; uint8_t *upTo; int smpl; int maxBehindBy = 0; diff --cc client/cmdlft55xx.c index c023d57f,a719c7ad..b6b5ea44 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@@ -18,533 -17,124 +18,519 @@@ #include "cmddata.h" #include "cmdlf.h" #include "cmdlft55xx.h" +#include "util.h" +#include "data.h" +#include "lfdemod.h" - -static int CmdHelp(const char *Cmd); +#define LF_TRACE_BUFF_SIZE 20000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) +#define LF_BITSSTREAM_LEN 1000 // more then 1000 bits shouldn't happend.. 8block * 4 bytes * 8bits = - static int CmdHelp(const char *Cmd); + - // int CmdReadBlk(const char *Cmd) - // { - // int block = -1; - // sscanf(Cmd, "%d", &block); - - // if ((block > 7) | (block < 0)) { - // PrintAndLog("Block must be between 0 and 7"); - // return 1; - // } - - // UsbCommand c; - // c.cmd = CMD_T55XX_READ_BLOCK; - // c.d.asBytes[0] = 0x00; - // c.arg[0] = 0; - // c.arg[1] = block; - // c.arg[2] = 0; - // SendCommand(&c); - // WaitForResponse(CMD_ACK, NULL); - - // uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - - // GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset.. - // WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - // for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - // GraphBuffer[j] = (int)data[j]; - // } - // GraphTraceLen = LF_TRACE_BUFF_SIZE; - // ManchesterDemod(block); - // RepaintGraphWindow(); - // return 0; - // } ++int usage_t55xx_rd(){ ++ PrintAndLog("Usage: lf t55xx rd "); ++ PrintAndLog(" , block number to read. Between 0-7"); ++ PrintAndLog(" , OPTIONAL password (8 hex characters)"); ++ PrintAndLog(""); ++ PrintAndLog(" sample: lf t55xx rd 0 = try reading data from block 0"); ++ PrintAndLog(" : lf t55xx rd 0 feedbeef = try reading data from block 0 using password"); ++ PrintAndLog(""); ++ return 0; ++} ++int usage_t55xx_wr(){ ++ PrintAndLog("Usage: lf t55xx wr [password]"); ++ PrintAndLog(" , block number to read. Between 0-7"); ++ PrintAndLog(" , 4 bytes of data to write (8 hex characters)"); ++ PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)"); ++ PrintAndLog(""); ++ PrintAndLog(" sample: lf t55xx wd 3 11223344 = try writing data 11223344 to block 3"); ++ PrintAndLog(" : lf t55xx wd 3 11223344 feedbeef = try writing data 11223344 to block 3 using password feedbeef"); ++ PrintAndLog(""); ++ return 0; ++} ++int usage_t55xx_trace() { ++ PrintAndLog("Usage: lf t55xx trace [graph buffer data]"); ++ PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); ++ PrintAndLog(""); ++ PrintAndLog(" sample: lf t55xx trace"); ++ PrintAndLog(" : lf t55xx trace 1"); ++ PrintAndLog(""); ++ return 0; ++} ++int usage_t55xx_info() { ++ PrintAndLog("Usage: lf t55xx info [graph buffer data]"); ++ PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); ++ PrintAndLog(""); ++ PrintAndLog(" sample: lf t55xx info"); ++ PrintAndLog(" : lf t55xx info 1"); ++ PrintAndLog(""); ++ return 0; ++} + ++int usage_t55xx_dump(){ ++ PrintAndLog("Usage: lf t55xx dump "); ++ PrintAndLog(" , OPTIONAL password 4bytes (8 hex characters)"); ++ PrintAndLog(""); ++ PrintAndLog(" sample: lf t55xx dump"); ++ PrintAndLog(" : lf t55xx dump feedbeef"); ++ PrintAndLog(""); ++ return 0; ++} ++static int CmdHelp(const char *Cmd); int CmdReadBlk(const char *Cmd) { - int Block = 8; //default to invalid block - UsbCommand c; + int invert = 0; + int clk = 0; + int block = -1; ++ int password = 0xFFFFFFFF; //default to blank Block 7 + int errCnt; + size_t bitlen; - //int decodedBitlen; ++ int maxErr = 100; ++ uint8_t askAmp = 0; + uint32_t blockData; + uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00}; + - sscanf(Cmd, "%d", &block); + - if ((block > 7) | (block < 0)) { ++ char cmdp = param_getchar(Cmd, 0); ++ if (cmdp == 'h' || cmdp == 'H') { ++ usage_t55xx_rd(); ++ return 0; ++ } + - sscanf(Cmd, "%d", &Block); ++ int res = sscanf(Cmd, "%d %x", &block, &password); + - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } ++ if ( res < 1 || res > 2 ){ ++ usage_t55xx_rd(); ++ return 1; ++ } ++ ++ if ((block < 0) | (block > 7)) { + PrintAndLog("Block must be between 0 and 7"); + return 1; ++ } + - PrintAndLog("Reading block %d", Block); ++ UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}}; ++ c.d.asBytes[0] = 0x0; + - c.cmd = CMD_T55XX_READ_BLOCK; - c.d.asBytes[0] = 0x0; //Normal mode - c.arg[0] = 0; - c.arg[1] = Block; - c.arg[2] = 0; - SendCommand(&c); - return 0; -} ++ //Password mode ++ if ( res == 2 ) { ++ c.arg[2] = password; ++ c.d.asBytes[0] = 0x1; + } - UsbCommand c = { CMD_T55XX_READ_BLOCK, { 0, block, 0 } }; -int CmdReadBlkPWD(const char *Cmd) -{ - int Block = 8; //default to invalid block - int Password = 0xFFFFFFFF; //default to blank Block 7 - UsbCommand c; + SendCommand(&c); + if ( !WaitForResponseTimeout(CMD_ACK,NULL,1500) ) { + PrintAndLog("command execution time out"); + return 2; + } + + CmdSamples("12000"); - sscanf(Cmd, "%d %x", &Block, &Password); + bitlen = getFromGraphBuf(bits); + - errCnt = askrawdemod(bits, &bitlen, &clk, &invert); ++ errCnt = askrawdemod(bits, &bitlen, &clk, &invert, maxErr, askAmp); + + //throw away static - allow 1 and -1 (in case of threshold command first) + if ( errCnt == -1 || bitlen < 16 ){ + PrintAndLog("no data found"); + if (g_debugMode) + PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt, bitlen, clk, invert); + return 3; + } + if (g_debugMode) + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, bitlen); - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + //move bits back to DemodBuffer + setDemodBuf(bits, bitlen, 0); + printBitStream(bits,bitlen); + + // bits has the manchester encoded data. + errCnt = manrawdecode(bits, &bitlen); + if ( errCnt == -1 || bitlen < 16 ){ + PrintAndLog("no data found"); + if (g_debugMode) + PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt, bitlen, clk, invert); + return 4; + } - PrintAndLog("Reading block %d with password %08X", Block, Password); + blockData = PackBits(0, 32, bits); - c.cmd = CMD_T55XX_READ_BLOCK; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = 0; - c.arg[1] = Block; - c.arg[2] = Password; - SendCommand(&c); - return 0; + if ( block < 0) + PrintAndLog(" Decoded : 0x%08X %s", blockData, sprint_bin(bits,32) ); + else + PrintAndLog(" Block %d : 0x%08X %s", block, blockData, sprint_bin(bits,32) ); + + return 0; } - int CmdReadBlkPWD(const char *Cmd) + int CmdWriteBlk(const char *Cmd) { - int Block = -1; //default to invalid block - int Password = 0xFFFFFFFF; //default to blank Block 7 - - - sscanf(Cmd, "%d %x", &Block, &Password); - int Block = 8; //default to invalid block - int Data = 0xFFFFFFFF; //default to blank Block - UsbCommand c; ++ int block = 8; //default to invalid block ++ int data = 0xFFFFFFFF; //default to blank Block ++ int password = 0xFFFFFFFF; //default to blank Block 7 ++ ++ char cmdp = param_getchar(Cmd, 0); ++ if (cmdp == 'h' || cmdp == 'H') { ++ usage_t55xx_wr(); ++ return 0; ++ } ++ ++ int res = sscanf(Cmd, "%d %x %x",&block, &data, &password); ++ ++ if ( res < 2 || res > 3) { ++ usage_t55xx_wr(); ++ return 1; ++ } - if ((Block > 7) | (Block < 0)) { - sscanf(Cmd, "%x %d", &Data, &Block); ++ if (block > 7) { + PrintAndLog("Block must be between 0 and 7"); + return 1; - } - - PrintAndLog("Reading page 0 block %d pwd %08X", Block, Password); - - UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, Block, Password} }; - c.d.asBytes[0] = 0x1; //Password mode - SendCommand(&c); - WaitForResponse(CMD_ACK, NULL); - - uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]); + } - GraphTraceLen = LF_TRACE_BUFF_SIZE; - ManchesterDemod(Block); - - RepaintGraphWindow(); - return 0; - } - - int CmdWriteBlk(const char *Cmd) - { - int Block = 8; //default to invalid block - int Data = 0xFFFFFFFF; //default to blank Block - - sscanf(Cmd, "%d %x", &Block, &Data); - - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } - - PrintAndLog("Writing block %d data %08X", Block, Data); - - UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {Data, Block, 0}}; - c.d.asBytes[0] = 0x0; //Normal mode - SendCommand(&c); - return 0; - } - - int CmdWriteBlkPWD(const char *Cmd) - { - int Block = 8; //default to invalid block - int Data = 0xFFFFFFFF; //default to blank Block - int Password = 0xFFFFFFFF; //default to blank Block 7 - - - sscanf(Cmd, "%d %x %x",&Block, &Data, &Password); - - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } - - PrintAndLog("Writing block %d data %08X password %08X", Block, Data, Password); - - UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {Data, Block, Password}}; - c.d.asBytes[0] = 0x1; //Password mode - SendCommand(&c); - return 0; ++ ++ UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}}; ++ c.d.asBytes[0] = 0x0; + - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } ++ if (res == 2) { ++ PrintAndLog("Writing block %d data %08X", block, data); ++ } else { ++ //Password mode ++ c.arg[2] = password; ++ c.d.asBytes[0] = 0x1; ++ PrintAndLog("Writing block %d data %08X password %08X", block, data, password); ++ } ++ ++ SendCommand(&c); ++ return 0; +} + +int CmdReadTrace(const char *Cmd) +{ + char cmdp = param_getchar(Cmd, 0); + + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf t55xx trace [use data from Graphbuffer]"); - PrintAndLog(" [use data from Graphbuffer], if not set, try reading data from tag."); - PrintAndLog(""); - PrintAndLog(" sample: lf t55xx trace"); - PrintAndLog(" : lf t55xx trace 1"); ++ usage_t55xx_trace(); + return 0; + } + + if ( strlen(Cmd)==0){ + + UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}}; + SendCommand(&c); + WaitForResponse(CMD_ACK, NULL); - PrintAndLog("Writting block %d with data %08X", Block, Data); + uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - c.cmd = CMD_T55XX_WRITE_BLOCK; - c.d.asBytes[0] = 0x0; //Normal mode - c.arg[0] = Data; - c.arg[1] = Block; - c.arg[2] = 0; - SendCommand(&c); + GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset.. + WaitForResponseTimeout(CMD_ACK,NULL, 1500); + + for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { + GraphBuffer[j] = ((int)data[j]); + } + GraphTraceLen = LF_TRACE_BUFF_SIZE; + } + + uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; + uint8_t * bitstream = bits; + + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream, LF_BITSSTREAM_LEN); + RepaintGraphWindow(); + + uint8_t si = 5; + uint32_t bl0 = PackBits(si, 32, bitstream); + uint32_t bl1 = PackBits(si+32, 32, bitstream); + + uint32_t acl = PackBits(si, 8, bitstream); si += 8; + uint32_t mfc = PackBits(si, 8, bitstream); si += 8; + uint32_t cid = PackBits(si, 5, bitstream); si += 5; + uint32_t icr = PackBits(si, 3, bitstream); si += 3; + uint32_t year = PackBits(si, 4, bitstream); si += 4; + uint32_t quarter = PackBits(si, 2, bitstream); si += 2; + uint32_t lotid = PackBits(si, 12, bitstream); si += 12; + uint32_t wafer = PackBits(si, 5, bitstream); si += 5; + uint32_t dw = PackBits(si, 15, bitstream); + + PrintAndLog(""); + PrintAndLog("-- T55xx Trace Information ----------------------------------"); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl); + PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d)", mfc, mfc); + PrintAndLog(" CID : 0x%02X (%d)", cid, cid); + PrintAndLog(" ICR IC Revision : %d",icr ); + PrintAndLog(" Manufactured"); + PrintAndLog(" Year/Quarter : %d/%d",2000+year, quarter ); + PrintAndLog(" Lot ID : %d", lotid ); + PrintAndLog(" Wafer number : %d", wafer); + PrintAndLog(" Die Number : %d", dw); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Raw Data - Page 1"); + PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(bitstream+5,32) ); + PrintAndLog(" Block 0 : 0x%08X %s", bl1, sprint_bin(bitstream+37,32) ); + PrintAndLog("-------------------------------------------------------------"); + /* + TRACE - BLOCK O + Bits Definition HEX + 1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0 + 9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation + 17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2 + 22-24 ICR IC revision + 25-28 YEAR (BCD encoded) 9 (= 2009) + 29-30 QUARTER 1,2,3,4 + 31-32 LOT ID + + TRACE - BLOCK 1 + 1-12 LOT ID + 13-17 Wafer number + 18-32 DW, die number sequential + */ + return 0; } -int CmdWriteBlkPWD(const char *Cmd) -{ - int Block = 8; //default to invalid block - int Data = 0xFFFFFFFF; //default to blank Block - int Password = 0xFFFFFFFF; //default to blank Block 7 - UsbCommand c; - - sscanf(Cmd, "%x %d %x", &Data, &Block, &Password); - - if (Block > 7) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } - - PrintAndLog("Writting block %d with data %08X and password %08X", Block, Data, Password); - - c.cmd = CMD_T55XX_WRITE_BLOCK; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = Data; - c.arg[1] = Block; - c.arg[2] = Password; - SendCommand(&c); - return 0; +int CmdInfo(const char *Cmd){ + /* + Page 0 Block 0 Configuration data. + Normal mode + Extended mode + */ + char cmdp = param_getchar(Cmd, 0); + + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf t55xx info [use data from Graphbuffer]"); - PrintAndLog(" [use data from Graphbuffer], if not set, try reading data from tag."); - PrintAndLog(""); - PrintAndLog(" sample: lf t55xx info"); - PrintAndLog(" sample: lf t55xx info 1"); ++ usage_t55xx_info(); + return 0; - } - - if ( strlen(Cmd) == 0 ){ ++ } else { + CmdReadBlk("0"); + } + + uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; + + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN); + + uint8_t si = 5; + uint32_t bl0 = PackBits(si, 32, bits); + + uint32_t safer = PackBits(si, 4, bits); si += 4; + uint32_t resv = PackBits(si, 7, bits); si += 7; + uint32_t dbr = PackBits(si, 3, bits); si += 3; + uint32_t extend = PackBits(si, 1, bits); si += 1; + uint32_t datamodulation = PackBits(si, 5, bits); si += 5; + uint32_t pskcf = PackBits(si, 2, bits); si += 2; + uint32_t aor = PackBits(si, 1, bits); si += 1; + uint32_t otp = PackBits(si, 1, bits); si += 1; + uint32_t maxblk = PackBits(si, 3, bits); si += 3; + uint32_t pwd = PackBits(si, 1, bits); si += 1; + uint32_t sst = PackBits(si, 1, bits); si += 1; + uint32_t fw = PackBits(si, 1, bits); si += 1; + uint32_t inv = PackBits(si, 1, bits); si += 1; + uint32_t por = PackBits(si, 1, bits); si += 1; + + PrintAndLog(""); + PrintAndLog("-- T55xx Configuration & Tag Information --------------------"); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Safer key : %s", GetSaferStr(safer)); + PrintAndLog(" reserved : %d", resv); + PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr)); + PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No"); + PrintAndLog(" Modulation : %s", GetModulationStr(datamodulation) ); + PrintAndLog(" PSK clock freq : %d", pskcf); + PrintAndLog(" AOR - Answer on Request : %s", (aor) ? "Yes":"No"); + PrintAndLog(" OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" ); + PrintAndLog(" Max block : %d", maxblk); + PrintAndLog(" Password mode : %s", (pwd) ? "Yes":"No"); + PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No"); + PrintAndLog(" Fast Write : %s", (fw) ? "Yes":"No"); + PrintAndLog(" Inverse data : %s", (inv) ? "Yes":"No"); + PrintAndLog(" POR-Delay : %s", (por) ? "Yes":"No"); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Raw Data - Page 0"); + PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(bits+5,32) ); + PrintAndLog("-------------------------------------------------------------"); + + return 0; } -int CmdReadTrace(const char *Cmd) -{ +int CmdDump(const char *Cmd){ - char cmdp = param_getchar(Cmd, 0); - char s[20]; - PrintAndLog("Reading traceability data"); ++ char s[20] = {0x00}; + uint8_t pwd[4] = {0x00}; - bool hasPwd = ( strlen(Cmd) > 0); - + - UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}}; - SendCommand(&c); - return 0; ++ char cmdp = param_getchar(Cmd, 0); + if ( cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf t55xx dump "); - PrintAndLog(" sample: lf t55xx dump FFFFFFFF"); ++ usage_t55xx_dump(); + return 0; + } - ++ ++ bool hasPwd = ( strlen(Cmd) > 0); + if ( hasPwd ){ + if (param_gethex(Cmd, 0, pwd, 8)) { + PrintAndLog("password must include 8 HEX symbols"); + return 1; + } + } + + for ( int i = 0; i <8; ++i){ + memset(s,0,sizeof(s)); + if ( hasPwd ) { + sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]); - CmdReadBlkPWD(s); + } else { + sprintf(s,"%d", i); - CmdReadBlk(s); + } ++ CmdReadBlk(s); + } + return 0; +} + +int CmdIceFsk(const char *Cmd){ + + if (!HasGraphData()) return 0; + + iceFsk3(GraphBuffer, LF_TRACE_BUFF_SIZE); + RepaintGraphWindow(); + return 0; +} +int CmdIceManchester(const char *Cmd){ + ManchesterDemod( -1); + return 0; +} +int ManchesterDemod(int blockNum){ + + if (!HasGraphData()) return 0; + + uint8_t sizebyte = 32; + // the value 5 was selected during empirical studies of the decoded data. Some signal noise to skip. + uint8_t offset = 5; + uint32_t blockData; + uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; + uint8_t * bitstream = bits; + + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN); + blockData = PackBits(offset, sizebyte, bits); + + if ( blockNum < 0) + PrintAndLog(" Decoded : 0x%08X %s", blockData, sprint_bin(bitstream+offset,sizebyte) ); + else + PrintAndLog(" Block %d : 0x%08X %s", blockNum, blockData, sprint_bin(bitstream+offset,sizebyte) ); + + return 0; +} + +char * GetBitRateStr(uint32_t id){ + static char buf[40]; + char *retStr = buf; + switch (id){ + case 0: + sprintf(retStr,"%d - RF/8",id); + break; + case 1: + sprintf(retStr,"%d - RF/16",id); + break; + case 2: + sprintf(retStr,"%d - RF/32",id); + break; + case 3: + sprintf(retStr,"%d - RF/40",id); + break; + case 4: + sprintf(retStr,"%d - RF/50",id); + break; + case 5: + sprintf(retStr,"%d - RF/64",id); + break; + case 6: + sprintf(retStr,"%d - RF/100",id); + break; + case 7: + sprintf(retStr,"%d - RF/128",id); + break; + default: + sprintf(retStr,"%d - (Unknown)",id); + break; + } + + return buf; +} + +char * GetSaferStr(uint32_t id){ + static char buf[40]; + char *retStr = buf; + + sprintf(retStr,"%d",id); + if (id == 6) { + sprintf(retStr,"%d - pasdwd",id); + } + if (id == 9 ){ + sprintf(retStr,"%d - testmode ",id); + } + + return buf; +} +char * GetModulationStr( uint32_t id){ + static char buf[40]; + char *retStr = buf; + + switch (id){ + case 0: + sprintf(retStr,"%d - DIRECT (ASK/NRZ)",id); + break; + case 1: + sprintf(retStr,"%d - PSK 1 phase change when input changes",id); + break; + case 2: + sprintf(retStr,"%d - PSK 2 phase change on bitclk if input high",id); + break; + case 3: + sprintf(retStr,"%d - PSK 3 phase change on rising edge of input",id); + break; + case 4: + sprintf(retStr,"%d - FSK 1 RF/8 RF/5",id); + break; + case 5: + sprintf(retStr,"%d - FSK 2 RF/8 RF/10",id); + break; + case 6: + sprintf(retStr,"%d - FSK 1a RF/5 RF/8",id); + break; + case 7: + sprintf(retStr,"%d - FSK 2a RF/10 RF/8",id); + break; + case 8: + sprintf(retStr,"%d - Manschester",id); + break; + case 16: + sprintf(retStr,"%d - Biphase",id); + break; + case 17: + sprintf(retStr,"%d - Reserved",id); + break; + default: + sprintf(retStr,"0x%02X (Unknown)",id); + break; + } + return buf; +} + + +uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){ + + int i = start; + int j = len-1; + if (len > 32) { + return 0; + } + uint32_t tmp = 0; + for (; j >= 0; --j, ++i){ + tmp |= bits[i] << j; + } + return tmp; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"readblock", CmdReadBlk, 1, " -- Read T55xx block data (page 0)"}, - {"readblockPWD", CmdReadBlkPWD, 1, " -- Read T55xx block data in password mode(page 0)"}, - {"writeblock", CmdWriteBlk, 1, " -- Write T55xx block data (page 0)"}, - {"writeblockPWD", CmdWriteBlkPWD, 1, " -- Write T55xx block data in password mode(page 0)"}, - {"readtrace", CmdReadTrace, 1, "Read T55xx traceability data (page 1)"}, + {"help", CmdHelp, 1, "This help"}, - {"rd", CmdReadBlk, 0, " -- Read T55xx block data (page 0)"}, - {"rdpwd", CmdReadBlkPWD, 0, " -- Read T55xx block data with password mode"}, - {"wr", CmdWriteBlk, 0, " -- Write T55xx block data (page 0)"}, - {"wrpwd", CmdWriteBlkPWD, 0, " -- Write T55xx block data with password"}, ++ {"rd", CmdReadBlk, 0, " [password] -- Read T55xx block data (page 0) [optional password]"}, ++ {"wr", CmdWriteBlk, 0, " [password] -- Write T55xx block data (page 0) [optional password]"}, + {"trace", CmdReadTrace, 0, "[1] Read T55xx traceability data (page 1/ blk 0-1)"}, + {"info", CmdInfo, 0, "[1] Read T55xx configuration data (page 0/ blk 0)"}, - {"dump", CmdDump, 0, "[password] Dump T55xx card block 0-7. optional with password"}, - //{"fsk", CmdIceFsk, 0, "FSK demod"}, ++ {"dump", CmdDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"}, + {"man", CmdIceManchester, 0, "Manchester demod (with SST)"}, {NULL, NULL, 0, NULL} }; diff --cc client/ui.c index 10ae1310,c0d01bc3..6645a99e --- a/client/ui.c +++ b/client/ui.c @@@ -94,388 -90,3 +94,388 @@@ void SetLogFilename(char *fn { logfilename = fn; } + +int manchester_decode( int * data, const size_t len, uint8_t * dataout, size_t dataoutlen){ + + int bitlength = 0; + int clock, high, low, startindex; + low = startindex = 0; + high = 1; + uint8_t * bitStream = (uint8_t* ) malloc(sizeof(uint8_t) * dataoutlen); + memset(bitStream, 0x00, dataoutlen); + + /* Detect high and lows */ + DetectHighLowInGraph(&high, &low, TRUE); + + /* get clock */ - clock = GetClock("",0, 0); ++ clock = GetAskClock("",false, false); + + startindex = DetectFirstTransition(data, len, high); + + if (high != 1) + // decode "raw" + bitlength = ManchesterConvertFrom255(data, len, bitStream, dataoutlen, high, low, clock, startindex); + else + // decode manchester + bitlength = ManchesterConvertFrom1(data, len, bitStream, dataoutlen, clock, startindex); + + memcpy(dataout, bitStream, bitlength); + free(bitStream); + return bitlength; +} + + int DetectFirstTransition(const int * data, const size_t len, int threshold){ + + int i = 0; + /* now look for the first threshold */ + for (; i < len; ++i) { + if (data[i] == threshold) { + break; + } + } + return i; + } + + int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout, int dataoutlen, int high, int low, int clock, int startIndex){ + + int i, j, z, hithigh, hitlow, bitIndex, startType; + i = 0; + bitIndex = 0; + + int isDamp = 0; + int damplimit = (int)((high / 2) * 0.3); + int dampHi = (high/2)+damplimit; + int dampLow = (high/2)-damplimit; + int firstST = 0; + + // i = clock frame of data + for (; i < (int)(len/clock); i++) + { + hithigh = 0; + hitlow = 0; + startType = -1; + z = startIndex + (i*clock); + isDamp = 0; + + /* Find out if we hit both high and low peaks */ + for (j = 0; j < clock; j++) + { + if (data[z+j] == high){ + hithigh = 1; + if ( startType == -1) + startType = 1; + } + + if (data[z+j] == low ){ + hitlow = 1; + if ( startType == -1) + startType = 0; + } + + if (hithigh && hitlow) + break; + } + + // No high value found, are we in a dampening field? + if ( !hithigh ) { + //PrintAndLog(" # Entering damp test at index : %d (%d)", z+j, j); + for (j = 0; j < clock; j++) { + if ( + (data[z+j] <= dampHi && data[z+j] >= dampLow) + ){ + isDamp++; + } + } + } + + /* Manchester Switching.. + 0: High -> Low + 1: Low -> High + */ + if (startType == 0) + dataout[bitIndex++] = 1; + else if (startType == 1) + dataout[bitIndex++] = 0; + else + dataout[bitIndex++] = 2; + + if ( isDamp > clock/2 ) { + firstST++; + } + + if ( firstST == 4) + break; + if ( bitIndex >= dataoutlen-1 ) + break; + } + return bitIndex; + } + + int ManchesterConvertFrom1(const int * data, const size_t len, uint8_t * dataout,int dataoutlen, int clock, int startIndex){ + + int i,j, bitindex, lc, tolerance, warnings; + warnings = 0; + int upperlimit = len*2/clock+8; + i = startIndex; + j = 0; + tolerance = clock/4; + uint8_t decodedArr[len]; + + /* Detect duration between 2 successive transitions */ + for (bitindex = 1; i < len; i++) { + + if (data[i-1] != data[i]) { + lc = i - startIndex; + startIndex = i; + + // Error check: if bitindex becomes too large, we do not + // have a Manchester encoded bitstream or the clock is really wrong! + if (bitindex > upperlimit ) { + PrintAndLog("Error: the clock you gave is probably wrong, aborting."); + return 0; + } + // Then switch depending on lc length: + // Tolerance is 1/4 of clock rate (arbitrary) + if (abs((lc-clock)/2) < tolerance) { + // Short pulse : either "1" or "0" + decodedArr[bitindex++] = data[i-1]; + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" + decodedArr[bitindex++] = data[i-1]; + decodedArr[bitindex++] = data[i-1]; + } else { + ++warnings; + PrintAndLog("Warning: Manchester decode error for pulse width detection."); + if (warnings > 10) { + PrintAndLog("Error: too many detection errors, aborting."); + return 0; + } + } + } + } + + /* + * We have a decodedArr of "01" ("1") or "10" ("0") + * parse it into final decoded dataout + */ + for (i = 0; i < bitindex; i += 2) { + + if ((decodedArr[i] == 0) && (decodedArr[i+1] == 1)) { + dataout[j++] = 1; + } else if ((decodedArr[i] == 1) && (decodedArr[i+1] == 0)) { + dataout[j++] = 0; + } else { + i++; + warnings++; + PrintAndLog("Unsynchronized, resync..."); + PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); + + if (warnings > 10) { + PrintAndLog("Error: too many decode errors, aborting."); + return 0; + } + } + } + + PrintAndLog("%s", sprint_hex(dataout, j)); + return j; + } + + void ManchesterDiffDecodedString(const uint8_t* bitstream, size_t len, uint8_t invert){ + /* + * We have a bitstream of "01" ("1") or "10" ("0") + * parse it into final decoded bitstream + */ + int i, j, warnings; + uint8_t decodedArr[(len/2)+1]; + + j = warnings = 0; + + uint8_t lastbit = 0; + + for (i = 0; i < len; i += 2) { + + uint8_t first = bitstream[i]; + uint8_t second = bitstream[i+1]; + + if ( first == second ) { + ++i; + ++warnings; + if (warnings > 10) { + PrintAndLog("Error: too many decode errors, aborting."); + return; + } + } + else if ( lastbit != first ) { + decodedArr[j++] = 0 ^ invert; + } + else { + decodedArr[j++] = 1 ^ invert; + } + lastbit = second; + } + + PrintAndLog("%s", sprint_hex(decodedArr, j)); +} + +void PrintPaddedManchester( uint8_t* bitStream, size_t len, size_t blocksize){ + + PrintAndLog(" Manchester decoded : %d bits", len); + + uint8_t mod = len % blocksize; + uint8_t div = len / blocksize; + int i; + + // Now output the bitstream to the scrollback by line of 16 bits + for (i = 0; i < div*blocksize; i+=blocksize) { + PrintAndLog(" %s", sprint_bin(bitStream+i,blocksize) ); + } + + if ( mod > 0 ) + PrintAndLog(" %s", sprint_bin(bitStream+i, mod) ); +} + +/* Sliding DFT + Smooths out +*/ +void iceFsk2(int * data, const size_t len){ + + int i, j; + int * output = (int* ) malloc(sizeof(int) * len); + memset(output, 0x00, len); + + // for (i=0; i 60)? 100:0; + } + } + + for (j=0; j 0)? 10 : -10; + } + + // show data + for (j=0; j0 ? 1:0; + printf("%d", bit ); + } + printf("\n"); + + printf("R/50 : "); + for (i =startPos ; i < adjustedLen; i += 50){ + bit = data[i]>0 ? 1:0; + printf("%d", bit ); } + printf("\n"); + + free(output); +} + +float complex cexpf (float complex Z) +{ + float complex Res; + double rho = exp (__real__ Z); + __real__ Res = rho * cosf(__imag__ Z); + __imag__ Res = rho * sinf(__imag__ Z); + return Res; +}