From 6a09bea4271573b36800126ca407bfe2d7214df2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 15 Oct 2015 11:30:37 +0200 Subject: [PATCH 01/16] CHG: code clean up. Have some questions regarding the CopyVikingTo method. The configblock looks wrong.. --- armsrc/lfops.c | 43 +++++++++++-------------------------------- client/cmdlfem4x.c | 1 - 2 files changed, 11 insertions(+), 33 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 4b668751..31fe4ca9 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1132,6 +1132,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) * Relevant times in microsecond * To compensate antenna falling times shorten the write times * and enlarge the gap ones. + * Q5 tags seems to have issues when these values changes. */ #define START_GAP 50*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc) @@ -1257,7 +1258,6 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { LED_A_OFF(); } - // Read card traceability data (page 1) void T55xxReadTrace(void){ LED_A_ON(); @@ -1285,7 +1285,6 @@ void T55xxReadTrace(void){ LED_A_OFF(); } - /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) @@ -1542,7 +1541,6 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID // and the block 0 for Indala64 format T55xxWriteBlock(hi,1,0,0); @@ -1556,12 +1554,10 @@ void CopyIndala64toT55x7(int hi, int lo) // T5567WriteBlock(0x603E1042,0); DbpString("DONE!"); - } void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID // and the block 0 for Indala224 format T55xxWriteBlock(uid1,1,0,0); @@ -1580,7 +1576,6 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int // T5567WriteBlock(0x603E10E2,0); DbpString("DONE!"); - } //----------------------------------- @@ -1591,7 +1586,6 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define FWD_CMD_READ 0x9 #define FWD_CMD_DISABLE 0x5 - uint8_t forwardLink_data[64]; //array of forwarded bits uint8_t * forward_ptr; //ptr for forward message preparation uint8_t fwd_bit_sz; //forwardlink bit counter @@ -1601,9 +1595,7 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer // prepares command bits // see EM4469 spec //==================================================================== -//-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- *forward_ptr++ = 0; //start bit *forward_ptr++ = 0; //second pause for 4050 code @@ -1623,10 +1615,7 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { // prepares address bits // see EM4469 spec //==================================================================== - -//-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- register uint8_t line_parity; @@ -1647,10 +1636,7 @@ uint8_t Prepare_Addr( uint8_t addr ) { // prepares data bits intreleaved with parity bits // see EM4469 spec //==================================================================== - -//-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- register uint8_t line_parity; register uint8_t column_parity; @@ -1694,21 +1680,14 @@ void SendForward(uint8_t fwd_bit_count) { LED_D_ON(); - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + // force 1st mod pulse (start gap must be longer for 4305) fwd_bit_sz--; //prepare next bit modulation fwd_write_ptr++; FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on SpinDelayUs(16*8); //16 cycles on (8us each) @@ -1720,7 +1699,6 @@ void SendForward(uint8_t fwd_bit_count) { //These timings work for 4469/4269/4305 (with the 55*8 above) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on SpinDelayUs(9*8); //16 cycles on (8us each) } @@ -1739,7 +1717,6 @@ void EM4xLogin(uint32_t Password) { //Wait for command to complete SpinDelay(20); - } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { @@ -1779,9 +1756,9 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { if (i >= bufferlength) break; } } - + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off cmd_send(CMD_ACK,0,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off LED_D_OFF(); } @@ -1805,13 +1782,15 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode LED_D_OFF(); } -void CopyViKingtoT55x7(uint32_t block1,uint32_t block2) { +void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) { LED_D_ON(); T55xxWriteBlock(block1,1,0,0); T55xxWriteBlock(block2,2,0,0); - T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1); + // ICEMAN NOTES: + // Shouldn't this one be: T55x7_MAXBLOCK_SHIFT and 0 in password mode + // like this: + // T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0); LED_D_OFF(); - DbpString("DONE!"); } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index c68d35f8..5a263bf6 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -232,7 +232,6 @@ int CmdEM410xWrite(const char *Cmd) UsbCommand c = {CMD_EM410X_WRITE_TAG, {card, (uint32_t)(id >> 32), (uint32_t)id}}; SendCommand(&c); - return 0; } -- 2.39.5 From 952a812c008767518e2357e420e1b54dcdf5e2b2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 15 Oct 2015 19:17:20 +0200 Subject: [PATCH 02/16] FIX: a suggested fix for #136 where the "lf t55x7 read" command when called with a password. The call will now try loading the config block, decode it and see if PWD is set. If PWD Bit is set, the call will be allowed to execute. If PWD Bit is NOT set, the call will print a message and excute the call but without sending the password. If config block is not being able to read or decode, the call with print a warning message and exit the call. --- client/cmdlft55xx.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1cadfe7a..e652c788 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -28,6 +28,7 @@ #define CONFIGURATION_BLOCK 0x00 #define TRACE_BLOCK 0x01 +#define T55x7_PWD 0x00000010 // Default configuration t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00}; @@ -235,8 +236,20 @@ int CmdT55xxReadBlock(const char *Cmd) { //Password mode if ( res == 2 ) { - c.arg[2] = password; - c.d.asBytes[0] = 0x1; + + // try reading the config block and verify that PWD bit is set before doing this! + AquireData( CONFIGURATION_BLOCK ); + if ( !tryDetectModulation() ) { + PrintAndLog("Could not detect is PWD bit is set in config block. Exits."); + return 1; + } + //if PWD bit is set, allow to execute read command with password. + if (( config.block0 & T55x7_PWD ) == 1) { + c.arg[2] = password; + c.d.asBytes[0] = 0x1; + } else { + PrintAndLog("PWD bit is NOT set in config block. Reading without password..."); + } } clearCommandBuffer(); -- 2.39.5 From 2f5436ff0d860267c3f5419ac218da474dff64f1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 15 Oct 2015 19:30:11 +0200 Subject: [PATCH 03/16] test --- README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.txt b/README.txt index 2bab1bcd..81bd7720 100644 --- a/README.txt +++ b/README.txt @@ -1,6 +1,6 @@ The iceman fork --------------- -NOTICE: +NOTICE: The official Proxmark repository is found here: https://github.com/Proxmark/proxmark3 -- 2.39.5 From a739812e899f9107ed7220965539c61705dc54c8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 16 Oct 2015 23:16:46 +0200 Subject: [PATCH 04/16] FIX: thanks @tony, for pointing out a "end" statement inside tnp3sim.lua ADD: @marshmello42 fixs for t55x7 --- armsrc/BigBuf.c | 6 ++ armsrc/BigBuf.h | 1 + armsrc/lfops.c | 163 +++++++++++++++++-------------------- armsrc/lfsampling.c | 2 +- armsrc/lfsampling.h | 1 - client/cmdlf.c | 15 ++-- client/cmdlfpcf7931.c | 8 +- client/cmdlft55xx.c | 6 +- client/scripts/tnp3sim.lua | 1 - 9 files changed, 97 insertions(+), 106 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 3499d7c7..64ad91ff 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -50,8 +50,14 @@ uint8_t *BigBuf_get_EM_addr(void) // clear ALL of BigBuf void BigBuf_Clear(void) +{ + BigBuf_Clear_ext(true); +} +// clear ALL of BigBuf +void BigBuf_Clear_ext(bool verbose) { memset(BigBuf,0,BIGBUF_SIZE); + if (verbose) Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE); } diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index b859ffda..3f1b05c2 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -25,6 +25,7 @@ extern uint8_t *BigBuf_get_addr(void); extern uint8_t *BigBuf_get_EM_addr(void); extern uint16_t BigBuf_max_traceLen(void); extern void BigBuf_Clear(void); +extern void BigBuf_Clear_ext(bool verbose); extern uint8_t *BigBuf_malloc(uint16_t); extern void BigBuf_free(void); extern void BigBuf_free_keep_EM(void); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 31fe4ca9..4a0dca16 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -242,11 +242,13 @@ void AcquireTiType(void) int i, j, n; // tag transmission is <20ms, sampling at 2M gives us 40K samples max // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t - #define TIBUFLEN 1250 + #define TIBUFLEN 1250 // clear buffer - uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr(); - memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t)); + uint32_t *buf = (uint32_t *)BigBuf_get_addr(); + + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); // Set up the synchronous serial port AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; @@ -284,7 +286,7 @@ void AcquireTiType(void) i = 0; for(;;) { if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + buf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer i++; if(i >= TIBUFLEN) break; } WDT_HIT(); @@ -295,11 +297,12 @@ void AcquireTiType(void) AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; char *dest = (char *)BigBuf_get_addr(); - n = TIBUFLEN*32; + n = TIBUFLEN * 32; + // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { + for (i = TIBUFLEN-1; i >= 0; i--) { + for (j = 0; j < 32; j++) { + if(buf[i] & (1 << j)) { dest[--n] = 1; } else { dest[--n] = -1; @@ -324,8 +327,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) crc = update_crc16(crc, (idhi>>16)&0xff); crc = update_crc16(crc, (idhi>>24)&0xff); } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + Dbprintf("Writing to tag: %x%08x, crc=%x", (unsigned int) idhi, (unsigned int) idlo, crc); // TI tags charge at 134.2Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz @@ -389,12 +391,11 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; #define SHORT_COIL() LOW(GPIO_SSC_DOUT) - #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) + #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) i = 0; for(;;) { @@ -406,16 +407,15 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) } WDT_HIT(); } - if (ledcontrol) - LED_D_ON(); + if (ledcontrol) LED_D_ON(); if(tab[i]) OPEN_COIL(); else SHORT_COIL(); - if (ledcontrol) - LED_D_OFF(); + if (ledcontrol) LED_D_OFF(); + //wait until SSC_CLK goes LOW while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { if(BUTTON_PRESS()) { @@ -569,12 +569,9 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) } } - if (ledcontrol) - LED_A_ON(); + if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); - - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) LED_A_OFF(); } // prepare a waveform pattern in the buffer based on the ID given then @@ -677,21 +674,10 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) if (separator==1) Dbprintf("sorry but separator option not yet available"); Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n); - //DEBUG - //Dbprintf("First 32:"); - //uint8_t *dest = BigBuf_get_addr(); - //i=0; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - //i+=16; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - if (ledcontrol) - LED_A_ON(); - + if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); - - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) LED_A_OFF(); } //carrier can be 2,4 or 8 @@ -720,7 +706,7 @@ static void pskSimBit(uint8_t waveLen, int *n, uint8_t clk, uint8_t *curPhase, b // args clock, carrier, invert, void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) { - int ledcontrol=1; + int ledcontrol = 1; int n=0, i=0; uint8_t clk = arg1 >> 8; uint8_t carrier = arg1 & 0xFF; @@ -734,26 +720,16 @@ void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) } } Dbprintf("Simulating with Carrier: %d, clk: %d, invert: %d, n: %d",carrier, clk, invert, n); - //Dbprintf("DEBUG: First 32:"); - //uint8_t *dest = BigBuf_get_addr(); - //i=0; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - //i+=16; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - if (ledcontrol) - LED_A_ON(); + if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); - - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); - //const size_t sizeOfBigBuff = BigBuf_max_traceLen(); size_t size = 0; uint32_t hi2=0, hi=0, lo=0; int idx=0; @@ -767,7 +743,6 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) DoAcquisition_default(-1,true); // FSK demodulator - //size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use size = 50*128*2; //big enough to catch 2 sequences of largest format idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo); @@ -775,12 +750,16 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // go over previously decoded manchester data and decode into usable tag ID if (hi2 != 0){ //extra large HID tags 88/192 bits Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + (unsigned int) hi2, + (unsigned int) hi, + (unsigned int) lo, + (unsigned int) (lo>>1) & 0xFFFF + ); }else { //standard HID tags 44/96 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd uint8_t bitlen = 0; uint32_t fc = 0; uint32_t cardnum = 0; + if (((hi>>5)&1) == 1){//if bit 38 is set then < 37 bit format is used uint32_t lo2=0; lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit @@ -818,11 +797,13 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) fc = ((hi&0xF)<<12)|(lo>>20); } } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + (unsigned int) hi, + (unsigned int) lo, + (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, + (unsigned int) fc, + (unsigned int) cardnum); } if (findone){ if (ledcontrol) LED_A_OFF(); @@ -843,7 +824,6 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); - //const size_t sizeOfBigBuff = BigBuf_max_traceLen(); size_t size; int idx=0; // Configure to go in 125Khz listen mode @@ -856,7 +836,6 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol) DoAcquisition_default(-1,true); // FSK demodulator - //size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use size = 50*128*2; //big enough to catch 2 sequences of largest format idx = AWIDdemodFSK(dest, &size); @@ -1041,7 +1020,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) code = bytebits_to_byte(dest+idx,32); code2 = bytebits_to_byte(dest+idx+32,32); version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8); + facilitycode = bytebits_to_byte(dest+idx+18,8); number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 crc = bytebits_to_byte(dest+idx+54,8); @@ -1056,7 +1035,6 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // if we're only looking for one tag if (findone){ if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); *high=code; *low=code2; return; @@ -1139,6 +1117,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc) #define WRITE_0 16*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc) #define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550 +#define READ_GAP 52*8 // VALUES TAKEN FROM EM4x function: SendForward // START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) @@ -1154,6 +1133,12 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // T0 = TIMER_CLOCK1 / 125000 = 192 // 1 Cycle = 8 microseconds(us) == 1 field clock +void TurnReadLFOn(int delay) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelayUs(delay); //155*8 //50*8 +} + // Write one bit to card void T55xxWriteBit(int bit) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); @@ -1183,18 +1168,18 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod T55xxWriteBit(0); //Page 0 if (PwdMode == 1){ - // Send pwd + // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } - // Send lock bit + // Send Lock bit T55xxWriteBit(0); - // Send data + // Send Data for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Data & i); - // Send block number + // Send Block number for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); @@ -1202,24 +1187,21 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // so wait a little more) TurnReadLFOn(20 * 1000); - // field off + // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); LED_A_OFF(); } -void TurnReadLFOn(int delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelayUs(delay); -} - // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { LED_A_ON(); uint32_t i = 0; + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); + //make sure block is at max 7 Block &= 0x7; @@ -1227,6 +1209,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { LFSetupFPGAForADC(95, true); // Trigger T55x7 in mode. + // Trigger T55x7 Direct Access Mode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); @@ -1235,24 +1218,24 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { T55xxWriteBit(0); //Page 0 if (PwdMode == 1){ - // Send pwd + // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } - // Send a zero bit seperation + // Send a zero bit separation T55xxWriteBit(0); - // Send block number + // Send Block number for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); // Turn field on to read the response - TurnReadLFOn(START_GAP); + TurnReadLFOn(READ_GAP); // Acquisition doT55x7Acquisition(); - // field off + // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); LED_A_OFF(); @@ -1262,10 +1245,13 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { void T55xxReadTrace(void){ LED_A_ON(); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); + // Set up FPGA, 125kHz LFSetupFPGAForADC(95, true); - // Trigger T55x7 in mode. + // Trigger T55x7 Direct Access Mode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); @@ -1274,12 +1260,12 @@ void T55xxReadTrace(void){ T55xxWriteBit(1); //Page 1 // Turn field on to read the response - TurnReadLFOn(START_GAP); + TurnReadLFOn(READ_GAP); // Acquisition doT55x7Acquisition(); - // field off + // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); LED_A_OFF(); @@ -1501,8 +1487,11 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) // Clock rate is stored in bits 8-15 of the card value clock = (card & 0xFF00) >> 8; Dbprintf("Clock rate: %d", clock); - switch (clock) - { + switch (clock) { + case 50: + clock = T55x7_BITRATE_RF_50; + case 40: + clock = T55x7_BITRATE_RF_40; case 32: clock = T55x7_BITRATE_RF_32; break; @@ -1721,15 +1710,14 @@ void EM4xLogin(uint32_t Password) { void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { + uint8_t fwd_bit_count; uint8_t *dest = BigBuf_get_addr(); - uint16_t bufferlength = BigBuf_max_traceLen(); + uint16_t bufsize = BigBuf_max_traceLen(); uint32_t i = 0; - // Clear destination buffer before sending the command 0x80 = average. - memset(dest, 0x80, bufferlength); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - uint8_t fwd_bit_count; - //If password mode do login if (PwdMode == 1) EM4xLogin(Pwd); @@ -1753,7 +1741,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; ++i; - if (i >= bufferlength) break; + if (i >= bufsize) break; } } @@ -1786,11 +1774,10 @@ void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) { LED_D_ON(); T55xxWriteBlock(block1,1,0,0); T55xxWriteBlock(block2,2,0,0); - T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1); + T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0); + // T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1); // ICEMAN NOTES: // Shouldn't this one be: T55x7_MAXBLOCK_SHIFT and 0 in password mode - // like this: - // T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0); LED_D_OFF(); } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 33943421..8b4ab778 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -266,7 +266,7 @@ void doT55x7Acquisition(void){ if ( bufsize > T55xx_SAMPLES_SIZE ) bufsize = T55xx_SAMPLES_SIZE; - memset(dest, 0, bufsize); + //memset(dest, 0, bufsize); uint16_t i = 0; bool startFound = false; diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 460e6d8b..a88def55 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -47,7 +47,6 @@ uint32_t DoAcquisition_config( bool silent); **/ void LFSetupFPGAForADC(int divisor, bool lf_field); - /** * Called from the USB-handler to set the sampling configuration * The sampling config is used for std reading and snooping. diff --git a/client/cmdlf.c b/client/cmdlf.c index c67f34a8..36c07628 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -36,26 +36,25 @@ static int CmdHelp(const char *Cmd); int usage_lf_cmdread() { - PrintAndLog("Usage: lf cmdread [H] "); + PrintAndLog("Usage: lf cmdread [H|L]"); PrintAndLog("Options: "); PrintAndLog(" h This help"); - PrintAndLog(" L Low frequency (125 KHz)"); - PrintAndLog(" H High frequency (134 KHz)"); - PrintAndLog(" H delay OFF"); - PrintAndLog(" H time period ZERO"); - PrintAndLog(" H time period ONE"); + PrintAndLog(" delay offset"); + PrintAndLog(" time period ZERO"); + PrintAndLog(" time period ONE"); + PrintAndLog(" [H|L] Frequency Low (125 KHz) / High (134 KHz)"); PrintAndLog("Examples:"); PrintAndLog(" lf cmdread 80 100 200 11000"); PrintAndLog(" lf cmdread 80 100 100 11000 H"); return 0; } -/* send a command before reading */ +/* send a LF command before reading */ int CmdLFCommandRead(const char *Cmd) { static char dummy[3] = {0x20,0x00,0x00}; bool errors = FALSE; - uint8_t divisor = 0; //125khz + uint8_t divisor = 95; //125khz uint8_t cmdp =0; while(param_getchar(Cmd, cmdp) != 0x00) { diff --git a/client/cmdlfpcf7931.c b/client/cmdlfpcf7931.c index c0a45cfc..23efd2e7 100644 --- a/client/cmdlfpcf7931.c +++ b/client/cmdlfpcf7931.c @@ -66,7 +66,7 @@ int usage_pcf7931_write(){ PrintAndLog("Options:"); PrintAndLog(" h This help"); PrintAndLog(" blockaddress Block to save [0-7]"); - PrintAndLog(" byteaddress Index of byte inside block to write [0-16]"); + PrintAndLog(" byteaddress Index of byte inside block to write [0-15]"); PrintAndLog(" data one byte of data (hex)"); PrintAndLog("Examples:"); PrintAndLog(" lf pcf7931 write 2 1 FF"); @@ -136,7 +136,7 @@ int CmdLFPCF7931Write(const char *Cmd){ if ( param_getdec(Cmd, 0, &block) ) return usage_pcf7931_write(); if ( param_getdec(Cmd, 1, &bytepos) ) return usage_pcf7931_write(); - if ( (block > 7) || (bytepos > 16) ) return usage_pcf7931_write(); + if ( (block > 7) || (bytepos > 15) ) return usage_pcf7931_write(); data = param_get8ex(Cmd, 2, 0, 16); @@ -159,8 +159,8 @@ int CmdLFPCF7931Write(const char *Cmd){ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"}, - {"write", CmdLFPCF7931Write, 1, "Write data on a PCF7931 transponder."}, + {"read", CmdLFPCF7931Read, 0, "Read content of a PCF7931 transponder"}, + {"write", CmdLFPCF7931Write, 0, "Write data on a PCF7931 transponder."}, {"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index e652c788..3b56881b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -262,8 +262,8 @@ int CmdT55xxReadBlock(const char *Cmd) { uint8_t got[12000]; GetFromBigBuf(got,sizeof(got),0); WaitForResponse(CMD_ACK,NULL); - setGraphBuf(got, 12000); - DemodBufferLen=0; + setGraphBuf(got, sizeof(got)); + //DemodBufferLen=0; if (!DecodeT55xxBlock()) return 3; char blk[10]={0}; sprintf(blk,"%d", block); @@ -680,8 +680,8 @@ int CmdT55xxWriteBlock(const char *Cmd) return 1; } - UsbCommand resp; UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}}; + UsbCommand resp; c.d.asBytes[0] = 0x0; PrintAndLog("Writing to block: %d data : 0x%08X", block, data); diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index fa9d1c22..4325ea3f 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -197,7 +197,6 @@ local function ValidateCheckSums(blocks) calc = CalcCheckSum(blocks,2,3) if crc == calc then isOk='Ok' else isOk = 'Error' end io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) -end local cmd local blockdata -- 2.39.5 From d8a3b6c11793d6b3c51fecc35d2549cccd168821 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 17 Oct 2015 14:16:42 +0200 Subject: [PATCH 05/16] FIX: @tony pointed out that there was a method name lost... its been reinstated :) --- client/scripts/tnp3sim.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index 4325ea3f..b6821606 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -198,6 +198,8 @@ local function ValidateCheckSums(blocks) if crc == calc then isOk='Ok' else isOk = 'Error' end io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) +end +local function LoadEmulator(blocks) local cmd local blockdata for _,b in pairs(blocks) do -- 2.39.5 From f14c9bf915f883b5dfa8645dcaf1ded8d5978b90 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 17 Oct 2015 14:35:04 +0200 Subject: [PATCH 06/16] FIX: "abort trap 6" error when runing the tnp3sim.lua script was because the CMD_MIFARE_EML_MEMSET needs to sent the bytewitdh now with recent changes in code to deal with different sizes in emulatormemory. the third argument should be 16 instead of 0. --- client/scripts/tnp3sim.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index b6821606..11b268dd 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -220,11 +220,9 @@ local function LoadEmulator(blocks) end end - cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 0, data = blockdata} + cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 16, data = blockdata} local err = core.SendCommand(cmd:getBytes()) - if err then - return err - end + if err then return err end end io.write('\n') end -- 2.39.5 From a826cb0df1dd2cd11facd5ab8fe0618422fa0054 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 19 Oct 2015 22:39:08 +0200 Subject: [PATCH 07/16] FIX: tnp3sim, now can insert keys if the dumpfile is blank. Like the ,,,lander dumps... --- client/scripts/tnp3dump.lua | 24 ++++++------- client/scripts/tnp3sim.lua | 68 +++++++++++++++++++++---------------- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index 211d146f..44e59657 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -38,9 +38,7 @@ local numSectors = 16 --- -- A debug printout-function function dbg(args) - if not DEBUG then - return - end + if not DEBUG then return end if type(args) == "table" then local i = 1 @@ -56,6 +54,7 @@ end -- This is only meant to be used when errors occur function oops(err) print("ERROR: ",err) + return nil,err end --- -- Usage help @@ -166,6 +165,8 @@ local function main(args) local block0, err = waitCmd() if err then return oops(err) end + core.clearCommandBuffer() + -- Read block 1 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA} err = core.SendCommand(cmd:getBytes()) @@ -173,16 +174,15 @@ local function main(args) local block1, err = waitCmd() if err then return oops(err) end + core.clearCommandBuffer() + local tmpHash = block0..block1..'%02x'..RANDOM local key local pos = 0 local blockNo local blocks = {} - - print('Reading card data') - core.clearCommandBuffer() - + -- main loop io.write('Reading blocks > ') for blockNo = 0, numBlocks-1, 1 do @@ -192,6 +192,8 @@ local function main(args) break end + core.clearCommandBuffer() + pos = (math.floor( blockNo / 4 ) * 12)+1 key = akeys:sub(pos, pos + 11 ) cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key} @@ -214,8 +216,8 @@ local function main(args) local baseStr = utils.ConvertHexToAscii(tmpHash:format(blockNo)) local key = md5.sumhexa(baseStr) local aestest = core.aes128_decrypt(key, blockdata) - local hex = utils.ConvertAsciiToBytes(aestest) - hex = utils.ConvertBytesToHex(hex) + local hex = ConvertAsciiToHex(aestest) + blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex) io.write(blockNo..',') end @@ -235,9 +237,7 @@ local function main(args) for _,s in pairs(blocks) do local slice = s:sub(8,#s) - local str = utils.ConvertBytesToAscii( - utils.ConvertHexToBytes(slice) - ) + local str = utils.ConvertHexToAscii(slice) emldata = emldata..slice..'\n' for c in (str):gmatch('.') do bindata[#bindata+1] = c diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index 11b268dd..ca729f38 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -5,7 +5,8 @@ local lib14a = require('read14a') local utils = require('utils') local md5 = require('md5') local toys = require('default_toys') - +local pre = require('precalc') + example =[[ 1. script run tnp3sim 2. script run tnp3sim -m @@ -27,7 +28,7 @@ Arguments: ]] local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds -local DEBUG = false -- the debug flag +local DEBUG = true -- the debug flag local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' local band = bit32.band @@ -42,9 +43,7 @@ local format = string.format --- -- A debug printout-function function dbg(args) - if not DEBUG then - return - end + if not DEBUG then return end if type(args) == "table" then local i = 1 @@ -107,6 +106,14 @@ local function GetCheckSum(blocks, dataarea, chksumtype) return utils.SwapEndianness(crc,16) end +local function SetAllCheckSum(blocks) + print('Updating all checksums') + SetCheckSum(blocks, 3) + SetCheckSum(blocks, 2) + SetCheckSum(blocks, 1) + SetCheckSum(blocks, 0) +end + local function SetCheckSum(blocks, chksumtype) if blocks == nil then return nil, 'Argument \"blocks\" nil' end @@ -154,7 +161,8 @@ function CalcCheckSum(blocks, dataarea, chksumtype) end local function ValidateCheckSums(blocks) - + print(' Validating checksums') + local isOk, crc, calc -- Checksum Type 0 crc = GetCheckSum(blocks,1,0) @@ -199,9 +207,17 @@ local function ValidateCheckSums(blocks) io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) end -local function LoadEmulator(blocks) - local cmd - local blockdata + +local function AddKey(keys, blockNo, data) + local pos = (math.floor( blockNo / 4 ) * 12)+1 + local key = keys:sub(pos, pos + 11 ) + return key..data:sub(13) +end + +local function LoadEmulator(uid, blocks) + print('Sending dumpdata to emulator memory') + local keys = pre.GetAll(uid) + local cmd, blockdata for _,b in pairs(blocks) do blockdata = b @@ -212,14 +228,16 @@ local function LoadEmulator(blocks) local baseStr = utils.ConvertHexToAscii(base) local key = md5.sumhexa(baseStr) local enc = core.aes128_encrypt(key, blockdata) - local hex = utils.ConvertAsciiToBytes(enc) - hex = utils.ConvertBytesToHex(hex) - - blockdata = hex + blockdata = utils.ConvertAsciiToHex(enc) io.write( _..',') end + else + -- add keys if not existing.. + if ( blockdata:sub(1,12) == '000000000000' ) then + blockdata = AddKey(keys, _, blockdata) + end end - + core.clearCommandBuffer() cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 16, data = blockdata} local err = core.SendCommand(cmd:getBytes()) if err then return err end @@ -357,10 +375,7 @@ local function main(args) blockindex = blockindex + 1 end - if DEBUG then - print(' Validating checksums') - ValidateCheckSums(blocks) - end + if DEBUG then ValidateCheckSums(blocks) end -- print( string.rep('--',20) ) @@ -419,7 +434,7 @@ local function main(args) local level = blocks[13]:sub(27,28) print(('LEVEL : %d'):format( tonumber(level,16))) - --hälsa: 667 029b + --local health = blocks[]:sub(); --print(('Health : %d'):format( tonumber(health,16)) @@ -457,20 +472,15 @@ local function main(args) --print (blocks[13]) -- Update Checksums - print('Updating all checksums') - SetCheckSum(blocks, 3) - SetCheckSum(blocks, 2) - SetCheckSum(blocks, 1) - SetCheckSum(blocks, 0) - - print('Validating all checksums') + SetAllCheckSum(blocks) + + -- Validate Checksums ValidateCheckSums(blocks) end - + --Load dumpdata to emulator memory if DEBUG then - print('Sending dumpdata to emulator memory') - err = LoadEmulator(blocks) + err = LoadEmulator(uid, blocks) if err then return oops(err) end core.clearCommandBuffer() print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..'\" <--') -- 2.39.5 From b87f99f4bbca6ed29ebeaa78b0165e70941e934d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 19 Oct 2015 22:41:53 +0200 Subject: [PATCH 08/16] ADD: some more keys found on a pastebin --- client/default_keys.dic | 36 ++++++++++++++++++++++++++- client/lualibs/mf_default_keys.lua | 40 +++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/client/default_keys.dic b/client/default_keys.dic index 5c21d6ac..8053f42d 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -93,4 +93,38 @@ fc0001877bf7,--RKFÖstgötaTrafikenKeyA f4a9ef2afc6d,--BCARD KeyB a9f953def0a3,-- 75ccb59c9bed,-- mystery KeyA Mifare 1k EV1 (S50) Sector 17! -4b791bea7bcc,-- mystery KeyB Mifare 1k EV1 (S50) Sector 17! \ No newline at end of file +4b791bea7bcc,-- mystery KeyB Mifare 1k EV1 (S50) Sector 17! +# +# Here be BIP keys... +3A42F33AF429, +1FC235AC1309, +6338A371C0ED, +243F160918D1, +F124C2578AD0, +9AFC42372AF1, +32AC3B90AC13, +682D401ABB09, +4AD1E273EAF1, +067DB45454A9, +E2C42591368A, +15FC4C7613FE, +2A3C347A1200, +68D30288910A, +16F3D5AB1139, +F59A36A2546D, +937A4FFF3011, +64E3C10394C2, +35C3D2CAEE88, +B736412614AF, +693143F10368, +324F5DF65310, +A3F97428DD01, +643FB6DE2217, +63F17A449AF0, +82F435DEDF01, +C4652C54261C, +0263DE1278F3, +D49E2826664F, +51284C3686A6, +3DF14C8000A1, +6A470D54127C, \ No newline at end of file diff --git a/client/lualibs/mf_default_keys.lua b/client/lualibs/mf_default_keys.lua index 006d2e6f..a7aac022 100644 --- a/client/lualibs/mf_default_keys.lua +++ b/client/lualibs/mf_default_keys.lua @@ -1,8 +1,5 @@ - local _keys = { - - --[[ These keys are from the pm3 c-codebase. @@ -187,6 +184,43 @@ local _keys = { --]] '75ccb59c9bed', '4b791bea7bcc', + + --[[ + Here be BIP keys... + ref: http://pastebin.com/QjUc66Zg + --]] + '3A42F33AF429', + '1FC235AC1309', + '6338A371C0ED', + '243F160918D1', + 'F124C2578AD0', + '9AFC42372AF1', + '32AC3B90AC13', + '682D401ABB09', + '4AD1E273EAF1', + '067DB45454A9', + 'E2C42591368A', + '15FC4C7613FE', + '2A3C347A1200', + '68D30288910A', + '16F3D5AB1139', + 'F59A36A2546D', + '937A4FFF3011', + '64E3C10394C2', + '35C3D2CAEE88', + 'B736412614AF', + '693143F10368', + '324F5DF65310', + 'A3F97428DD01', + '643FB6DE2217', + '63F17A449AF0', + '82F435DEDF01', + 'C4652C54261C', + '0263DE1278F3', + 'D49E2826664F', + '51284C3686A6', + '3DF14C8000A1', + '6A470D54127C', } --- -- 2.39.5 From 9276e859a6f57ba2518e501fd8148a390ca3aa5e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 20 Oct 2015 19:00:02 +0200 Subject: [PATCH 09/16] ADD: @marshmellows42 's fixes for "lf cmdread" and CHANGELOG.md ADD: Added the "lf t55x7 wakeup" command. It will send a pwd, and leave the antenna on. Process like: 1. lf t55x7 wakeup p 11223344 2. lf search --- It is still not finished, will work together with the "lf t55x7 commands" in next step when I figure out the process from the datasheets. --- CHANGELOG.md | 10 ++- armsrc/appmain.c | 5 +- armsrc/apps.h | 6 +- armsrc/lfops.c | 42 +++++++-- armsrc/lfsampling.c | 9 +- client/cmdlf.c | 63 ++++++++----- client/cmdlft55xx.c | 169 +++++++++++++++++++++++++++-------- client/hid-flasher/usb_cmd.h | 3 + client/lualibs/commands.lua | 1 + include/usb_cmd.h | 2 +- 10 files changed, 230 insertions(+), 80 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e619d89e..83b46cf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] --trying to fix "hf 14b" command to be able to read CALYPSO card. (iceman) - --trying to fix "t55x7" read with password bug. (iceman) -- -### Added +### Added +- `lf t55xx read w` added wake with password then read following stream option to standard t55xx read commands (marshmellow) - `hf mf eload u` added an ultralight/ntag option. (marshmellow) - `hf iclass managekeys` to save, load and manage iclass keys. (adjusted most commands to accept a loaded key in memory) (marshmellow) - `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (marshmellow) @@ -22,6 +22,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman) ### Changed +- added lf t5xx read with password safety check and warning text +- Adjusted LF FSK demod to account for cross threshold fluctuations (898 count waves will adjust the 9 to 8 now...) more accurate. +- Adjusted timings for t55xx commands. more reliable now. +- `lf cmdread` adjusted input methods and added help text (marshmellow & iceman) - changed `lf config t ` to be 0 - 128 and will trigger on + or - threshold value (marshmellow) - `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to muliple pages for the larger tags yet) - Revised workflow for StandAloneMode14a (Craig Young) @@ -39,7 +43,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ### Added - Add `hf 14b reader` to find and print general info about known 14b tags (marshmellow) -- Add `hf 14b info` to find and print full info about std 14b tags and sri tags (using 14b raw commands in the client) (marshmellow) +- Add `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client) (marshmellow) - Add PACE replay functionality (frederikmoellers) ### Fixed diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e092c366..4ccb8edc 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -980,7 +980,7 @@ void UsbPacketReceived(uint8_t *packet, int len) CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]); break; case CMD_T55XX_READ_BLOCK: - T55xxReadBlock(c->arg[1], c->arg[2],c->d.asBytes[0]); + T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]); break; case CMD_T55XX_WRITE_BLOCK: T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); @@ -988,6 +988,9 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_T55XX_READ_TRACE: T55xxReadTrace(); break; + case CMD_T55XX_WAKEUP: + T55xxWakeUp(c->arg[0]); + break; case CMD_PCF7931_READ: ReadPCF7931(); break; diff --git a/armsrc/apps.h b/armsrc/apps.h index f15ffd14..7039ab5b 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -67,9 +67,10 @@ extern uint8_t bits_per_sample ; extern bool averaging; void AcquireRawAdcSamples125k(int divisor); -void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,uint8_t *command); +void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command); void ReadTItag(void); void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc); + void AcquireTiType(void); void AcquireRawBitsTI(void); void SimulateTagLowFrequency(int period, int gap, int ledcontrol); @@ -88,8 +89,9 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); void CopyIndala64toT55x7(int hi, int lo); // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7); // Clone Indala 224-bit tag by UID to T55x7 void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode); -void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode ); +void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd); void T55xxReadTrace(void); +void T55xxWakeUp(uint32_t Pwd); void TurnReadLFOn(); void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode); void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 4a0dca16..c070b87c 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -26,7 +26,7 @@ * @param period_1 * @param command */ -void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) +void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command) { int divisor_used = 95; // 125 KHz @@ -1167,7 +1167,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod T55xxWriteBit(1); T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ + if (PwdMode){ // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); @@ -1190,13 +1190,14 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); + LED_A_OFF(); + LED_B_OFF(); } // Read one card block in page 0 -void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { +void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { LED_A_ON(); - + uint8_t PwdMode = arg0 & 0xFF; uint32_t i = 0; //clear buffer now so it does not interfere with timing later @@ -1208,8 +1209,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { // Set up FPGA, 125kHz LFSetupFPGAForADC(95, true); - // Trigger T55x7 in mode. - // Trigger T55x7 Direct Access Mode + // Trigger T55x7 Direct Access Mode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); @@ -1217,11 +1217,12 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { T55xxWriteBit(1); T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ + if (PwdMode){ // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } + // Send a zero bit separation T55xxWriteBit(0); @@ -1239,6 +1240,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); LED_A_OFF(); + LED_B_OFF(); } // Read card traceability data (page 1) @@ -1269,6 +1271,30 @@ void T55xxReadTrace(void){ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); LED_A_OFF(); + LED_B_OFF(); +} + +void T55xxWakeUp(uint32_t Pwd){ + LED_B_ON(); + uint32_t i = 0; + + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + + // Trigger T55x7 Direct Access Mode + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode 10 + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + + // Send Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + + // Turn field on to read the response + TurnReadLFOn(READ_GAP); } /*-------------- Cloning routines -----------*/ diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 8b4ab778..3a70c340 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -266,14 +266,16 @@ void doT55x7Acquisition(void){ if ( bufsize > T55xx_SAMPLES_SIZE ) bufsize = T55xx_SAMPLES_SIZE; - //memset(dest, 0, bufsize); - uint16_t i = 0; + uint16_t nosignal = 0; bool startFound = false; bool highFound = false; uint8_t curSample = 0; uint8_t firstSample = 0; - for(;;) { + while(!BUTTON_PRESS()) { + WDT_HIT(); + if ( nosignal == 0xFFFF ) break; + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { AT91C_BASE_SSC->SSC_THR = 0x43; LED_D_ON(); @@ -287,6 +289,7 @@ void doT55x7Acquisition(void){ firstSample = curSample; highFound = true; } else if (!highFound) { + nosignal++; continue; } diff --git a/client/cmdlf.c b/client/cmdlf.c index 36c07628..f04feb97 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -36,16 +36,18 @@ static int CmdHelp(const char *Cmd); int usage_lf_cmdread() { - PrintAndLog("Usage: lf cmdread [H|L]"); + PrintAndLog("Usage: lf cmdread d z o c [H]"); PrintAndLog("Options: "); PrintAndLog(" h This help"); - PrintAndLog(" delay offset"); - PrintAndLog(" time period ZERO"); - PrintAndLog(" time period ONE"); - PrintAndLog(" [H|L] Frequency Low (125 KHz) / High (134 KHz)"); + PrintAndLog(" H Freqency High (134 KHz), default is 'Low (125KHz)'"); + PrintAndLog(" d delay OFF period, (dec)"); + PrintAndLog(" z time period ZERO, (dec)"); + PrintAndLog(" o time period ONE, (dec)"); + PrintAndLog(" c Command bytes"); + PrintAndLog(" ************* All periods in microseconds (ms)"); PrintAndLog("Examples:"); - PrintAndLog(" lf cmdread 80 100 200 11000"); - PrintAndLog(" lf cmdread 80 100 100 11000 H"); + PrintAndLog(" lf cmdread d 80 z 100 o 200 c 11000"); + PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000 H"); return 0; } @@ -53,21 +55,38 @@ int usage_lf_cmdread() int CmdLFCommandRead(const char *Cmd) { static char dummy[3] = {0x20,0x00,0x00}; + UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; bool errors = FALSE; - uint8_t divisor = 95; //125khz - uint8_t cmdp =0; - while(param_getchar(Cmd, cmdp) != 0x00) - { + + uint8_t cmdp = 0; + int strLength = 0; + + while(param_getchar(Cmd, cmdp) != 0x00) { switch(param_getchar(Cmd, cmdp)) { case 'h': return usage_lf_cmdread(); case 'H': - divisor = 88; + dummy[1]='h'; cmdp++; break; - case 'a': - //param_getchar(Cmd, cmdp+1) == '1'; + case 'L': + cmdp++; + break; + case 'c': + strLength = param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes); + cmdp+=2; + break; + case 'd': + c.arg[0] = param_get32ex(Cmd, cmdp+1, 0, 10); + cmdp+=2; + break; + case 'z': + c.arg[1] = param_get32ex(Cmd, cmdp+1, 0, 10); + cmdp+=2; + break; + case 'o': + c.arg[2] = param_get32ex(Cmd, cmdp+1, 0, 10); cmdp+=2; break; default: @@ -78,19 +97,15 @@ int CmdLFCommandRead(const char *Cmd) if(errors) break; } // No args - if(cmdp == 0) errors = 1; + if (cmdp == 0) errors = 1; //Validations - if(errors) return usage_lf_cmdread(); - - UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; - - sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); + if (errors) return usage_lf_cmdread(); - // in case they specified 'h' - strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); + // in case they specified 'H' + // added to the end.. + strcpy((char *)&c.d.asBytes + strLength, dummy); - PrintAndLog("ICE: %d %s -- %s", strlen((char *)c.d.asBytes) ,dummy, c.d.asBytes); clearCommandBuffer(); SendCommand(&c); return 0; @@ -1205,8 +1220,8 @@ int CmdLFfind(const char *Cmd) static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, + {"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"}, {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, - {"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"}, {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, {"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"}, {"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"}, diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 3b56881b..28956fdc 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -35,7 +35,7 @@ t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offse int usage_t55xx_config(){ PrintAndLog("Usage: lf t55xx config [d ] [i 1] [o ]"); - PrintAndLog("Options: "); + PrintAndLog("Options:"); PrintAndLog(" h This help"); PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate"); PrintAndLog(" d Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A"); @@ -50,30 +50,39 @@ int usage_t55xx_config(){ return 0; } int usage_t55xx_read(){ - PrintAndLog("Usage: lf t55xx read "); - PrintAndLog(" , block number to read. Between 0-7"); - PrintAndLog(" , OPTIONAL password (8 hex characters)"); + PrintAndLog("Usage: lf t55xx read b p "); + PrintAndLog("Options:"); + PrintAndLog(" b , block number to read. Between 0-7"); + PrintAndLog(" p , OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLog(" o, OPTIONAL override safety check"); + PrintAndLog(" w, OPTIONAL wakeup"); + PrintAndLog(" ****WARNING****"); + PrintAndLog(" Use of read with password on a tag not configured for a pwd"); + PrintAndLog(" can damage the tag"); PrintAndLog(""); PrintAndLog("Examples:"); - PrintAndLog(" lf t55xx read 0 - read data from block 0"); - PrintAndLog(" lf t55xx read 0 feedbeef - read data from block 0 password feedbeef"); + PrintAndLog(" lf t55xx read b 0 - read data from block 0"); + PrintAndLog(" lf t55xx read b 0 p feedbeef - read data from block 0 password feedbeef"); + PrintAndLog(" lf t55xx read b 0 p feedbeef o - read data from block 0 password feedbeef safety check"); PrintAndLog(""); return 0; } int usage_t55xx_write(){ - PrintAndLog("Usage: lf t55xx wr [password]"); + PrintAndLog("Usage: lf t55xx write [password]"); + PrintAndLog("Options:"); PrintAndLog(" , block number to write. Between 0-7"); - PrintAndLog(" , 4 bytes of data to write (8 hex characters)"); - PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)"); + PrintAndLog(" , 4 bytes of data to write (8 hex symbols)"); + PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLog(""); PrintAndLog("Examples:"); - PrintAndLog(" lf t55xx wr 3 11223344 - write 11223344 to block 3"); - PrintAndLog(" lf t55xx wr 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef"); + PrintAndLog(" lf t55xx write 3 11223344 - write 11223344 to block 3"); + PrintAndLog(" lf t55xx write 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef"); PrintAndLog(""); return 0; } int usage_t55xx_trace() { PrintAndLog("Usage: lf t55xx trace [1]"); + PrintAndLog("Options:"); PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); PrintAndLog(""); PrintAndLog("Examples:"); @@ -84,6 +93,7 @@ int usage_t55xx_trace() { } int usage_t55xx_info() { PrintAndLog("Usage: lf t55xx info [1]"); + PrintAndLog("Options:"); PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); PrintAndLog(""); PrintAndLog("Examples:"); @@ -94,6 +104,7 @@ int usage_t55xx_info() { } int usage_t55xx_dump(){ PrintAndLog("Usage: lf t55xx dump "); + PrintAndLog("Options:"); PrintAndLog(" , OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLog(""); PrintAndLog("Examples:"); @@ -103,7 +114,9 @@ int usage_t55xx_dump(){ return 0; } int usage_t55xx_detect(){ - PrintAndLog("Usage: lf t55xx detect"); + PrintAndLog("Usage: lf t55xx detect [1]"); + PrintAndLog("Options:"); + PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); PrintAndLog(""); PrintAndLog("Examples:"); PrintAndLog(" lf t55xx detect"); @@ -111,6 +124,17 @@ int usage_t55xx_detect(){ PrintAndLog(""); return 0; } +int usage_t55xx_wakup(){ + PrintAndLog("Usage: lf t55xx wakeup [h] p "); + PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards."); + PrintAndLog("Options:"); + PrintAndLog(" h - this help"); + PrintAndLog(" p - password 4bytes (8 hex symbols)"); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password"); + return 0; +} static int CmdHelp(const char *Cmd); @@ -216,39 +240,72 @@ int CmdT55xxSetConfig(const char *Cmd) { } int CmdT55xxReadBlock(const char *Cmd) { - int block = -1; - int password = 0xFFFFFFFF; //default to blank Block 7 - - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_read(); - - int res = sscanf(Cmd, "%d %x", &block, &password); - - if ( res < 1 || res > 2 ) return usage_t55xx_read(); - - if ((block < 0) | (block > 7)) { + uint8_t block = 255; + uint8_t wake = 0; + uint8_t usepwd = 0; + uint32_t password = 0xFFFFFFFF; //default to blank Block 7 + uint8_t override = 0; + uint8_t cmdp = 0; + bool errors = false; + while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch(param_getchar(Cmd, cmdp)) { + case 'h': + case 'H': + return usage_t55xx_read(); + case 'b': + case 'B': + errors |= param_getdec(Cmd, cmdp+1, &block); + cmdp+=2; + break; + case 'o': + case 'O': + override = 1; + cmdp++; + break; + case 'p': + case 'P': + password = param_get32ex(Cmd, cmdp+1, 0, 10); + usepwd = 1; + cmdp+=2; + break; + case 'w': + case 'W': + wake = 1; + cmdp++; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors) return usage_t55xx_read(); + if (wake && !usepwd) { + PrintAndLog("Wake command must use a pwd"); + return 1; + } + if ((block > 7) && !wake) { PrintAndLog("Block must be between 0 and 7"); return 1; } - UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}}; - c.d.asBytes[0] = 0x0; + UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, password}}; //Password mode - if ( res == 2 ) { - + if ( usepwd || wake ) { // try reading the config block and verify that PWD bit is set before doing this! - AquireData( CONFIGURATION_BLOCK ); - if ( !tryDetectModulation() ) { - PrintAndLog("Could not detect is PWD bit is set in config block. Exits."); - return 1; - } - //if PWD bit is set, allow to execute read command with password. - if (( config.block0 & T55x7_PWD ) == 1) { - c.arg[2] = password; - c.d.asBytes[0] = 0x1; - } else { - PrintAndLog("PWD bit is NOT set in config block. Reading without password..."); + if ( wake || override ) { + c.arg[0] = (wake<<8) & usepwd; + if ( !wake && override ) + PrintAndLog("Safety Check Overriden - proceeding despite risk"); + } else { + AquireData( CONFIGURATION_BLOCK ); + if ( !tryDetectModulation() ) { + PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits."); + return 1; + } else { + PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password..."); + } } } @@ -266,7 +323,11 @@ int CmdT55xxReadBlock(const char *Cmd) { //DemodBufferLen=0; if (!DecodeT55xxBlock()) return 3; char blk[10]={0}; + if ( wake ) { + sprintf(blk,"wake"); + } else { sprintf(blk,"%d", block); + } printT55xxBlock(blk); return 0; } @@ -1074,6 +1135,36 @@ void t55x7_create_config_block( int tagtype ){ } +int CmdT55xxWakeUp(const char *Cmd) { + uint32_t password = 0xFFFFFFFF; //default to blank Block 7 + uint8_t cmdp = 0; + bool errors = false; + while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch(param_getchar(Cmd, cmdp)) { + case 'h': + case 'H': + return usage_t55xx_wakup(); + case 'p': + case 'P': + password = param_get32ex(Cmd, cmdp+1, 0, 10); + cmdp+=2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors) return usage_t55xx_wakup(); + + UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}}; + + clearCommandBuffer(); + SendCommand(&c); + PrintAndLog("Wake up command sent. Try read now"); + return 0; +} + /* uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){ @@ -1100,6 +1191,8 @@ static command_t CommandTable[] = {"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"}, {"dump", CmdT55xxDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"}, {"special", special, 0, "Show block changes with 64 different offsets"}, + {"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"}, + {NULL, NULL, 0, NULL} }; diff --git a/client/hid-flasher/usb_cmd.h b/client/hid-flasher/usb_cmd.h index 8f4eee97..b662b929 100644 --- a/client/hid-flasher/usb_cmd.h +++ b/client/hid-flasher/usb_cmd.h @@ -86,6 +86,8 @@ typedef struct{ #define CMD_T55XX_READ_BLOCK 0x0214 #define CMD_T55XX_WRITE_BLOCK 0x0215 #define CMD_T55XX_READ_TRACE 0x0216 +#define CMD_T55XX_WAKEUP 0x0224 + #define CMD_PCF7931_READ 0x0217 #define CMD_PCF7931_WRITE 0x0223 #define CMD_EM4X_READ_WORD 0x0218 @@ -101,6 +103,7 @@ typedef struct{ #define CMD_AWID_DEMOD_FSK 0x0221 #define CMD_VIKING_CLONE_TAG 0x0222 + /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ // For the 13.56 MHz tags diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 97b40d98..dd5544cb 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -58,6 +58,7 @@ local _commands = { CMD_PSK_SIM_TAG = 0x0220, CMD_AWID_DEMOD_FSK = 0x0221, CMD_VIKING_CLONE_TAG = 0x0222, + CMD_T55XX_WAKEUP = 0x0224, --/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 4a6704c6..114e6d08 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -100,7 +100,7 @@ typedef struct{ #define CMD_PSK_SIM_TAG 0x0220 #define CMD_AWID_DEMOD_FSK 0x0221 #define CMD_VIKING_CLONE_TAG 0x0222 - +#define CMD_T55XX_WAKEUP 0x0224 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ -- 2.39.5 From 2efd63948406db6dc65109c0cd5d79538acdd908 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 20 Oct 2015 19:02:03 +0200 Subject: [PATCH 10/16] CHG: some cleanup of pcf7931.c --- armsrc/pcf7931.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 0dba4fe3..2b23bc36 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -19,8 +19,7 @@ int DemodPCF7931(uint8_t **outBlocks) { int GraphTraceLen = BigBuf_max_traceLen(); if ( GraphTraceLen > 18000 ) GraphTraceLen = 18000; - - + int i, j, lastval, bitidx, half_switch; int clock = 64; int tolerance = clock / 8; @@ -152,10 +151,12 @@ int IsBlock0PCF7931(uint8_t *Block) { int IsBlock1PCF7931(uint8_t *Block) { // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + if( Block[10] == 0 && + Block[11] == 0 && + Block[12] == 0 && + Block[13] == 0) + if ( (Block[14] & 0x7f) <= 9 && Block[15] <= 9) return 1; - return 0; } @@ -279,8 +280,7 @@ void ReadPCF7931() { */ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { - - uint32_t tab[1024]={0}; // data times frame + uint32_t tab[1024] = {0}; // data times frame uint32_t u = 0; uint8_t parity = 0; bool comp = 0; @@ -299,7 +299,6 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui //password indication bit AddBitPCF7931(1, tab, l, p); - //password (on 56 bits) Dbprintf("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", pass1,pass2,pass3,pass4,pass5,pass6,pass7); AddBytePCF7931(pass1, tab, l, p); @@ -366,8 +365,7 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui tab[u]=(tab[u] * 3)/2; } - - //compennsation of the counter reload + //compensation of the counter reload while (!comp){ comp = 1; for(u=0;tab[u]!=0;u++){ @@ -460,9 +458,9 @@ bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){ for (u=0; u<8; u++) { if (byte&(1< Date: Wed, 21 Oct 2015 09:07:36 +0200 Subject: [PATCH 11/16] CHG: move some methods, its easier to read now. Cosmetic change. --- client/cmdlf.c | 244 +++++++++++++++++++++++-------------------------- client/cmdlf.h | 8 ++ 2 files changed, 120 insertions(+), 132 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index f04feb97..c638bb93 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -33,9 +33,7 @@ #include "cmdlfviking.h" static int CmdHelp(const char *Cmd); - -int usage_lf_cmdread() -{ +int usage_lf_cmdread(void) { PrintAndLog("Usage: lf cmdread d z o c [H]"); PrintAndLog("Options: "); PrintAndLog(" h This help"); @@ -50,6 +48,85 @@ int usage_lf_cmdread() PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000 H"); return 0; } +int usage_lf_read(void){ + PrintAndLog("Usage: lf read [h] [s]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" s silent run no printout"); + PrintAndLog("This function takes no arguments. "); + PrintAndLog("Use 'lf config' to set parameters."); + return 0; +} +int usage_lf_snoop(void) { + PrintAndLog("Usage: lf snoop"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog("This function takes no arguments. "); + PrintAndLog("Use 'lf config' to set parameters."); + return 0; +} +int usage_lf_config(void) { + PrintAndLog("Usage: lf config [H|] [b ] [d ] [a 0|1]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" L Low frequency (125 KHz)"); + PrintAndLog(" H High frequency (134 KHz)"); + PrintAndLog(" q Manually set divisor. 88-> 134KHz, 95-> 125 Hz"); + PrintAndLog(" b Sets resolution of bits per sample. Default (max): 8"); + PrintAndLog(" d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); + PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); + PrintAndLog(" t Sets trigger threshold. 0 means no threshold (range: 0-128)"); + PrintAndLog("Examples:"); + PrintAndLog(" lf config b 8 L"); + PrintAndLog(" Samples at 125KHz, 8bps."); + PrintAndLog(" lf config H b 4 d 3"); + PrintAndLog(" Samples at 134KHz, averages three samples into one, stored with "); + PrintAndLog(" a resolution of 4 bits per sample."); + PrintAndLog(" lf read"); + PrintAndLog(" Performs a read (active field)"); + PrintAndLog(" lf snoop"); + PrintAndLog(" Performs a snoop (no active field)"); + return 0; +} +int usage_lf_simfsk(void) { + PrintAndLog("Usage: lf simfsk [c ] [i] [H ] [L ] [d ]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); + PrintAndLog(" i invert data"); + PrintAndLog(" H Manually set the larger Field Clock"); + PrintAndLog(" L Manually set the smaller Field Clock"); + //PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); + PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); + PrintAndLog("\n NOTE: if you set one clock manually set them all manually"); + return 0; +} +int usage_lf_simask(void) { + PrintAndLog("Usage: lf simask [c ] [i] [b|m|r] [s] [d ]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); + PrintAndLog(" i invert data"); + PrintAndLog(" b sim ask/biphase"); + PrintAndLog(" m sim ask/manchester - Default"); + PrintAndLog(" r sim ask/raw"); + PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); + PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); + return 0; +} +int usage_lf_simpsk(void) { + PrintAndLog("Usage: lf simpsk [1|2|3] [c ] [i] [r ] [d ]"); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); + PrintAndLog(" i invert data"); + PrintAndLog(" 1 set PSK1 (default)"); + PrintAndLog(" 2 set PSK2"); + PrintAndLog(" 3 set PSK3"); + PrintAndLog(" r 2|4|8 are valid carriers: default = 2"); + PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); + return 0; +} /* send a LF command before reading */ int CmdLFCommandRead(const char *Cmd) @@ -421,51 +498,6 @@ int CmdIndalaClone(const char *Cmd) return 0; } -int usage_lf_read() -{ - PrintAndLog("Usage: lf read"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" s silent run no printout"); - PrintAndLog("This function takes no arguments. "); - PrintAndLog("Use 'lf config' to set parameters."); - return 0; -} -int usage_lf_snoop() -{ - PrintAndLog("Usage: lf snoop"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog("This function takes no arguments. "); - PrintAndLog("Use 'lf config' to set parameters."); - return 0; -} - -int usage_lf_config() -{ - PrintAndLog("Usage: lf config [H|] [b ] [d ] [a 0|1]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" L Low frequency (125 KHz)"); - PrintAndLog(" H High frequency (134 KHz)"); - PrintAndLog(" q Manually set divisor. 88-> 134KHz, 95-> 125 Hz"); - PrintAndLog(" b Sets resolution of bits per sample. Default (max): 8"); - PrintAndLog(" d Sets decimation. A value of N saves only 1 in N samples. Default: 1"); - PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); - PrintAndLog(" t Sets trigger threshold. 0 means no threshold (range: 0-128)"); - PrintAndLog("Examples:"); - PrintAndLog(" lf config b 8 L"); - PrintAndLog(" Samples at 125KHz, 8bps."); - PrintAndLog(" lf config H b 4 d 3"); - PrintAndLog(" Samples at 134KHz, averages three samples into one, stored with "); - PrintAndLog(" a resolution of 4 bits per sample."); - PrintAndLog(" lf read"); - PrintAndLog(" Performs a read (active field)"); - PrintAndLog(" lf snoop"); - PrintAndLog(" Performs a snoop (no active field)"); - return 0; -} - int CmdLFSetConfig(const char *Cmd) { @@ -545,35 +577,31 @@ int CmdLFSetConfig(const char *Cmd) int CmdLFRead(const char *Cmd) { - - uint8_t cmdp = 0; bool arg1 = false; - if (param_getchar(Cmd, cmdp) == 'h') - { - return usage_lf_read(); - } - if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print - //And ship it to device + uint8_t cmdp = param_getchar(Cmd, 0); + + if ( cmdp == 'h' || cmdp == 'H') return usage_lf_read(); + + //suppress print + if ( cmdp == 's' || cmdp == 'S') arg1 = true; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}}; + clearCommandBuffer(); SendCommand(&c); - //WaitForResponse(CMD_ACK,NULL); if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { PrintAndLog("command execution time out"); return 1; } - return 0; } int CmdLFSnoop(const char *Cmd) { - uint8_t cmdp =0; - if(param_getchar(Cmd, cmdp) == 'h') - { - return usage_lf_snoop(); - } - + uint8_t cmdp = param_getchar(Cmd, 0); + if(cmdp == 'h' || cmdp == 'H') return usage_lf_snoop(); + UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; + clearCommandBuffer(); SendCommand(&c); WaitForResponse(CMD_ACK,NULL); return 0; @@ -595,81 +623,33 @@ static void ChkBitstream(const char *str) // converts GraphBuffer to bitstream (based on zero crossings) if needed. int CmdLFSim(const char *Cmd) { - int i,j; - static int gap; + int i,j; + static int gap; - sscanf(Cmd, "%i", &gap); + sscanf(Cmd, "%i", &gap); // convert to bitstream if necessary - - ChkBitstream(Cmd); + ChkBitstream(Cmd); //can send only 512 bits at a time (1 byte sent per bit...) - printf("Sending [%d bytes]", GraphTraceLen); - for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) { - UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; - - for (j = 0; j < USB_CMD_DATA_SIZE; j++) { - c.d.asBytes[j] = GraphBuffer[i+j]; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - printf("."); - } - - printf("\n"); - PrintAndLog("Starting to simulate"); - UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; - SendCommand(&c); - return 0; -} + printf("Sending [%d bytes]", GraphTraceLen); + for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) { + UsbCommand c = {CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; -int usage_lf_simfsk(void) -{ - //print help - PrintAndLog("Usage: lf simfsk [c ] [i] [H ] [L ] [d ]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); - PrintAndLog(" i invert data"); - PrintAndLog(" H Manually set the larger Field Clock"); - PrintAndLog(" L Manually set the smaller Field Clock"); - //PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); - PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); - PrintAndLog("\n NOTE: if you set one clock manually set them all manually"); - return 0; -} - -int usage_lf_simask(void) -{ - //print help - PrintAndLog("Usage: lf simask [c ] [i] [b|m|r] [s] [d ]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); - PrintAndLog(" i invert data"); - PrintAndLog(" b sim ask/biphase"); - PrintAndLog(" m sim ask/manchester - Default"); - PrintAndLog(" r sim ask/raw"); - PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap"); - PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); - return 0; -} + for (j = 0; j < USB_CMD_DATA_SIZE; j++) { + c.d.asBytes[j] = GraphBuffer[i+j]; + } + clearCommandBuffer(); + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + printf("."); + } -int usage_lf_simpsk(void) -{ - //print help - PrintAndLog("Usage: lf simpsk [1|2|3] [c ] [i] [r ] [d ]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" c Manually set clock - can autodetect if using DemodBuffer"); - PrintAndLog(" i invert data"); - PrintAndLog(" 1 set PSK1 (default)"); - PrintAndLog(" 2 set PSK2"); - PrintAndLog(" 3 set PSK3"); - PrintAndLog(" r 2|4|8 are valid carriers: default = 2"); - PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); - return 0; + PrintAndLog("\nStarting to simulate"); + UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; + clearCommandBuffer(); + SendCommand(&c); + return 0; } // by marshmellow - sim ask data given clock, fcHigh, fcLow, invert diff --git a/client/cmdlf.h b/client/cmdlf.h index 7dd1b044..5dbb9b6e 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -27,4 +27,12 @@ int CmdLFSnoop(const char *Cmd); int CmdVchDemod(const char *Cmd); int CmdLFfind(const char *Cmd); +// usages helptext +int usage_lf_cmdread(void); +int usage_lf_read(void); +int usage_lf_snoop(void); +int usage_lf_config(void); +int usage_lf_simfsk(void); +int usage_lf_simask(void); +int usage_lf_simpsk(void); #endif -- 2.39.5 From 1c8fbeb93e82f6aafb885b57b9afbfadcf85c171 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 21 Oct 2015 09:12:33 +0200 Subject: [PATCH 12/16] ADD: 'LF T55X7 WAKEUP' command. For tags with AOR bit set, send this command with password to wake tag up and be able to do a "LF SEARCH" etc on it. CHG: Minor code changes on T55X7 code. Default password is back to 'FF FF FF FF', REM: removed @marshmellow42 's wakeup option in "lf t55x7 read", --- BASICALLY: if a T55X7 tag has following bits set: AOR - send wakeup command with pwd, to enable LF interacting with it. PWD - send read/write/trace/info command with pwd. No need to send wakeup. --- armsrc/appmain.c | 2 +- armsrc/lfops.c | 63 +++++++++++-------- armsrc/lfsampling.c | 43 +++++++------ client/cmdlft55xx.c | 143 ++++++++++++++++---------------------------- client/cmdlft55xx.h | 2 +- 5 files changed, 113 insertions(+), 140 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 4ccb8edc..8b8f2594 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -921,7 +921,7 @@ void UsbPacketReceived(uint8_t *packet, int len) setSamplingConfig((sample_config *) c->d.asBytes); break; case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: - cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0); + cmd_send(CMD_ACK, SampleLF(c->arg[0]),0,0,0,0); break; case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K: ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index c070b87c..1d452fd3 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1197,7 +1197,8 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // Read one card block in page 0 void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { LED_A_ON(); - uint8_t PwdMode = arg0 & 0xFF; + uint8_t PwdMode = arg0 & 0x01; + uint8_t Page = arg0 & 0x02; uint32_t i = 0; //clear buffer now so it does not interfere with timing later @@ -1215,7 +1216,7 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Opcode 10 T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 + T55xxWriteBit(Page); //Page 0 if (PwdMode){ // Send Pwd @@ -1245,33 +1246,45 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Read card traceability data (page 1) void T55xxReadTrace(void){ - LED_A_ON(); + // LED_A_ON(); - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_ext(false); + // uint8_t PwdMode = arg0 & 0xFF; + // uint32_t i = 0; + + // //clear buffer now so it does not interfere with timing later + // BigBuf_Clear_ext(false); - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); + // // Set up FPGA, 125kHz + // LFSetupFPGAForADC(95, true); - // Trigger T55x7 Direct Access Mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode 11 - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 - - // Turn field on to read the response - TurnReadLFOn(READ_GAP); + // // Trigger T55x7 Direct Access Mode + // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // SpinDelayUs(START_GAP); + + // // Opcode 11 + // T55xxWriteBit(1); + // T55xxWriteBit(1); //Page 1 + + // if (PwdMode){ + // // Send Pwd + // for (i = 0x80000000; i != 0; i >>= 1) + // T55xxWriteBit(Pwd & i); + // } + + // // Send a zero bit separation + // T55xxWriteBit(0); + + // // Turn field on to read the response + // TurnReadLFOn(READ_GAP); - // Acquisition - doT55x7Acquisition(); + // // Acquisition + // doT55x7Acquisition(); - // turn field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); - LED_B_OFF(); + // // turn field off + // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // cmd_send(CMD_ACK,0,0,0,0,0); + // LED_A_OFF(); + // LED_B_OFF(); } void T55xxWakeUp(uint32_t Pwd){ @@ -1294,7 +1307,7 @@ void T55xxWakeUp(uint32_t Pwd){ T55xxWriteBit(Pwd & i); // Turn field on to read the response - TurnReadLFOn(READ_GAP); + TurnReadLFOn(20*1000); } /*-------------- Cloning routines -----------*/ diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 3a70c340..83579cca 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -121,11 +121,11 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) */ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent) { - //. + //bigbuf, to hold the aquired raw data signal uint8_t *dest = BigBuf_get_addr(); - int bufsize = BigBuf_max_traceLen(); + uint16_t bufsize = BigBuf_max_traceLen(); - memset(dest, 0, bufsize); + BigBuf_Clear_ext(false); if(bits_per_sample < 1) bits_per_sample = 1; if(bits_per_sample > 8) bits_per_sample = 8; @@ -244,7 +244,6 @@ uint32_t SampleLF(bool printCfg) * Initializes the FPGA for snoop-mode (field off), and acquires the samples. * @return number of bits sampled **/ - uint32_t SnoopLF() { return ReadLF(false, true); } @@ -256,9 +255,9 @@ uint32_t SnoopLF() { void doT55x7Acquisition(void){ #define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) - #define T55xx_READ_UPPER_THRESHOLD 128+40 // 50 + #define T55xx_UPPER_THRESHOLD 128+40 // 50 #define T55xx_READ_TOL 5 - //#define T55xx_READ_LOWER_THRESHOLD 128-40 //-50 + #define T55xx_LOWER_THRESHOLD 128-40 //-50 uint8_t *dest = BigBuf_get_addr(); uint16_t bufsize = BigBuf_max_traceLen(); @@ -267,39 +266,37 @@ void doT55x7Acquisition(void){ bufsize = T55xx_SAMPLES_SIZE; uint16_t i = 0; - uint16_t nosignal = 0; bool startFound = false; bool highFound = false; - uint8_t curSample = 0; + uint8_t sample = 0; uint8_t firstSample = 0; while(!BUTTON_PRESS()) { - WDT_HIT(); - if ( nosignal == 0xFFFF ) break; - + WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; + AT91C_BASE_SSC->SSC_THR = 0x00; LED_D_ON(); } if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - + sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + // find first high sample - if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { - if (curSample > firstSample) - firstSample = curSample; - highFound = true; + if (!startFound && sample > T55xx_UPPER_THRESHOLD) { + if (sample > firstSample) + firstSample = sample; + highFound = TRUE; } else if (!highFound) { - nosignal++; continue; } // skip until samples begin to change - if (startFound || curSample < firstSample-T55xx_READ_TOL){ + if (startFound || sample < firstSample - T55xx_READ_TOL){ if (!startFound) dest[i++] = firstSample; - startFound = true; - dest[i++] = curSample; - LED_D_OFF(); + startFound = TRUE; + dest[i++] = sample; + + // exit condition. if (i >= bufsize) break; } } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 28956fdc..f3add53d 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -50,12 +50,11 @@ int usage_t55xx_config(){ return 0; } int usage_t55xx_read(){ - PrintAndLog("Usage: lf t55xx read b p "); + PrintAndLog("Usage: lf t55xx read b p "); PrintAndLog("Options:"); PrintAndLog(" b , block number to read. Between 0-7"); PrintAndLog(" p , OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLog(" o, OPTIONAL override safety check"); - PrintAndLog(" w, OPTIONAL wakeup"); PrintAndLog(" ****WARNING****"); PrintAndLog(" Use of read with password on a tag not configured for a pwd"); PrintAndLog(" can damage the tag"); @@ -226,52 +225,42 @@ int CmdT55xxSetConfig(const char *Cmd) { } // No args - if (cmdp == 0) { - printConfiguration( config ); - return 0; - } + if (cmdp == 0) return printConfiguration( config ); + //Validations - if (errors) - return usage_t55xx_config(); + if (errors) return usage_t55xx_config(); config.block0 = 0; - printConfiguration ( config ); - return 0; + return printConfiguration ( config ); } int CmdT55xxReadBlock(const char *Cmd) { uint8_t block = 255; - uint8_t wake = 0; - uint8_t usepwd = 0; - uint32_t password = 0xFFFFFFFF; //default to blank Block 7 - uint8_t override = 0; + uint32_t password = 0; //default to blank Block 7 + bool usepwd = FALSE; + bool override = FALSE; + bool errors = FALSE; uint8_t cmdp = 0; - bool errors = false; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch(param_getchar(Cmd, cmdp)) { case 'h': case 'H': - return usage_t55xx_read(); + return usage_t55xx_read(); case 'b': case 'B': errors |= param_getdec(Cmd, cmdp+1, &block); - cmdp+=2; + cmdp += 2; break; case 'o': case 'O': - override = 1; + override = TRUE; cmdp++; break; case 'p': case 'P': - password = param_get32ex(Cmd, cmdp+1, 0, 10); - usepwd = 1; - cmdp+=2; - break; - case 'w': - case 'W': - wake = 1; - cmdp++; + password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16); + usepwd = TRUE; + cmdp += 2; break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); @@ -280,11 +269,8 @@ int CmdT55xxReadBlock(const char *Cmd) { } } if (errors) return usage_t55xx_read(); - if (wake && !usepwd) { - PrintAndLog("Wake command must use a pwd"); - return 1; - } - if ((block > 7) && !wake) { + + if ( block > 7 ) { PrintAndLog("Block must be between 0 and 7"); return 1; } @@ -292,13 +278,10 @@ int CmdT55xxReadBlock(const char *Cmd) { UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, password}}; //Password mode - if ( usepwd || wake ) { + if ( usepwd ) { + // try reading the config block and verify that PWD bit is set before doing this! - if ( wake || override ) { - c.arg[0] = (wake<<8) & usepwd; - if ( !wake && override ) - PrintAndLog("Safety Check Overriden - proceeding despite risk"); - } else { + if ( !override ) { AquireData( CONFIGURATION_BLOCK ); if ( !tryDetectModulation() ) { PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits."); @@ -306,6 +289,9 @@ int CmdT55xxReadBlock(const char *Cmd) { } else { PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password..."); } + } else { + PrintAndLog("Safety Check Overriden - proceeding despite risk"); + c.arg[0] = usepwd; } } @@ -320,14 +306,11 @@ int CmdT55xxReadBlock(const char *Cmd) { GetFromBigBuf(got,sizeof(got),0); WaitForResponse(CMD_ACK,NULL); setGraphBuf(got, sizeof(got)); - //DemodBufferLen=0; + if (!DecodeT55xxBlock()) return 3; + char blk[10]={0}; - if ( wake ) { - sprintf(blk,"wake"); - } else { - sprintf(blk,"%d", block); - } + sprintf(blk,"%d", block); printT55xxBlock(blk); return 0; } @@ -390,8 +373,7 @@ bool DecodeT55xxBlock(){ int CmdT55xxDetect(const char *Cmd){ char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') - return usage_t55xx_detect(); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_detect(); if (strlen(Cmd)==0) AquireData( CONFIGURATION_BLOCK ); @@ -683,17 +665,17 @@ void printT55xxBlock(const char *blockNum){ } for (; i < endpos; ++i) - bits[i - config.offset]=DemodBuffer[i]; + bits[i - config.offset] = DemodBuffer[i]; blockData = PackBits(0, 32, bits); - PrintAndLog("[%s] 0x%08X %s", blockNum, blockData, sprint_bin(bits,32)); + PrintAndLog("%s | %08X | %s", blockNum, blockData, sprint_bin(bits,32)); } int special(const char *Cmd) { uint32_t blockData = 0; uint8_t bits[32] = {0x00}; - PrintAndLog("[OFFSET] [DATA] [BINARY]"); + PrintAndLog("OFFSET | DATA | BINARY"); PrintAndLog("----------------------------------------------------"); int i,j = 0; for (; j < 64; ++j){ @@ -703,32 +685,29 @@ int special(const char *Cmd) { blockData = PackBits(0, 32, bits); - PrintAndLog("[%02d] 0x%08X %s",j , blockData, sprint_bin(bits,32)); + PrintAndLog("%02d | 0x%08X | %s",j , blockData, sprint_bin(bits,32)); } return 0; } -void printConfiguration( t55xx_conf_block_t b){ +int printConfiguration( t55xx_conf_block_t b){ PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) ); PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) ); PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" ); PrintAndLog("Offset : %d", b.offset); PrintAndLog("Block0 : 0x%08X", b.block0); PrintAndLog(""); + return 0; } -int CmdT55xxWriteBlock(const char *Cmd) -{ +int CmdT55xxWriteBlock(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 char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') { - usage_t55xx_write(); - return 0; - } - + if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_write(); + int res = sscanf(Cmd, "%d %x %x",&block, &data, &password); if ( res < 2 || res > 3) { @@ -762,12 +741,10 @@ int CmdT55xxWriteBlock(const char *Cmd) return 0; } -int CmdT55xxReadTrace(const char *Cmd) -{ +int CmdT55xxReadTrace(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') - return usage_t55xx_trace(); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_trace(); if (strlen(Cmd)==0) AquireData( TRACE_BLOCK ); @@ -852,8 +829,7 @@ int CmdT55xxInfo(const char *Cmd){ */ char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') - return usage_t55xx_info(); + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_info(); if (strlen(Cmd)==0) AquireData( CONFIGURATION_BLOCK ); @@ -909,12 +885,8 @@ int CmdT55xxDump(const char *Cmd){ char s[20] = {0x00}; uint8_t pwd[4] = {0x00}; - char cmdp = param_getchar(Cmd, 0); - if ( cmdp == 'h' || cmdp == 'H') { - usage_t55xx_dump(); - return 0; - } + if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump(); bool hasPwd = ( strlen(Cmd) > 0); if ( hasPwd ){ @@ -937,25 +909,17 @@ int CmdT55xxDump(const char *Cmd){ } int AquireData( uint8_t block ){ - - UsbCommand c; - if ( block == CONFIGURATION_BLOCK ) - c.cmd = CMD_T55XX_READ_BLOCK; - else if (block == TRACE_BLOCK ) - c.cmd = CMD_T55XX_READ_TRACE; - - c.arg[0] = 0x00; - c.arg[1] = 0x00; - c.arg[2] = 0x00; - c.d.asBytes[0] = 0x0; - - //Password mode - // if ( res == 2 ) { - // c.arg[2] = password; - // c.d.asBytes[0] = 0x1; - // } - + uint32_t password = 0; + UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, 0, password}}; + + if ( block == CONFIGURATION_BLOCK ) { + c.arg[0] = 0x00 | 0x01; + } + else if (block == TRACE_BLOCK ) { + c.arg[0] = 0x02 | 0x01; + } + clearCommandBuffer(); SendCommand(&c); if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { @@ -1136,7 +1100,7 @@ void t55x7_create_config_block( int tagtype ){ } int CmdT55xxWakeUp(const char *Cmd) { - uint32_t password = 0xFFFFFFFF; //default to blank Block 7 + uint32_t password = 0; uint8_t cmdp = 0; bool errors = false; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -1146,7 +1110,7 @@ int CmdT55xxWakeUp(const char *Cmd) { return usage_t55xx_wakup(); case 'p': case 'P': - password = param_get32ex(Cmd, cmdp+1, 0, 10); + password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16); cmdp+=2; break; default: @@ -1156,9 +1120,8 @@ int CmdT55xxWakeUp(const char *Cmd) { } } if (errors) return usage_t55xx_wakup(); - - UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}}; + UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}}; clearCommandBuffer(); SendCommand(&c); PrintAndLog("Wake up command sent. Try read now"); diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index d8e516e8..0fe1b0be 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -76,7 +76,7 @@ char * GetModelStrFromCID(uint32_t cid); char * GetSelectedModulationStr( uint8_t id); uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream); void printT55xxBlock(const char *demodStr); -void printConfiguration( t55xx_conf_block_t b); +int printConfiguration( t55xx_conf_block_t b); bool DecodeT55xxBlock(); bool tryDetectModulation(); -- 2.39.5 From 1d0ccbe04b6d04cc4e05aeb9bbcb7b7fa0cfdbd1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Oct 2015 21:47:21 +0100 Subject: [PATCH 13/16] ADD: added the "hf snoop" patch original from @Enio, rearranged by @Etmatrix. ADD: added the "t55x7" refactoring by @marshmellow42 --- armsrc/Makefile | 8 +- armsrc/appmain.c | 10 +- armsrc/apps.h | 6 +- armsrc/fpgaloader.h | 1 + armsrc/hfsnoop.c | 76 +++++++ armsrc/lfops.c | 392 +++++++++-------------------------- armsrc/lfsampling.c | 36 ++-- client/cmdhf.c | 9 + client/cmdhfmfdes.c | 2 +- client/cmdhfmfu.c | 116 ++++++----- client/cmdlft55xx.c | 388 ++++++++++++++++++---------------- client/cmdlft55xx.h | 2 +- client/hid-flasher/usb_cmd.h | 2 + client/lualibs/commands.lua | 5 +- client/scripting.c | 2 +- common/Makefile.common | 3 +- common/lfdemod.c | 10 + common/lfdemod.h | 1 + common/protocols.c | 67 +++--- common/protocols.h | 55 ++++- fpga/Makefile | 2 +- fpga/fpga_hf.v | 34 ++- fpga/hi_sniffer.v | 77 +++++++ include/usb_cmd.h | 2 + 24 files changed, 703 insertions(+), 603 deletions(-) create mode 100644 armsrc/hfsnoop.c create mode 100644 fpga/hi_sniffer.v diff --git a/armsrc/Makefile b/armsrc/Makefile index b6b80c12..ddcff33b 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -10,12 +10,12 @@ APP_INCLUDES = apps.h #remove one of the following defines and comment out the relevant line #in the next section to remove that particular feature from compilation -APP_CFLAGS = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE \ +APP_CFLAGS = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -DWITH_HFSNOOP \ -fno-strict-aliasing -ffunction-sections -fdata-sections #-DWITH_LCD #SRC_LCD = fonts.c LCD.c -SRC_LF = lfops.c hitag2.c lfsampling.c pcf7931.c +SRC_LF = lfops.c hitag2.c lfsampling.c pcf7931.c lfdemod.c protocols.c SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c SRC_ISO14443b = iso14443b.c @@ -52,7 +52,6 @@ THUMBSRC = start.c \ # These are to be compiled in ARM mode ARMSRC = fpgaloader.c \ legicrf.c \ - lfdemod.c \ $(SRC_ISO14443a) \ $(SRC_ISO14443b) \ $(SRC_CRAPTO1) \ @@ -60,7 +59,8 @@ ARMSRC = fpgaloader.c \ legic_prng.c \ iclass.c \ BigBuf.c \ - optimized_cipher.c + optimized_cipher.c \ + hfsnoop.c # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common/Makefile.common diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8b8f2594..b4eab733 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -985,9 +985,6 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_T55XX_WRITE_BLOCK: T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); break; - case CMD_T55XX_READ_TRACE: - T55xxReadTrace(); - break; case CMD_T55XX_WAKEUP: T55xxWakeUp(c->arg[0]); break; @@ -1236,6 +1233,11 @@ void UsbPacketReceived(uint8_t *packet, int len) iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes); break; #endif +#ifdef WITH_HFSNOOP + case CMD_HF_SNIFFER: + HfSnoop(c->arg[0], c->arg[1]); + break; +#endif case CMD_BUFF_CLEAR: BigBuf_Clear(); @@ -1372,7 +1374,7 @@ void __attribute__((noreturn)) AppMain(void) AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0; // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK | - AT91C_PMC_PRES_CLK_4; + AT91C_PMC_PRES_CLK_4; // 4 for 24Mhz pck0, 2 for 48 MHZ pck0 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0; // Reset SPI diff --git a/armsrc/apps.h b/armsrc/apps.h index 7039ab5b..556581f8 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -86,11 +86,10 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an ioPro void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen); void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); -void CopyIndala64toT55x7(int hi, int lo); // Clone Indala 64-bit tag by UID to T55x7 -void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7); // Clone Indala 224-bit tag by UID to T55x7 +void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 +void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode); void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd); -void T55xxReadTrace(void); void T55xxWakeUp(uint32_t Pwd); void TurnReadLFOn(); void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode); @@ -208,5 +207,6 @@ bool cmd_receive(UsbCommand* cmd); bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len); /// util.h +void HfSnoop(int , int); #endif diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 52d6c677..35f7e37c 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -43,6 +43,7 @@ void SetAdcMuxFor(uint32_t whichGpio); #define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5) #define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5) #define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5) +#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5) // BOTH #define FPGA_MAJOR_MODE_OFF (7<<5) // Options for LF_ADC diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c new file mode 100644 index 00000000..b7d69013 --- /dev/null +++ b/armsrc/hfsnoop.c @@ -0,0 +1,76 @@ +#include "proxmark3.h" +#include "apps.h" +#include "BigBuf.h" +#include "util.h" + +static void RAMFUNC optimizedSnoop(void); + +static void RAMFUNC optimizedSnoop(void) +{ + BigBuf_free(); + int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory + + uint16_t *dest = (uint16_t *)BigBuf_get_addr(); + uint16_t *destend = dest + n; + + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); // Setting Frame mode, 16 bits per word + // Reading data loop + while(dest <= destend) + { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) + { + *dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); + dest = dest + 1; + } + } + //Resetting Frame mode (First set in fpgaloader.c) + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); +} + +void HfSnoop(int samplesToSkip, int triggersToSkip) +{ + Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); + bool trigger_cnt; + LED_D_ON(); + // Select correct configs + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // Set up the synchronous serial port + FpgaSetupSsc(); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP); + SpinDelay(100); + + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); // Setting Frame Mode For better performance on high speed data transfer. + + trigger_cnt = 0; + uint16_t r = 0; + while(!BUTTON_PRESS()) { + WDT_HIT(); + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + r = (uint16_t)AT91C_BASE_SSC->SSC_RHR; + if (!(trigger_cnt == triggersToSkip) && ( (r >> 8) >= 240)) + { + Dbprintf("Trigger kicked! Value: %d.", r >> 8); + trigger_cnt++; + break; + } + } + } + if(!BUTTON_PRESS()) { + Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r >> 8); + int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0 + while(waitcount != 0) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + waitcount--; + } + } + + optimizedSnoop(); + } + + DbpString("HF Snoop end"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); +} + diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 1d452fd3..0472122a 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -16,8 +16,8 @@ #include "string.h" #include "lfdemod.h" #include "lfsampling.h" -#include "usb_cdc.h" - +#include "protocols.h" +#include "usb_cdc.h" //test /** * Function to do a modulation and then get samples. @@ -1053,61 +1053,9 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) /*------------------------------ * T5555/T5557/T5567 routines *------------------------------ - */ - -/* T55x7 configuration register definitions */ -#define T55x7_POR_DELAY 0x00000001 -#define T55x7_ST_TERMINATOR 0x00000008 -#define T55x7_PWD 0x00000010 -#define T55x7_MAXBLOCK_SHIFT 5 -#define T55x7_AOR 0x00000200 -#define T55x7_PSKCF_RF_2 0 -#define T55x7_PSKCF_RF_4 0x00000400 -#define T55x7_PSKCF_RF_8 0x00000800 -#define T55x7_MODULATION_DIRECT 0 -#define T55x7_MODULATION_PSK1 0x00001000 -#define T55x7_MODULATION_PSK2 0x00002000 -#define T55x7_MODULATION_PSK3 0x00003000 -#define T55x7_MODULATION_FSK1 0x00004000 -#define T55x7_MODULATION_FSK2 0x00005000 -#define T55x7_MODULATION_FSK1a 0x00006000 -#define T55x7_MODULATION_FSK2a 0x00007000 -#define T55x7_MODULATION_MANCHESTER 0x00008000 -#define T55x7_MODULATION_BIPHASE 0x00010000 -#define T55x7_MODULATION_DIPHASE 0x00018000 -//#define T55x7_MODULATION_BIPHASE57 0x00011000 -#define T55x7_BITRATE_RF_8 0 -#define T55x7_BITRATE_RF_16 0x00040000 -#define T55x7_BITRATE_RF_32 0x00080000 -#define T55x7_BITRATE_RF_40 0x000C0000 -#define T55x7_BITRATE_RF_50 0x00100000 -#define T55x7_BITRATE_RF_64 0x00140000 -#define T55x7_BITRATE_RF_100 0x00180000 -#define T55x7_BITRATE_RF_128 0x001C0000 - -/* T5555 (Q5) configuration register definitions */ -#define T5555_ST_TERMINATOR 0x00000001 -#define T5555_MAXBLOCK_SHIFT 0x00000001 -#define T5555_MODULATION_MANCHESTER 0 -#define T5555_MODULATION_PSK1 0x00000010 -#define T5555_MODULATION_PSK2 0x00000020 -#define T5555_MODULATION_PSK3 0x00000030 -#define T5555_MODULATION_FSK1 0x00000040 -#define T5555_MODULATION_FSK2 0x00000050 -#define T5555_MODULATION_BIPHASE 0x00000060 -#define T5555_MODULATION_DIRECT 0x00000070 -#define T5555_INVERT_OUTPUT 0x00000080 -#define T5555_PSK_RF_2 0 -#define T5555_PSK_RF_4 0x00000100 -#define T5555_PSK_RF_8 0x00000200 -#define T5555_USE_PWD 0x00000400 -#define T5555_USE_AOR 0x00000800 -#define T5555_BITRATE_SHIFT 12 -#define T5555_FAST_WRITE 0x00004000 -#define T5555_PAGE_SELECT 0x00008000 - -/* - * Relevant times in microsecond + * NOTE: T55x7/T5555 configuration register definitions moved to protocols.h + * + * Relevant communication times in microsecond * To compensate antenna falling times shorten the write times * and enlarge the gap ones. * Q5 tags seems to have issues when these values changes. @@ -1136,24 +1084,29 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) void TurnReadLFOn(int delay) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // Give it a bit of time for the resonant antenna to settle. - SpinDelayUs(delay); //155*8 //50*8 + + // measure antenna strength. + //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); + // where to save it + + SpinDelayUs(delay); } // Write one bit to card void T55xxWriteBit(int bit) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); if (!bit) - SpinDelayUs(WRITE_0); + TurnReadLFOn(WRITE_0); else - SpinDelayUs(WRITE_1); + TurnReadLFOn(WRITE_1); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock -void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { +void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) { LED_A_ON(); - + bool PwdMode = arg & 0x1; + uint8_t Page = (arg & 0x2)>>1; uint32_t i = 0; // Set up FPGA, 125kHz @@ -1165,8 +1118,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // Opcode 10 T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - + T55xxWriteBit(Page); //Page 0 if (PwdMode){ // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) @@ -1186,20 +1138,24 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, // so wait a little more) TurnReadLFOn(20 * 1000); + //could attempt to do a read to confirm write took + // as the tag should repeat back the new block + // until it is reset, but to confirm it we would + // need to know the current block 0 config mode // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); LED_A_OFF(); - LED_B_OFF(); } // Read one card block in page 0 void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { LED_A_ON(); - uint8_t PwdMode = arg0 & 0x01; - uint8_t Page = arg0 & 0x02; + bool PwdMode = arg0 & 0x1; + uint8_t Page = (arg0 & 0x2) >> 1; uint32_t i = 0; + bool RegReadMode = (Block == 0xFF); //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); @@ -1207,14 +1163,14 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { //make sure block is at max 7 Block &= 0x7; - // Set up FPGA, 125kHz + // Set up FPGA, 125kHz to power up the tag LFSetupFPGAForADC(95, true); - // Trigger T55x7 Direct Access Mode + // Trigger T55x7 Direct Access Mode with start gap FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); - // Opcode 10 + // Opcode 1[page] T55xxWriteBit(1); T55xxWriteBit(Page); //Page 0 @@ -1223,11 +1179,11 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } - // Send a zero bit separation T55xxWriteBit(0); - // Send Block number + // Send Block number (if direct access mode) + if (!RegReadMode) for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); @@ -1237,54 +1193,10 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // Acquisition doT55x7Acquisition(); - // turn field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Turn the field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off cmd_send(CMD_ACK,0,0,0,0,0); LED_A_OFF(); - LED_B_OFF(); -} - -// Read card traceability data (page 1) -void T55xxReadTrace(void){ - // LED_A_ON(); - - // uint8_t PwdMode = arg0 & 0xFF; - // uint32_t i = 0; - - // //clear buffer now so it does not interfere with timing later - // BigBuf_Clear_ext(false); - - // // Set up FPGA, 125kHz - // LFSetupFPGAForADC(95, true); - - // // Trigger T55x7 Direct Access Mode - // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // SpinDelayUs(START_GAP); - - // // Opcode 11 - // T55xxWriteBit(1); - // T55xxWriteBit(1); //Page 1 - - // if (PwdMode){ - // // Send Pwd - // for (i = 0x80000000; i != 0; i >>= 1) - // T55xxWriteBit(Pwd & i); - // } - - // // Send a zero bit separation - // T55xxWriteBit(0); - - // // Turn field on to read the response - // TurnReadLFOn(READ_GAP); - - // // Acquisition - // doT55x7Acquisition(); - - // // turn field off - // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // cmd_send(CMD_ACK,0,0,0,0,0); - // LED_A_OFF(); - // LED_B_OFF(); } void T55xxWakeUp(uint32_t Pwd){ @@ -1306,16 +1218,23 @@ void T55xxWakeUp(uint32_t Pwd){ for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); - // Turn field on to read the response + // Turn and leave field on to let the begin repeating transmission TurnReadLFOn(20*1000); } /*-------------- Cloning routines -----------*/ + +void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { + // write last block first and config block last (if included) + for (uint8_t i = numblocks; i > startblock; i--) + T55xxWriteBlock(blockdata[i-1],i-1,0,0); +} + // Copy HID id to card and setup block 0 config -void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) -{ - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; +void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { + uint32_t data[] = {0,0,0,0,0,0,0}; + //int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + uint8_t last_block = 0; if (longFMT){ // Ensure no more than 84 bits supplied @@ -1325,108 +1244,34 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) } // Build the 6 data blocks for supplied 84bit ID last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - else { + // load preamble (1D) & long format identifier (9E manchester encoded) + data[1] = 0x1D96A900 | manchesterEncode2Bytes((hi2 >> 16) & 0xF); + // load raw id from hi2, hi, lo to data blocks (manchester encoded) + data[2] = manchesterEncode2Bytes(hi2 & 0xFFFF); + data[3] = manchesterEncode2Bytes(hi >> 16); + data[4] = manchesterEncode2Bytes(hi & 0xFFFF); + data[5] = manchesterEncode2Bytes(lo >> 16); + data[6] = manchesterEncode2Bytes(lo & 0xFFFF); + } else { // Ensure no more than 44 bits supplied if (hi>0xFFF) { DbpString("Tags can only have 44 bits."); return; } - // Build the 3 data blocks for supplied 44bit ID last_block = 3; - - data1 = 0x1D000000; // load preamble - - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } + // load preamble + data[1] = 0x1D000000 | manchesterEncode2Bytes(hi & 0xFFF); + data[2] = manchesterEncode2Bytes(lo >> 16); + data[3] = manchesterEncode2Bytes(lo & 0xFFFF); } + // load chip config block + data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT; LED_D_ON(); // Program the data blocks for supplied ID // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); - - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); - } - - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); + WriteT55xx(data, 0, last_block+1); LED_D_OFF(); @@ -1435,24 +1280,42 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format - - data1 = hi; // load preamble - data2 = lo; + uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; LED_D_ON(); // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); + // and the block 0 config + WriteT55xx(data, 0, 3); - //Config Block - T55xxWriteBlock(0x00147040,0,0,0); LED_D_OFF(); DbpString("DONE!"); } +// Clone Indala 64-bit tag by UID to T55x7 +void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) { + //Program the 2 data blocks for supplied 64bit UID + // and the Config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) + uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; + WriteT55xx(data, 0, 3); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); + DbpString("DONE!"); +} +// Clone Indala 224-bit tag by UID to T55x7 +void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7) +{ + //Program the 7 data blocks for supplied 224bit UID + uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7}; + // and the block 0 for Indala224 format + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (7 << T55x7_MAXBLOCK_SHIFT); + WriteT55xx(data, 0, 8); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); + DbpString("DONE!"); +} + // Define 9bit header for EM410x tags #define EM410X_HEADER 0x1FF #define EM410X_ID_LENGTH 40 @@ -1518,94 +1381,29 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) LED_D_ON(); // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); - - // Config for EM410x (RF/64, Manchester, Maxblock=2) + uint32_t data[] = {0, id>>32, id & 0xFFFF}; if (card) { - // Clock rate is stored in bits 8-15 of the card value clock = (card & 0xFF00) >> 8; + clock = (clock == 0) ? 64 : clock; Dbprintf("Clock rate: %d", clock); - switch (clock) { - case 50: - clock = T55x7_BITRATE_RF_50; - case 40: - clock = T55x7_BITRATE_RF_40; - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: + clock = GetT55xxClockBit(clock); + if (clock == 0) { Dbprintf("Invalid clock rate: %d", clock); return; } - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); + data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT); + } else { + data[0] = (0x1F << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT); } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); + + WriteT55xx(data, 0, 3); LED_D_OFF(); Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", (uint32_t)(id >> 32), (uint32_t)id); } -// Clone Indala 64-bit tag by UID to T55x7 -void CopyIndala64toT55x7(int hi, int lo) -{ - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); - - DbpString("DONE!"); -} - -void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) -{ - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - - DbpString("DONE!"); -} - //----------------------------------- // EM4469 / EM4305 routines //----------------------------------- diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 83579cca..2a763a50 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -255,9 +255,8 @@ uint32_t SnoopLF() { void doT55x7Acquisition(void){ #define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) - #define T55xx_UPPER_THRESHOLD 128+40 // 50 + #define T55xx_READ_UPPER_THRESHOLD 128+40 // 50 #define T55xx_READ_TOL 5 - #define T55xx_LOWER_THRESHOLD 128-40 //-50 uint8_t *dest = BigBuf_get_addr(); uint16_t bufsize = BigBuf_max_traceLen(); @@ -265,40 +264,43 @@ void doT55x7Acquisition(void){ if ( bufsize > T55xx_SAMPLES_SIZE ) bufsize = T55xx_SAMPLES_SIZE; + //int adcval = 0; uint16_t i = 0; bool startFound = false; bool highFound = false; - uint8_t sample = 0; + uint8_t curSample = 0; uint8_t firstSample = 0; - while(!BUTTON_PRESS()) { + uint16_t skipCnt = 0; + while(!BUTTON_PRESS() && skipCnt<1000) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x00; + AT91C_BASE_SSC->SSC_THR = 0x43; LED_D_ON(); } if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; LED_D_OFF(); // find first high sample - if (!startFound && sample > T55xx_UPPER_THRESHOLD) { - if (sample > firstSample) - firstSample = sample; - highFound = TRUE; + if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { + if (curSample > firstSample) + firstSample = curSample; + highFound = true; } else if (!highFound) { + skipCnt++; continue; } // skip until samples begin to change - if (startFound || sample < firstSample - T55xx_READ_TOL){ + if (startFound || curSample < firstSample-T55xx_READ_TOL){ if (!startFound) dest[i++] = firstSample; - startFound = TRUE; - dest[i++] = sample; - - // exit condition. - if (i >= bufsize) break; + startFound = true; + dest[i++] = curSample; + if (i >= bufsize-1) break; } } + } -} \ No newline at end of file +} + \ No newline at end of file diff --git a/client/cmdhf.c b/client/cmdhf.c index 4a871586..d0b1f01c 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -736,6 +736,14 @@ int CmdHFSearch(const char *Cmd){ return 0; } +int CmdHFSnoop(const char *Cmd) +{ + char * pEnd; + UsbCommand c = {CMD_HF_SNIFFER, {strtol(Cmd, &pEnd,0),strtol(pEnd, &pEnd,0),0}}; + SendCommand(&c); + return 0; +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, @@ -752,6 +760,7 @@ static command_t CommandTable[] = {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"}, {"list", CmdHFList, 1, "List protocol data in trace buffer"}, {"search", CmdHFSearch, 1, "Search for known HF tags [preliminary]"}, + {"snoop", CmdHFSnoop, 0, " Generic LF/HF Snoop in Testing stage"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index fd06791f..4aeeffd9 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -611,7 +611,7 @@ int CmdHF14ADesAuth(const char *Cmd){ c.d.asBytes[0] = keylength; memcpy(c.d.asBytes+1, key, keylength); - + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 5bb9a91e..07609339 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1209,7 +1209,49 @@ int usage_hf_mfu_eload(void) { return 0; } +int usage_hf_mfu_ucauth(void) { + PrintAndLog("Usage: hf mfu cauth k "); + PrintAndLog(" 0 (default): 3DES standard key"); + PrintAndLog(" 1 : all 0x00 key"); + PrintAndLog(" 2 : 0x00-0x0F key"); + PrintAndLog(" 3 : nfc key"); + PrintAndLog(" 4 : all 0x01 key"); + PrintAndLog(" 5 : all 0xff key"); + PrintAndLog(" 6 : 0x00-0xFF key"); + PrintAndLog("\n sample : hf mfu cauth k"); + PrintAndLog(" : hf mfu cauth k 3"); + return 0; +} + +int usage_hf_mfu_ucsetpwd(void) { + PrintAndLog("Usage: hf mfu setpwd "); + PrintAndLog(" [password] - (32 hex symbols)"); + PrintAndLog(""); + PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f"); + PrintAndLog(""); + return 0; +} + +int usage_hf_mfu_ucsetuid(void) { + PrintAndLog("Usage: hf mfu setuid "); + PrintAndLog(" [uid] - (14 hex symbols)"); + PrintAndLog("\nThis only works for Magic Ultralight tags."); + PrintAndLog(""); + PrintAndLog("sample: hf mfu setuid 11223344556677"); + PrintAndLog(""); + return 0; +} + +int usage_hf_mfu_gendiverse(void){ + PrintAndLog("Usage: hf mfu gen "); + PrintAndLog(""); + PrintAndLog("sample: hf mfu gen 11223344"); + PrintAndLog(""); + return 0; +} + // + // Mifare Ultralight / Ultralight-C / Ultralight-EV1 // Read and Dump Card Contents, using auto detection of tag size. int CmdHF14AMfUDump(const char *Cmd){ @@ -1455,6 +1497,7 @@ int CmdHF14AMfUDump(const char *Cmd){ // Ultralight C Methods //------------------------------------------------------------------------------- + // // Ultralight C Authentication Demo {currently uses hard-coded key} // @@ -1472,22 +1515,9 @@ int CmdHF14AMfucAuth(const char *Cmd){ errors = true; } - if (cmdp == 'h' || cmdp == 'H') - errors = true; + if (cmdp == 'h' || cmdp == 'H') errors = true; - if (errors) { - PrintAndLog("Usage: hf mfu cauth k "); - PrintAndLog(" 0 (default): 3DES standard key"); - PrintAndLog(" 1 : all 0x00 key"); - PrintAndLog(" 2 : 0x00-0x0F key"); - PrintAndLog(" 3 : nfc key"); - PrintAndLog(" 4 : all 0x01 key"); - PrintAndLog(" 5 : all 0xff key"); - PrintAndLog(" 6 : 0x00-0xFF key"); - PrintAndLog("\n sample : hf mfu cauth k"); - PrintAndLog(" : hf mfu cauth k 3"); - return 0; - } + if (errors) return usage_hf_mfu_ucauth(); uint8_t *key = default_3des_keys[keyNo]; if (ulc_authentication(key, true)) @@ -1601,17 +1631,9 @@ int CmdTestDES(const char * cmd) int CmdHF14AMfucSetPwd(const char *Cmd){ uint8_t pwd[16] = {0x00}; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: hf mfu setpwd "); - PrintAndLog(" [password] - (32 hex symbols)"); - PrintAndLog(""); - PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f"); - PrintAndLog(""); - return 0; - } + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd(); if (param_gethex(Cmd, 0, pwd, 32)) { PrintAndLog("Password must include 32 HEX symbols"); @@ -1624,7 +1646,6 @@ int CmdHF14AMfucSetPwd(const char *Cmd){ SendCommand(&c); UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { if ( (resp.arg[0] & 0xff) == 1) PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16)); @@ -1636,8 +1657,7 @@ int CmdHF14AMfucSetPwd(const char *Cmd){ else { PrintAndLog("command execution time out"); return 1; - } - + } return 0; } @@ -1650,17 +1670,8 @@ int CmdHF14AMfucSetUid(const char *Cmd){ UsbCommand resp; uint8_t uid[7] = {0x00}; char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: hf mfu setuid "); - PrintAndLog(" [uid] - (14 hex symbols)"); - PrintAndLog("\nThis only works for Magic Ultralight tags."); - PrintAndLog(""); - PrintAndLog("sample: hf mfu setuid 11223344556677"); - PrintAndLog(""); - return 0; - } - + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid(); + if (param_gethex(Cmd, 0, uid, 14)) { PrintAndLog("UID must include 14 HEX symbols"); return 1; @@ -1724,14 +1735,20 @@ int CmdHF14AMfucSetUid(const char *Cmd){ } int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ + + uint8_t uid[4]; + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_gendiverse(); + + if (param_gethex(Cmd, 0, uid, 8)) { + PrintAndLog("UID must include 8 HEX symbols"); + return 1; + } uint8_t iv[8] = { 0x00 }; - uint8_t block = 0x07; + uint8_t block = 0x01; - // UL-EV1 - //04 57 b6 e2 05 3f 80 UID - //4a f8 4b 19 PWD - uint8_t uid[] = { 0xF4,0xEA, 0x54, 0x8E }; uint8_t mifarekeyA[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 }; uint8_t mifarekeyB[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 }; uint8_t dkeyA[8] = { 0x00 }; @@ -1760,15 +1777,13 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ , divkey // output ); - PrintAndLog("3DES version"); + PrintAndLog("-- 3DES version"); PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey,sizeof(masterkey))); PrintAndLog("UID :\t %s", sprint_hex(uid, sizeof(uid))); - PrintAndLog("Sector :\t %0d", block); + PrintAndLog("block :\t %0d", block); PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA))); PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix))); PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6)); - - PrintAndLog("\n DES version"); for (int i=0; i < sizeof(mifarekeyA); ++i){ dkeyA[i] = (mifarekeyA[i] << 1) & 0xff; @@ -1798,20 +1813,19 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ , newpwd // output ); + PrintAndLog("\n-- DES version"); PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA))); PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB))); PrintAndLog("Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey))); PrintAndLog("Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd))); + // next. from the diversify_key method. return 0; } // static uint8_t * diversify_key(uint8_t * key){ - // for(int i=0; i<16; i++){ - // if(i<=6) key[i]^=cuid[i]; - // if(i>6) key[i]^=cuid[i%7]; - // } + // return key; // } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index f3add53d..100170e3 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -26,9 +26,11 @@ #include "../common/iso14443crc.h" #include "cmdhf14a.h" -#define CONFIGURATION_BLOCK 0x00 -#define TRACE_BLOCK 0x01 +#define T55x7_CONFIGURATION_BLOCK 0x00 +#define T55x7_PAGE0 0x00 +#define T55x7_PAGE1 0x01 #define T55x7_PWD 0x00000010 +#define REGULAR_READ_MODE_BLOCK 0xFF // Default configuration t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00}; @@ -50,11 +52,12 @@ int usage_t55xx_config(){ return 0; } int usage_t55xx_read(){ - PrintAndLog("Usage: lf t55xx read b p "); + PrintAndLog("Usage: lf t55xx read [b ] [p ] "); PrintAndLog("Options:"); - PrintAndLog(" b , block number to read. Between 0-7"); - PrintAndLog(" p , OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLog(" o, OPTIONAL override safety check"); + PrintAndLog(" b - block number to read. Between 0-7"); + PrintAndLog(" p - OPTIONAL password (8 hex characters)"); + PrintAndLog(" o - OPTIONAL override safety check"); + PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0"); PrintAndLog(" ****WARNING****"); PrintAndLog(" Use of read with password on a tag not configured for a pwd"); PrintAndLog(" can damage the tag"); @@ -67,22 +70,23 @@ int usage_t55xx_read(){ return 0; } int usage_t55xx_write(){ - PrintAndLog("Usage: lf t55xx write [password]"); + PrintAndLog("Usage: lf t55xx wr [b ] [d ] [p ] [1]"); PrintAndLog("Options:"); - PrintAndLog(" , block number to write. Between 0-7"); - PrintAndLog(" , 4 bytes of data to write (8 hex symbols)"); - PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLog(" b - block number to write. Between 0-7"); + PrintAndLog(" d - 4 bytes of data to write (8 hex characters)"); + PrintAndLog(" p - OPTIONAL password 4bytes (8 hex characters)"); + PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLog(""); PrintAndLog("Examples:"); - PrintAndLog(" lf t55xx write 3 11223344 - write 11223344 to block 3"); - PrintAndLog(" lf t55xx write 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef"); + PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); + PrintAndLog(" lf t55xx write b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef"); PrintAndLog(""); return 0; } int usage_t55xx_trace() { PrintAndLog("Usage: lf t55xx trace [1]"); PrintAndLog("Options:"); - PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); + PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag."); PrintAndLog(""); PrintAndLog("Examples:"); PrintAndLog(" lf t55xx trace"); @@ -93,7 +97,7 @@ int usage_t55xx_trace() { int usage_t55xx_info() { PrintAndLog("Usage: lf t55xx info [1]"); PrintAndLog("Options:"); - PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); + PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag."); PrintAndLog(""); PrintAndLog("Examples:"); PrintAndLog(" lf t55xx info"); @@ -102,20 +106,21 @@ int usage_t55xx_info() { return 0; } int usage_t55xx_dump(){ - PrintAndLog("Usage: lf t55xx dump "); + PrintAndLog("Usage: lf t55xx dump [o]"); PrintAndLog("Options:"); - PrintAndLog(" , OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLog(" - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLog(" o - OPTIONAL override, force pwd read despite danger to card"); PrintAndLog(""); PrintAndLog("Examples:"); PrintAndLog(" lf t55xx dump"); - PrintAndLog(" lf t55xx dump feedbeef"); + PrintAndLog(" lf t55xx dump feedbeef o"); PrintAndLog(""); return 0; } int usage_t55xx_detect(){ PrintAndLog("Usage: lf t55xx detect [1]"); PrintAndLog("Options:"); - PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); + PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag."); PrintAndLog(""); PrintAndLog("Examples:"); PrintAndLog(" lf t55xx detect"); @@ -146,8 +151,7 @@ int CmdT55xxSetConfig(const char *Cmd) { char tmp = 0x00; uint8_t bitRate = 0; uint8_t rates[9] = {8,16,32,40,50,64,100,128,0}; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) - { + while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { tmp = param_getchar(Cmd, cmdp); switch(tmp) { @@ -234,12 +238,43 @@ int CmdT55xxSetConfig(const char *Cmd) { return printConfiguration ( config ); } +int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){ + //Password mode + if ( usepwd ) { + // try reading the config block and verify that PWD bit is set before doing this! + if ( !override ) { + + if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0 ) ) return 0; + + if ( !tryDetectModulation() ) { + PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits."); + return 0; + } else { + PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password..."); + usepwd = false; + page1 = false; + } + } else { + PrintAndLog("Safety Check Overriden - proceeding despite risk"); + } + } + + if (!AquireData(page1, block, usepwd, password) ) return 0; + if (!DecodeT55xxBlock()) return 0; + + char blk[10]={0}; + sprintf(blk,"%d", block); + printT55xxBlock(blk); + return 1; +} + int CmdT55xxReadBlock(const char *Cmd) { - uint8_t block = 255; + uint8_t block = REGULAR_READ_MODE_BLOCK; uint32_t password = 0; //default to blank Block 7 - bool usepwd = FALSE; - bool override = FALSE; - bool errors = FALSE; + bool usepwd = false; + bool override = false; + bool page1 = false; + bool errors = false; uint8_t cmdp = 0; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch(param_getchar(Cmd, cmdp)) { @@ -258,10 +293,14 @@ int CmdT55xxReadBlock(const char *Cmd) { break; case 'p': case 'P': - password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16); - usepwd = TRUE; + password = param_get32ex(Cmd, cmdp+1, 0, 16); + usepwd = true; cmdp += 2; break; + case '1': + page1 = true; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -270,49 +309,13 @@ int CmdT55xxReadBlock(const char *Cmd) { } if (errors) return usage_t55xx_read(); - if ( block > 7 ) { + if (block > 7 && block != REGULAR_READ_MODE_BLOCK ) { PrintAndLog("Block must be between 0 and 7"); - return 1; - } - - UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, password}}; - - //Password mode - if ( usepwd ) { - - // try reading the config block and verify that PWD bit is set before doing this! - if ( !override ) { - AquireData( CONFIGURATION_BLOCK ); - if ( !tryDetectModulation() ) { - PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits."); - return 1; - } else { - PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password..."); - } - } else { - PrintAndLog("Safety Check Overriden - proceeding despite risk"); - c.arg[0] = usepwd; - } - } - - clearCommandBuffer(); - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { - PrintAndLog("command execution time out"); - return 2; + return 0; } - - uint8_t got[12000]; - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); - setGraphBuf(got, sizeof(got)); - - if (!DecodeT55xxBlock()) return 3; - - char blk[10]={0}; - sprintf(blk,"%d", block); - printT55xxBlock(blk); - return 0; + PrintAndLog("Reading Page %d:", page1); + PrintAndLog("blk | hex data | binary"); + return T55xxReadBlock(block, page1, usepwd, override, password); } bool DecodeT55xxBlock(){ @@ -323,9 +326,6 @@ bool DecodeT55xxBlock(){ uint8_t bitRate[8] = {8,16,32,40,50,64,100,128}; DemodBufferLen = 0x00; - //trim 1/2 a clock from beginning - //snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 ); - //CmdLtrim(cmdStr); switch( config.modulation ){ case DEMOD_FSK: snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted ); @@ -372,21 +372,36 @@ bool DecodeT55xxBlock(){ int CmdT55xxDetect(const char *Cmd){ + bool override = false; + //bool pwdmode = false; + + uint32_t password = 0; //default to blank Block 7 + bool usepwd = ( strlen(Cmd) > 0); + if ( usepwd ){ + password = param_get32ex(Cmd, 0, 0, 16); + if (param_getchar(Cmd, 1) =='o' ) + override = true; + } + char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_detect(); - if (strlen(Cmd)==0) - AquireData( CONFIGURATION_BLOCK ); + if (strlen(Cmd)==0) { + password = param_get32ex(Cmd, 0, 0, 16); + if (param_getchar(Cmd, 1) =='o' ) override = true; + } + if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password) ) + return 0; + if ( !tryDetectModulation() ) PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); - return 0; + return 1; } // detect configuration? bool tryDetectModulation(){ - //char cmdStr[8] = {0}; uint8_t hits = 0; t55xx_conf_block_t tests[15]; int bitRate=0; @@ -394,8 +409,6 @@ bool tryDetectModulation(){ save_restoreGB(1); if (GetFskClock("", FALSE, FALSE)){ fskClocks(&fc1, &fc2, &clk, FALSE); - //sprintf(cmdStr,"%d", clk/2); - //CmdLtrim(cmdStr); if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){ tests[hits].modulation = DEMOD_FSK; if (fc1==8 && fc2 == 5) @@ -422,8 +435,6 @@ bool tryDetectModulation(){ } else { clk = GetAskClock("", FALSE, FALSE); if (clk>0) { - //sprintf(cmdStr,"%d", clk/2); - //CmdLtrim(cmdStr); if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_ASK; tests[hits].bitrate = bitRate; @@ -457,8 +468,6 @@ bool tryDetectModulation(){ save_restoreGB(0); clk = GetNrzClock("", FALSE, FALSE); if (clk>0) { - //sprintf(cmdStr,"%d", clk/2); - //CmdLtrim(cmdStr); if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_NRZ; tests[hits].bitrate = bitRate; @@ -480,9 +489,6 @@ bool tryDetectModulation(){ save_restoreGB(0); clk = GetPskClock("", FALSE, FALSE); if (clk>0) { - //PrintAndLog("clk %d",clk); - //sprintf(cmdStr,"%d", clk/2); - //CmdLtrim(cmdStr); if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_PSK1; tests[hits].bitrate = bitRate; @@ -700,66 +706,126 @@ int printConfiguration( t55xx_conf_block_t b){ return 0; } +int CmdT55xxWakeUp(const char *Cmd) { + uint32_t password = 0; + uint8_t cmdp = 0; + bool errors = false; + while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch(param_getchar(Cmd, cmdp)) { + case 'h': + case 'H': + return usage_t55xx_wakup(); + case 'p': + case 'P': + password = param_get32ex(Cmd, cmdp+1, 0, 16); + cmdp += 2; + errors = false; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors) return usage_t55xx_wakup(); + + UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}}; + clearCommandBuffer(); + SendCommand(&c); + PrintAndLog("Wake up command sent. Try read now"); + return 0; +} + int CmdT55xxWriteBlock(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 - - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_write(); - - int res = sscanf(Cmd, "%d %x %x",&block, &data, &password); - - if ( res < 2 || res > 3) { - usage_t55xx_write(); - return 1; + uint8_t block = 0xFF; //default to invalid block + uint32_t data = 0; //default to blank Block + uint32_t password = 0; //default to blank Block 7 + bool usepwd = false; + bool page1 = false; + bool gotdata = false; + bool errors = false; + uint8_t cmdp = 0; + while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch(param_getchar(Cmd, cmdp)) { + case 'h': + case 'H': + return usage_t55xx_write(); + case 'b': + case 'B': + errors |= param_getdec(Cmd, cmdp+1, &block); + cmdp += 2; + break; + case 'd': + case 'D': + data = param_get32ex(Cmd, cmdp+1, 0, 16); + gotdata = true; + cmdp += 2; + break; + case 'p': + case 'P': + password = param_get32ex(Cmd, cmdp+1, 0, 16); + usepwd = true; + cmdp += 2; + break; + case '1': + page1 = true; + cmdp++; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } + if (errors || !gotdata) return usage_t55xx_write(); if (block > 7) { PrintAndLog("Block number must be between 0 and 7"); - return 1; + return 0; } UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}}; UsbCommand resp; - c.d.asBytes[0] = 0x0; + c.d.asBytes[0] = (page1) ? 0x2 : 0; - PrintAndLog("Writing to block: %d data : 0x%08X", block, data); + PrintAndLog("Writing to page: %d block: %d data : 0x%08X", page1, block, data); //Password mode - if (res == 3) { + if (usepwd) { c.arg[2] = password; - c.d.asBytes[0] = 0x1; + c.d.asBytes[0] |= 0x1; PrintAndLog("pwd : 0x%08X", password); } clearCommandBuffer(); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)"); - return -1; - } return 0; + } + return 1; } int CmdT55xxReadTrace(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - + bool pwdmode = false; + uint32_t password = 0; if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_trace(); if (strlen(Cmd)==0) - AquireData( TRACE_BLOCK ); + if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password ) ) + return 0; - if (!DecodeT55xxBlock()) return 1; + if (!DecodeT55xxBlock()) return 0; - if ( !DemodBufferLen) return 1; + if ( !DemodBufferLen) return 0; RepaintGraphWindow(); uint8_t repeat = 0; if (config.offset > 5) repeat = 32; uint8_t si = config.offset+repeat; - uint32_t bl0 = PackBits(si, 32, DemodBuffer); - uint32_t bl1 = PackBits(si+32, 32, DemodBuffer); + uint32_t bl1 = PackBits(si, 32, DemodBuffer); + uint32_t bl2 = PackBits(si+32, 32, DemodBuffer); uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8; uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8; @@ -780,7 +846,7 @@ int CmdT55xxReadTrace(const char *Cmd) { if ( acl != 0xE0 ) { PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. "); - return 1; + return 0; } PrintAndLog(""); @@ -797,8 +863,8 @@ int CmdT55xxReadTrace(const char *Cmd) { PrintAndLog(" Die Number : %d", dw); PrintAndLog("-------------------------------------------------------------"); PrintAndLog(" Raw Data - Page 1"); - PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) ); - PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) ); + PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) ); + PrintAndLog(" Block 2 : 0x%08X %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) ); PrintAndLog("-------------------------------------------------------------"); /* @@ -827,12 +893,15 @@ int CmdT55xxInfo(const char *Cmd){ Normal mode Extended mode */ + bool pwdmode = false; + uint32_t password = 0; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') return usage_t55xx_info(); if (strlen(Cmd)==0) - AquireData( CONFIGURATION_BLOCK ); + if ( !AquireData( T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password ) ) + return 1; if (!DecodeT55xxBlock()) return 1; @@ -883,55 +952,50 @@ int CmdT55xxInfo(const char *Cmd){ int CmdT55xxDump(const char *Cmd){ - char s[20] = {0x00}; - uint8_t pwd[4] = {0x00}; - char cmdp = param_getchar(Cmd, 0); + uint32_t password = 0; + bool override = false; + char cmdp = param_getchar(Cmd, 0); if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump(); - bool hasPwd = ( strlen(Cmd) > 0); - if ( hasPwd ){ - if (param_gethex(Cmd, 0, pwd, 8)) { - PrintAndLog("password must include 8 HEX symbols"); - return 1; - } + bool usepwd = ( strlen(Cmd) > 0); + if ( usepwd ){ + password = param_get32ex(Cmd, 0, 0, 16); + if (param_getchar(Cmd, 1) =='o' ) + override = true; } - 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]); - } else { - sprintf(s,"%d", i); - } - CmdT55xxReadBlock(s); + PrintAndLog("Reading Page 0:"); + PrintAndLog("blk | hex data | binary"); + for ( uint8_t i = 0; i < 8; ++i){ + T55xxReadBlock(i, 0, usepwd, override, password); } - return 0; + PrintAndLog("Reading Page 1:"); + PrintAndLog("blk | hex data | binary"); + for ( uint8_t i = 0; i < 4; i++){ + T55xxReadBlock(i, 1, usepwd, override, password); + } + return 1; } -int AquireData( uint8_t block ){ - - uint32_t password = 0; - UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, 0, password}}; - - if ( block == CONFIGURATION_BLOCK ) { - c.arg[0] = 0x00 | 0x01; - } - else if (block == TRACE_BLOCK ) { - c.arg[0] = 0x02 | 0x01; - } +int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){ + // arg0 bitmodes: + // bit0 = pwdmode + // bit1 = page to read from + uint8_t arg0 = (page<<1) | pwdmode; + UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}}; clearCommandBuffer(); SendCommand(&c); if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { PrintAndLog("command execution time out"); - return 1; + return 0; } uint8_t got[12000]; GetFromBigBuf(got,sizeof(got),0); WaitForResponse(CMD_ACK,NULL); - setGraphBuf(got, 12000); - return 0; + setGraphBuf(got, sizeof(got)); + return 1; } char * GetBitRateStr(uint32_t id){ @@ -1099,35 +1163,6 @@ void t55x7_create_config_block( int tagtype ){ } -int CmdT55xxWakeUp(const char *Cmd) { - uint32_t password = 0; - uint8_t cmdp = 0; - bool errors = false; - while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch(param_getchar(Cmd, cmdp)) { - case 'h': - case 'H': - return usage_t55xx_wakup(); - case 'p': - case 'P': - password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16); - cmdp+=2; - break; - default: - PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - if (errors) return usage_t55xx_wakup(); - - UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); - PrintAndLog("Wake up command sent. Try read now"); - return 0; -} - /* uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){ @@ -1148,14 +1183,13 @@ static command_t CommandTable[] = {"help", CmdHelp, 1, "This help"}, {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, {"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."}, - {"read", CmdT55xxReadBlock, 0, " [password] -- Read T55xx block data (page 0) [optional password]"}, - {"write", CmdT55xxWriteBlock,0, " [password] -- Write T55xx block data (page 0) [optional password]"}, + {"read", CmdT55xxReadBlock, 0, "b p [password] [o] [1] -- Read T55xx block data (page 0) [optional password]"}, + {"write", CmdT55xxWriteBlock,0, "b d p [password] [1] -- Write T55xx block data (page 0) [optional password]"}, {"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"}, {"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"}, - {"dump", CmdT55xxDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"}, + {"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. [optional password]"}, {"special", special, 0, "Show block changes with 64 different offsets"}, {"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"}, - {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 0fe1b0be..ac188963 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -82,6 +82,6 @@ bool DecodeT55xxBlock(); bool tryDetectModulation(); bool test(uint8_t mode, uint8_t *offset, int *fndBitRate); int special(const char *Cmd); -int AquireData( uint8_t block ); +int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ); #endif diff --git a/client/hid-flasher/usb_cmd.h b/client/hid-flasher/usb_cmd.h index b662b929..739e2447 100644 --- a/client/hid-flasher/usb_cmd.h +++ b/client/hid-flasher/usb_cmd.h @@ -196,6 +196,8 @@ typedef struct{ #define CMD_MIFARE_DESFIRE 0x072e #define CMD_MIFARE_COLLECT_NONCES 0x072f + +#define CMD_HF_SNIFFER 0x0800 #define CMD_UNKNOWN 0xFFFF diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index dd5544cb..5ff64bb5 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -44,7 +44,7 @@ local _commands = { CMD_INDALA_CLONE_TAG_L = 0x0213, CMD_T55XX_READ_BLOCK = 0x0214, CMD_T55XX_WRITE_BLOCK = 0x0215, - CMD_T55XX_READ_TRACE = 0x0216, + --//CMD_T55XX_READ_TRACE = 0x0216, CMD_PCF7931_READ = 0x0217, CMD_PCF7931_WRITE = 0x0223, CMD_EM4X_READ_WORD = 0x0218, @@ -157,7 +157,8 @@ local _commands = { CMD_MIFARE_DES_READER = 0x072c, CMD_MIFARE_DESFIRE_INFO = 0x072d, CMD_MIFARE_DESFIRE = 0x072e, - + CMD_HF_SNIFFER = 0x0800, + CMD_UNKNOWN = 0xFFFF, } diff --git a/client/scripting.c b/client/scripting.c index 63d7f44e..5d9ce55a 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -53,7 +53,7 @@ static int l_SendCommand(lua_State *L){ const char *data = luaL_checklstring(L, 1, &size); if(size != sizeof(UsbCommand)) { - printf("Got data size %d, expected %d" , size, sizeof(UsbCommand)); + printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand)); lua_pushstring(L,"Wrong data size"); return 1; } diff --git a/common/Makefile.common b/common/Makefile.common index 98ff4d0d..72ad0758 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -67,7 +67,8 @@ VPATH = . ../common ../fpga ../zlib INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES) -CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) -Os +#-Wunused -Wsign-compare -Wtype-limits -Wuninitialized -Wno-deprecated -Wstrict-aliasing -Wpointer-arith -Wpointer-arith -Wformat-nonliteral -Winit-self -Wparentheses -Wunreachable-code +CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -Wunused -std=c99 $(APP_CFLAGS) -Os LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc diff --git a/common/lfdemod.c b/common/lfdemod.c index 0f8dd452..9a4051c9 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -282,6 +282,16 @@ int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert) return bestErr; } +uint32_t manchesterEncode2Bytes(uint16_t datain) { + uint32_t output = 0; + uint8_t curBit = 0; + for (uint8_t i=0; i<16; i++) { + curBit = (datain >> (15-i) & 1); + output |= (1<<(((15-i)*2)+curBit)); + } + return output; +} + //by marshmellow //encode binary data into binary manchester int ManchesterEncode(uint8_t *BitStream, size_t size) diff --git a/common/lfdemod.h b/common/lfdemod.h index 3b807b56..75820199 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -30,6 +30,7 @@ int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo); int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow); int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); +uint32_t manchesterEncode2Bytes(uint16_t datain); int ManchesterEncode(uint8_t *BitStream, size_t size); int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert); int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr); diff --git a/common/protocols.c b/common/protocols.c index 0a523da3..ee8abadd 100644 --- a/common/protocols.c +++ b/common/protocols.c @@ -3,13 +3,36 @@ #include #include #include "protocols.h" + +// ATA55xx shared presets & routines +uint32_t GetT55xxClockBit(uint32_t clock) { + switch (clock) { + case 128: + return T55x7_BITRATE_RF_128; + case 100: + return T55x7_BITRATE_RF_100; + case 64: + return T55x7_BITRATE_RF_64; + case 50: + return T55x7_BITRATE_RF_50; + case 40: + return T55x7_BITRATE_RF_40; + case 32: + return T55x7_BITRATE_RF_32; + case 16: + return T55x7_BITRATE_RF_16; + case 8: + return T55x7_BITRATE_RF_8; + default: + return 0; + } +} + #ifndef ON_DEVICE #include "ui.h" #define prnt PrintAndLog -#endif - - +// iclass / picopass chip config structures and shared routines typedef struct { uint8_t app_limit; //[8] uint8_t otp[2]; //[9-10] @@ -31,20 +54,7 @@ typedef struct { }picopass_hdr; - -//#define prnt printf -/*void prnt(char *fmt,...) -{ - va_list argptr; - va_start(argptr, fmt); - vprintf(fmt, argptr); - printf(" "); // cleaning prompt - va_end(argptr); - printf("\n"); -} -*/ -uint8_t isset(uint8_t val, uint8_t mask) -{ +uint8_t isset(uint8_t val, uint8_t mask) { return (val & mask); } @@ -52,8 +62,7 @@ uint8_t notset(uint8_t val, uint8_t mask){ return !(val & mask); } -void fuse_config(const picopass_hdr *hdr) -{ +void fuse_config(const picopass_hdr *hdr) { uint8_t fuses = hdr->conf.fuses; if (isset(fuses,FUSE_FPERS))prnt(" Mode: Personalization [Programmable]"); @@ -104,8 +113,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t * } } -void mem_app_config(const picopass_hdr *hdr) -{ +void mem_app_config(const picopass_hdr *hdr) { uint8_t mem = hdr->conf.mem_config; uint8_t chip = hdr->conf.chip_config; uint8_t applimit = hdr->conf.app_limit; @@ -118,28 +126,25 @@ void mem_app_config(const picopass_hdr *hdr) prnt(" AA1: blocks 06-%02X", applimit); prnt(" AA2: blocks %02X-%02X", applimit+1, max_blk); } -void print_picopass_info(const picopass_hdr *hdr) -{ +void print_picopass_info(const picopass_hdr *hdr) { fuse_config(hdr); mem_app_config(hdr); } -void printIclassDumpInfo(uint8_t* iclass_dump) -{ -// picopass_hdr hdr; -// memcpy(&hdr, iclass_dump, sizeof(picopass_hdr)); +void printIclassDumpInfo(uint8_t* iclass_dump) { print_picopass_info((picopass_hdr *) iclass_dump); } /* -void test() -{ +void test() { picopass_hdr hdr = {0x27,0xaf,0x48,0x01,0xf9,0xff,0x12,0xe0,0x12,0xff,0xff,0xff,0x7f,0x1f,0xff,0x3c}; prnt("Picopass configuration:"); print_picopass_info(&hdr); } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { test(); return 0; } */ + +#endif +//ON_DEVICE diff --git a/common/protocols.h b/common/protocols.h index e676cbfe..d20c95fc 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -267,4 +267,57 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. void printIclassDumpInfo(uint8_t* iclass_dump); void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb); -#endif // PROTOCOLS_H +/* T55x7 configuration register definitions */ +#define T55x7_POR_DELAY 0x00000001 +#define T55x7_ST_TERMINATOR 0x00000008 +#define T55x7_PWD 0x00000010 +#define T55x7_MAXBLOCK_SHIFT 5 +#define T55x7_AOR 0x00000200 +#define T55x7_PSKCF_RF_2 0 +#define T55x7_PSKCF_RF_4 0x00000400 +#define T55x7_PSKCF_RF_8 0x00000800 +#define T55x7_MODULATION_DIRECT 0 +#define T55x7_MODULATION_PSK1 0x00001000 +#define T55x7_MODULATION_PSK2 0x00002000 +#define T55x7_MODULATION_PSK3 0x00003000 +#define T55x7_MODULATION_FSK1 0x00004000 +#define T55x7_MODULATION_FSK2 0x00005000 +#define T55x7_MODULATION_FSK1a 0x00006000 +#define T55x7_MODULATION_FSK2a 0x00007000 +#define T55x7_MODULATION_MANCHESTER 0x00008000 +#define T55x7_MODULATION_BIPHASE 0x00010000 +#define T55x7_MODULATION_DIPHASE 0x00018000 +#define T55x7_BITRATE_RF_8 0 +#define T55x7_BITRATE_RF_16 0x00040000 +#define T55x7_BITRATE_RF_32 0x00080000 +#define T55x7_BITRATE_RF_40 0x000C0000 +#define T55x7_BITRATE_RF_50 0x00100000 +#define T55x7_BITRATE_RF_64 0x00140000 +#define T55x7_BITRATE_RF_100 0x00180000 +#define T55x7_BITRATE_RF_128 0x001C0000 + +/* T5555 (Q5) configuration register definitions */ +#define T5555_ST_TERMINATOR 0x00000001 +#define T5555_MAXBLOCK_SHIFT 0x00000001 +#define T5555_MODULATION_MANCHESTER 0 +#define T5555_MODULATION_PSK1 0x00000010 +#define T5555_MODULATION_PSK2 0x00000020 +#define T5555_MODULATION_PSK3 0x00000030 +#define T5555_MODULATION_FSK1 0x00000040 +#define T5555_MODULATION_FSK2 0x00000050 +#define T5555_MODULATION_BIPHASE 0x00000060 +#define T5555_MODULATION_DIRECT 0x00000070 +#define T5555_INVERT_OUTPUT 0x00000080 +#define T5555_PSK_RF_2 0 +#define T5555_PSK_RF_4 0x00000100 +#define T5555_PSK_RF_8 0x00000200 +#define T5555_USE_PWD 0x00000400 +#define T5555_USE_AOR 0x00000800 +#define T5555_BITRATE_SHIFT 12 +#define T5555_FAST_WRITE 0x00004000 +#define T5555_PAGE_SELECT 0x00008000 + +uint32_t GetT55xxClockBit(uint32_t clock); + +#endif +// PROTOCOLS_H diff --git a/fpga/Makefile b/fpga/Makefile index fad2ff04..e58d6fc4 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -9,7 +9,7 @@ fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_ $(DELETE) $@ $(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr -fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v lp20khz_1MSa_iir_filter.v min_max_tracker.v lf_edge_detect.v +fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v lp20khz_1MSa_iir_filter.v min_max_tracker.v lf_edge_detect.v hi_sniffer.v $(DELETE) $@ $(XILINX_TOOLS_PREFIX)xst -ifn xst_lf.scr diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v index 8a465e75..264e1b0c 100644 --- a/fpga/fpga_hf.v +++ b/fpga/fpga_hf.v @@ -17,6 +17,7 @@ `include "hi_read_rx_xcorr.v" `include "hi_simulate.v" `include "hi_iso14443a.v" +`include "hi_sniffer.v" `include "util.v" module fpga_hf( @@ -122,25 +123,36 @@ hi_iso14443a hisn( hi_simulate_mod_type ); +hi_sniffer he( + pck0, ck_1356meg, ck_1356megb, + he_pwr_lo, he_pwr_hi, he_pwr_oe1, he_pwr_oe2, he_pwr_oe3, he_pwr_oe4, + adc_d, he_adc_clk, + he_ssp_frame, he_ssp_din, ssp_dout, he_ssp_clk, + cross_hi, cross_lo, + he_dbg, + hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter +); + // Major modes: // 000 -- HF reader, transmitting to tag; modulation depth selectable // 001 -- HF reader, receiving from tag, correlating as it goes; frequency selectable // 010 -- HF simulated tag // 011 -- HF ISO14443-A +// 100 -- HF Snoop // 111 -- everything off -mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, 1'b0, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, 1'b0, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, 1'b0, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; diff --git a/fpga/hi_sniffer.v b/fpga/hi_sniffer.v new file mode 100644 index 00000000..f9d8ba93 --- /dev/null +++ b/fpga/hi_sniffer.v @@ -0,0 +1,77 @@ + +module hi_sniffer( + pck0, ck_1356meg, ck_1356megb, + pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, + adc_d, adc_clk, + ssp_frame, ssp_din, ssp_dout, ssp_clk, + cross_hi, cross_lo, + dbg, + xcorr_is_848, snoop, xcorr_quarter_freq // not used. +); + input pck0, ck_1356meg, ck_1356megb; + output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; + input [7:0] adc_d; + output adc_clk; + input ssp_dout; + output ssp_frame, ssp_din, ssp_clk; + input cross_hi, cross_lo; + output dbg; + input xcorr_is_848, snoop, xcorr_quarter_freq; // not used. + +// We are only snooping, all off. +assign pwr_hi = 1'b0;// ck_1356megb & (~snoop); +assign pwr_oe1 = 1'b0; +assign pwr_oe2 = 1'b0; +assign pwr_oe3 = 1'b0; +assign pwr_oe4 = 1'b0; + +reg ssp_clk = 1'b0; +reg ssp_frame; +reg adc_clk; +reg [7:0] adc_d_out = 8'd0; +reg [7:0] ssp_cnt = 8'd0; +reg [7:0] pck_divider = 8'd0; +reg ant_lo = 1'b0; +reg bit_to_send = 1'b0; + +always @(ck_1356meg, pck0) // should synthetisize to a mux.. + begin + adc_clk = ck_1356meg; + ssp_clk = ~ck_1356meg; + end + +reg [7:0] cnt_test = 8'd0; // test + +always @(posedge pck0) +begin + ant_lo <= 1'b0; +end + +always @(posedge ssp_clk) // ~1356 (hf) +begin + if(ssp_cnt[7:0] == 8'd255) // SSP counter for divides. + ssp_cnt[7:0] <= 8'd0; + else + ssp_cnt <= ssp_cnt + 1; + + if((ssp_cnt[2:0] == 3'b000) && !ant_lo) // To set frame length + begin + adc_d_out[7:0] = adc_d; // disable for test + bit_to_send = adc_d_out[0]; + ssp_frame <= 1'b1; + end + else + begin + adc_d_out[6:0] = adc_d_out[7:1]; + adc_d_out[7] = 1'b0; // according to old lf_read.v comment prevents gliches if not set. + bit_to_send = adc_d_out[0]; + ssp_frame <= 1'b0; + end +end + +assign ssp_din = bit_to_send && !ant_lo;//bit_to_send && !ant_lo; // && .. not needed i guess? + +assign pwr_lo = ant_lo; + + +endmodule diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 114e6d08..547043a2 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -200,6 +200,8 @@ typedef struct{ #define CMD_MIFARE_COLLECT_NONCES 0x072f +#define CMD_HF_SNIFFER 0x0800 + #define CMD_UNKNOWN 0xFFFF -- 2.39.5 From f218d50efb324da7f268d9b657a5be93d702c4f8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Oct 2015 09:05:22 +0100 Subject: [PATCH 14/16] ADD: @gm4tr1x found some new known mifare keys. --- client/default_keys.dic | 8 +++++++- client/lualibs/mf_default_keys.lua | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/client/default_keys.dic b/client/default_keys.dic index 8053f42d..9bd6b02c 100644 --- a/client/default_keys.dic +++ b/client/default_keys.dic @@ -127,4 +127,10 @@ C4652C54261C, D49E2826664F, 51284C3686A6, 3DF14C8000A1, -6A470D54127C, \ No newline at end of file +6A470D54127C, +# Data from: http://pastebin.com/AK9Bftpw +# +48ffe71294a0, -- Länstrafiken i Västerbotten +e3429281efc1, -- Länstrafiken i Västerbotten +16f21a82ec84, -- Länstrafiken i Västerbotten +460722122510, -- Länstrafiken i Västerbotten \ No newline at end of file diff --git a/client/lualibs/mf_default_keys.lua b/client/lualibs/mf_default_keys.lua index a7aac022..8473e657 100644 --- a/client/lualibs/mf_default_keys.lua +++ b/client/lualibs/mf_default_keys.lua @@ -64,6 +64,11 @@ local _keys = { '776974687573', -- Transport Key B '4AF9D7ADEBE4', -- Directory and event log Key A '2BA9621E0A36', -- Directory and event log Key B + -- Data from: http://pastebin.com/AK9Bftpw + '48ffe71294a0', -- Länstrafiken i Västerbotten + 'e3429281efc1', -- Länstrafiken i Västerbotten + '16f21a82ec84', -- Länstrafiken i Västerbotten + '460722122510', -- Länstrafiken i Västerbotten -- Data from: http://pastebin.com/Dnnc5dFC -- New cards are not encrypted (MF Ultralight) 'fc00018778f7', -- Västtrafiken Key A @@ -141,7 +146,7 @@ local _keys = { 'b00000000000', --[[ - Should be for Mifare TNP3xxx tags A KEY. + Should be for Mifare TNP3xxx tags key A --]] '4b0b20107ccb', -- 2.39.5 From 84f9cf06261d20d81fd4c0f2aa7d4d384df751b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Oct 2015 09:07:04 +0100 Subject: [PATCH 15/16] ADD: a minor xor script --- client/scripts/calc_ev1_it.lua | 147 +++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 client/scripts/calc_ev1_it.lua diff --git a/client/scripts/calc_ev1_it.lua b/client/scripts/calc_ev1_it.lua new file mode 100644 index 00000000..0471da70 --- /dev/null +++ b/client/scripts/calc_ev1_it.lua @@ -0,0 +1,147 @@ +local bin = require('bin') +local getopt = require('getopt') +local utils = require('utils') + +local bxor=bit32.bxor + +example =[[ + script run calc_ev1_it + script run calc_ev1_it -u 11223344556677 +]] +author = "Iceman" +usage = "script run calc_ev1_it -u " +desc =[[ +Arguments: + -h : this help + -u : UID +]] +--- +-- A debug printout-function +function dbg(args) + if type(args) == "table" then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) + return nil,err +end +--- +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end +-- +-- Exit message +function exitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end + +local _xortable = { + --[[ position, 4byte xor + --]] + {"00","4f2711c1"}, + {"01","07D7BB83"}, + {"02","9636EF07"}, + {"03","B5F4460E"}, + {"04","F271141C"}, + {"05","7D7BB038"}, + {"06","636EF871"}, + {"07","5F4468E3"}, + {"08","271149C7"}, + {"09","D7BB0B8F"}, + {"0A","36EF8F1E"}, + {"0B","F446863D"}, + {"0C","7114947A"}, + {"0D","7BB0B0F5"}, + {"0E","6EF8F9EB"}, + {"0F","44686BD7"}, + {"10","11494fAF"}, + {"11","BB0B075F"}, + {"12","EF8F96BE"}, + {"13","4686B57C"}, + {"14","1494F2F9"}, + {"15","B0B07DF3"}, + {"16","F8F963E6"}, + {"17","686B5FCC"}, + {"18","494F2799"}, + {"19","0B07D733"}, + {"1A","8F963667"}, + {"1B","86B5F4CE"}, + {"1C","94F2719C"}, + {"1D","B07D7B38"}, + {"1E","F9636E70"}, + {"1F","6B5F44E0"}, +} + +local function findEntryByUid( uid ) + + -- xor UID4,UID5,UID6,UID7 + -- mod 0x20 (dec 32) + local pos = (bxor(bxor(bxor(uid[4],uid[5]), uid[6]),uid[7])) % 32 + + -- convert to hexstring + pos = string.format('%02X', pos) + + for k, v in pairs(_xortable) do + if ( v[1] == pos ) then + return utils.ConvertHexToBytes(v[2]) + end + end + return nil +end + +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print() + + local i,j, pwd + local uid = '04111211121110' + + -- Arguments for the script + for o, a in getopt.getopt(args, 'hu:') do + if o == "h" then return help() end + if o == "u" then uid = a end + end + + -- uid string checks + if uid == nil then return oops('empty uid string') end + if #uid == 0 then return oops('empty uid string') end + if #uid ~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end + + local uidbytes = utils.ConvertHexToBytes(uid) + + local entry = findEntryByUid(uidbytes) + if entry == nil then return oops("Can't find a xor entry") end + + -- PWD CALC + -- PWD0 = T0 xor B xor C xor D + -- PWD1 = T1 xor A xor C xor E + -- PWD2 = T2 xor A xor B xor F + -- PWD3 = T3 xor G + + local pwd0 = bxor( bxor( bxor( entry[1], uidbytes[2]), uidbytes[3]), uidbytes[4]) + local pwd1 = bxor( bxor( bxor( entry[2], uidbytes[1]), uidbytes[3]), uidbytes[5]) + local pwd2 = bxor( bxor( bxor( entry[3], uidbytes[1]), uidbytes[2]), uidbytes[6]) + local pwd3 = bxor( entry[4], uidbytes[7]) + + print('UID | '..uid) + print(string.format('PWD | %02X%02X%02X%02X', pwd0, pwd1, pwd2, pwd3)) +end + +main(args) \ No newline at end of file -- 2.39.5 From 857bc2ff6a4b7112b61def90b4716dcdf2c448af Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 30 Oct 2015 09:09:35 +0100 Subject: [PATCH 16/16] CHG: some desfire changes from @bforbort fork. *untested* --- armsrc/desfire_key.c | 1 + armsrc/mifaredesfire.c | 93 ++++++++++++++++++++++++++++++++++++++---- armsrc/mifaredesfire.h | 1 + common/protocols.h | 46 ++++++++++----------- 4 files changed, 110 insertions(+), 31 deletions(-) diff --git a/armsrc/desfire_key.c b/armsrc/desfire_key.c index b3aa14e9..9ae2c3f0 100644 --- a/armsrc/desfire_key.c +++ b/armsrc/desfire_key.c @@ -60,6 +60,7 @@ void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t ke if ( key != NULL ){ key->type = T_3DES; memcpy (key->data, value, 16); + memcpy (key->data + 16, value, 8); update_key_schedules (key); } } diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index b1e035f9..57681d71 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -1,5 +1,4 @@ #include "mifaredesfire.h" -#include "des.h" #include "BigBuf.h" #define MAX_APPLICATION_COUNT 28 @@ -198,6 +197,10 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain InitDesfireCard(); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); + // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) // 4 olika crypto algo DES, 3DES, 3K3DES, AES // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO @@ -205,20 +208,32 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain // des, nyckel 0, switch (mode){ case 1:{ - if (algo == 1) { - - uint8_t keybytes[8] = {0x00}; + uint8_t keybytes[16]; uint8_t RndA[8] = {0x00}; uint8_t RndB[8] = {0x00}; + if (algo == 2) { if (datain[1] == 0xff){ + memcpy(keybytes,PICC_MASTER_KEY16,16); + } else { + memcpy(keybytes, datain+1, datalen); + } + } else { + if (algo == 1) { + if (datain[1] == 0xff){ memcpy(keybytes,null_key_data8,8); } else{ memcpy(keybytes, datain+1, datalen); } + } + } struct desfire_key defaultkey = {0}; desfirekey_t key = &defaultkey; + + if (algo == 2) + Desfire_3des_key_new_with_version(keybytes, key); + else if (algo ==1) Desfire_des_key_new(keybytes, key); cmd[0] = AUTHENTICATE; @@ -240,8 +255,11 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain } memcpy( encRndB, resp+3, 8); - + if (algo == 2) + tdes_dec(&decRndB, &encRndB, key->data); + else if (algo == 1) des_dec(&decRndB, &encRndB, key->data); + memcpy(RndB, decRndB, 8); rol(decRndB,8); @@ -250,14 +268,21 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain memcpy(RndA, decRndA, 8); uint8_t encRndA[8] = {0x00}; + if (algo == 2) + tdes_dec(&encRndA, &decRndA, key->data); + else if (algo == 1) des_dec(&encRndA, &decRndA, key->data); memcpy(both, encRndA, 8); for (int x = 0; x < 8; x++) { decRndB[x] = decRndB[x] ^ encRndA[x]; + } + if (algo == 2) + tdes_dec(&encRndB, &decRndB, key->data); + else if (algo == 1) des_dec(&encRndB, &decRndB, key->data); memcpy(both + 8, encRndB, 8); @@ -282,7 +307,12 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain //print_result("SESSION : ", skey->data, 8); memcpy(encRndA, resp+3, 8); + + if (algo == 2) + tdes_dec(&encRndA, &encRndA, key->data); + else if (algo == 1) des_dec(&encRndA, &encRndA, key->data); + rol(decRndA,8); for (int x = 0; x < 8; x++) { if (decRndA[x] != encRndA[x]) { @@ -295,6 +325,8 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain //Change the selected key to a new value. /* + // Current key is a 3DES key, change it to a DES key + if (algo == 2) { cmd[0] = CHANGE_KEY; cmd[1] = keyno; @@ -312,6 +344,48 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain memcpy(buff3, &first, 1); memcpy(buff3 + 1, &second, 1); + tdes_dec(&buff1, &buff1, skey->data); + memcpy(cmd+2,buff1,8); + + for (int x = 0; x < 8; x++) { + buff2[x] = buff2[x] ^ buff1[x]; + } + tdes_dec(&buff2, &buff2, skey->data); + memcpy(cmd+10,buff2,8); + + for (int x = 0; x < 8; x++) { + buff3[x] = buff3[x] ^ buff2[x]; + } + tdes_dec(&buff3, &buff3, skey->data); + memcpy(cmd+18,buff3,8); + + // The command always times out on the first attempt, this will retry until a response + // is recieved. + len = 0; + while(!len) { + len = DesfireAPDU(cmd,26,resp); + } + + } else { + // Current key is a DES key, change it to a 3DES key + if (algo == 1) { + cmd[0] = CHANGE_KEY; + cmd[1] = keyno; + + uint8_t newKey[16] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; + + uint8_t first, second; + uint8_t buff1[8] = {0x00}; + uint8_t buff2[8] = {0x00}; + uint8_t buff3[8] = {0x00}; + + memcpy(buff1,newKey, 8); + memcpy(buff2,newKey + 8, 8); + + ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second); + memcpy(buff3, &first, 1); + memcpy(buff3 + 1, &second, 1); + des_dec(&buff1, &buff1, skey->data); memcpy(cmd+2,buff1,8); @@ -333,18 +407,20 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain while(!len) { len = DesfireAPDU(cmd,26,resp); } + } + } */ OnSuccess(); + if (algo == 2) + cmd_send(CMD_ACK,1,0,0,skey->data,16); + else if (algo == 1) cmd_send(CMD_ACK,1,0,0,skey->data,8); - } else { DbpString("Authetication failed."); OnError(6); return; } - - } } break; case 2: @@ -416,6 +492,7 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain OnError(7); return; } + break; } } diff --git a/armsrc/mifaredesfire.h b/armsrc/mifaredesfire.h index 7cd81c7e..3d59f950 100644 --- a/armsrc/mifaredesfire.h +++ b/armsrc/mifaredesfire.h @@ -11,5 +11,6 @@ #include "desfire_key.h" #include "mifareutil.h" #include "common.h" +#include "des.h" #endif diff --git a/common/protocols.h b/common/protocols.h index d20c95fc..152039b9 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -268,14 +268,14 @@ void printIclassDumpInfo(uint8_t* iclass_dump); void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb); /* T55x7 configuration register definitions */ -#define T55x7_POR_DELAY 0x00000001 -#define T55x7_ST_TERMINATOR 0x00000008 -#define T55x7_PWD 0x00000010 +#define T55x7_POR_DELAY 0x00000001 +#define T55x7_ST_TERMINATOR 0x00000008 +#define T55x7_PWD 0x00000010 #define T55x7_MAXBLOCK_SHIFT 5 -#define T55x7_AOR 0x00000200 -#define T55x7_PSKCF_RF_2 0 -#define T55x7_PSKCF_RF_4 0x00000400 -#define T55x7_PSKCF_RF_8 0x00000800 +#define T55x7_AOR 0x00000200 +#define T55x7_PSKCF_RF_2 0 +#define T55x7_PSKCF_RF_4 0x00000400 +#define T55x7_PSKCF_RF_8 0x00000800 #define T55x7_MODULATION_DIRECT 0 #define T55x7_MODULATION_PSK1 0x00001000 #define T55x7_MODULATION_PSK2 0x00002000 @@ -287,17 +287,17 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t * #define T55x7_MODULATION_MANCHESTER 0x00008000 #define T55x7_MODULATION_BIPHASE 0x00010000 #define T55x7_MODULATION_DIPHASE 0x00018000 -#define T55x7_BITRATE_RF_8 0 -#define T55x7_BITRATE_RF_16 0x00040000 -#define T55x7_BITRATE_RF_32 0x00080000 -#define T55x7_BITRATE_RF_40 0x000C0000 -#define T55x7_BITRATE_RF_50 0x00100000 -#define T55x7_BITRATE_RF_64 0x00140000 +#define T55x7_BITRATE_RF_8 0 +#define T55x7_BITRATE_RF_16 0x00040000 +#define T55x7_BITRATE_RF_32 0x00080000 +#define T55x7_BITRATE_RF_40 0x000C0000 +#define T55x7_BITRATE_RF_50 0x00100000 +#define T55x7_BITRATE_RF_64 0x00140000 #define T55x7_BITRATE_RF_100 0x00180000 #define T55x7_BITRATE_RF_128 0x001C0000 /* T5555 (Q5) configuration register definitions */ -#define T5555_ST_TERMINATOR 0x00000001 +#define T5555_ST_TERMINATOR 0x00000001 #define T5555_MAXBLOCK_SHIFT 0x00000001 #define T5555_MODULATION_MANCHESTER 0 #define T5555_MODULATION_PSK1 0x00000010 @@ -307,15 +307,15 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t * #define T5555_MODULATION_FSK2 0x00000050 #define T5555_MODULATION_BIPHASE 0x00000060 #define T5555_MODULATION_DIRECT 0x00000070 -#define T5555_INVERT_OUTPUT 0x00000080 -#define T5555_PSK_RF_2 0 -#define T5555_PSK_RF_4 0x00000100 -#define T5555_PSK_RF_8 0x00000200 -#define T5555_USE_PWD 0x00000400 -#define T5555_USE_AOR 0x00000800 -#define T5555_BITRATE_SHIFT 12 -#define T5555_FAST_WRITE 0x00004000 -#define T5555_PAGE_SELECT 0x00008000 +#define T5555_INVERT_OUTPUT 0x00000080 +#define T5555_PSK_RF_2 0 +#define T5555_PSK_RF_4 0x00000100 +#define T5555_PSK_RF_8 0x00000200 +#define T5555_USE_PWD 0x00000400 +#define T5555_USE_AOR 0x00000800 +#define T5555_BITRATE_SHIFT 12 +#define T5555_FAST_WRITE 0x00004000 +#define T5555_PAGE_SELECT 0x00008000 uint32_t GetT55xxClockBit(uint32_t clock); -- 2.39.5